[5269] | 1 | /* $Id: IRTMidi.cpp,v 1.7 2001-02-26 20:14:38 sandervl Exp $ */
|
---|
[95] | 2 |
|
---|
[4] | 3 | /*******************************************************************************
|
---|
| 4 | * FILE NAME: IRTMidi.cpp *
|
---|
| 5 | * *
|
---|
| 6 | * DESCRIPTION: *
|
---|
| 7 | * Class implementation of the class: *
|
---|
| 8 | * IRTMidi- Real Time Midi Base Class *
|
---|
| 9 | * *
|
---|
| 10 | * Copyright Joel Troster *
|
---|
| 11 | *
|
---|
| 12 | * Project Odin Software License can be found in LICENSE.TXT
|
---|
| 13 | *
|
---|
| 14 | *******************************************************************************/
|
---|
[588] | 15 |
|
---|
| 16 |
|
---|
| 17 | /****************************************************************************
|
---|
| 18 | * Includes *
|
---|
| 19 | ****************************************************************************/
|
---|
| 20 |
|
---|
[4] | 21 | #define INCL_DOS
|
---|
[588] | 22 | #include <os2wrap.h> //Odin32 OS/2 api wrappers
|
---|
[4] | 23 | #include <win32type.h>
|
---|
| 24 | #include "IRTMidi.hpp"
|
---|
| 25 | #include <meerror.h>
|
---|
| 26 | #include <string.h>
|
---|
| 27 | #include <stdio.h>
|
---|
| 28 | #include <malloc.h>
|
---|
| 29 |
|
---|
[2812] | 30 | #define DBG_LOCALLOG DBG_irtmidi
|
---|
| 31 | #include "dbglocal.h"
|
---|
| 32 |
|
---|
[4] | 33 | IRTMidi * IRTMidi::iTheIRTMidiSingleton = NULL;
|
---|
| 34 |
|
---|
| 35 | //------------------------------------------------------------------------------
|
---|
| 36 | // IRTMidi::IRTMidi
|
---|
| 37 | //------------------------------------------------------------------------------
|
---|
| 38 | IRTMidi::IRTMidi()
|
---|
| 39 | : iHardwareClass( 0 )
|
---|
| 40 | , iApplicationClass( 1 )
|
---|
| 41 | , iRTMidiModule( NULL )
|
---|
| 42 | , iNumInInstances( 0 )
|
---|
| 43 | , iNumOutInstances( 0 )
|
---|
| 44 | {
|
---|
| 45 | unsigned long rc = 0;
|
---|
| 46 |
|
---|
| 47 | // Remember my address
|
---|
| 48 | iTheIRTMidiSingleton = this;
|
---|
| 49 |
|
---|
| 50 | // Get RTMIDI.DLL Module Handle procedures
|
---|
| 51 | rc = getRTMidiProcs();
|
---|
| 52 | //fprintf( stderr, "Get Procs rc=%d\n", rc );
|
---|
| 53 |
|
---|
| 54 | // Initialize MIDI Setup structure and call MIDISetup
|
---|
| 55 | iSetup.ulStructLength = sizeof( MIDISETUP );
|
---|
| 56 | iSetup.pulMaxRTSysexLength = &maxRTSysexLen;
|
---|
| 57 | iSetup.ppulMIDICurrentTime = &iCurrentTime;
|
---|
| 58 | iSetup.ulFlags = 0;
|
---|
| 59 | iSetup.pfnMIDI_NotifyCallback = NULL;
|
---|
| 60 | iSetup.hwndCallback = 0;
|
---|
| 61 | iSetup.hqueueCallback = 0;
|
---|
| 62 | if ( rc == 0 )
|
---|
[5269] | 63 | rc = MidiSetup( &iSetup, 0 );
|
---|
[4] | 64 | //fprintf( stderr, "MidiSetup rc=%d\n", rc );
|
---|
| 65 |
|
---|
| 66 | // Clear all Instance slots
|
---|
| 67 | unsigned int i;
|
---|
| 68 | for ( i = 0; i < MAX_INSTANCES; i++ )
|
---|
| 69 | {
|
---|
| 70 | iInstances[ i ] = NULL;
|
---|
| 71 | iInInstances[ i ] = NULL;
|
---|
| 72 | iOutInstances[ i ] = NULL;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | // Query Classes & Instances, filling in the slots
|
---|
| 76 | if ( rc == 0 ) rc = getClasses();
|
---|
| 77 | if ( rc == 0 ) rc = getInstances();
|
---|
| 78 | setLastRC( rc );
|
---|
| 79 |
|
---|
| 80 | // Start up the MIDI timer
|
---|
| 81 | if ( rc == 0 )
|
---|
| 82 | startTimer();
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | unsigned long IRTMidi::getRTMidiProcs()
|
---|
| 86 | {
|
---|
| 87 | char loadError[256] = "";
|
---|
| 88 | unsigned long rc;
|
---|
| 89 | PFN modAddr;
|
---|
| 90 | rc = DosLoadModule( loadError, sizeof(loadError), "RTMIDI", &iRTMidiModule );
|
---|
| 91 | if ( rc ) return rc;
|
---|
| 92 |
|
---|
| 93 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDICreateInstance", &modAddr );
|
---|
| 94 | if ( rc ) return rc;
|
---|
[21916] | 95 | pfnMidiCreateInstance = (ULONG(APIENTRY *)( ULONG, MINSTANCE*, PCSZ, ULONG)) modAddr;
|
---|
[4] | 96 |
|
---|
| 97 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIDeleteInstance", &modAddr );
|
---|
| 98 | if ( rc ) return rc;
|
---|
[21916] | 99 | pfnMidiDeleteInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
|
---|
[4] | 100 |
|
---|
| 101 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIEnableInstance", &modAddr );
|
---|
| 102 | if ( rc ) return rc;
|
---|
[21916] | 103 | pfnMidiEnableInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
|
---|
[4] | 104 |
|
---|
| 105 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIDisableInstance", &modAddr );
|
---|
| 106 | if ( rc ) return rc;
|
---|
[21916] | 107 | pfnMidiDisableInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
|
---|
[4] | 108 |
|
---|
| 109 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIAddLink", &modAddr );
|
---|
| 110 | if ( rc ) return rc;
|
---|
[21916] | 111 | pfnMidiAddLink = (ULONG(APIENTRY *)(MINSTANCE, MINSTANCE, ULONG, ULONG)) modAddr;
|
---|
[4] | 112 |
|
---|
| 113 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIRemoveLink", &modAddr );
|
---|
| 114 | if ( rc ) return rc;
|
---|
[21916] | 115 | pfnMidiRemoveLink = (ULONG(APIENTRY *)(MINSTANCE, MINSTANCE, ULONG, ULONG)) modAddr;
|
---|
[4] | 116 |
|
---|
| 117 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryClassList", &modAddr );
|
---|
| 118 | if ( rc ) return rc;
|
---|
[21916] | 119 | pfnMidiQueryClassList = (ULONG(APIENTRY *)(ULONG, PMIDICLASSINFO, ULONG)) modAddr;
|
---|
[4] | 120 |
|
---|
| 121 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryInstanceList", &modAddr );
|
---|
| 122 | if ( rc ) return rc;
|
---|
[21916] | 123 | pfnMidiQueryInstanceList = (ULONG(APIENTRY *)(ULONG, PMIDIINSTANCEINFO, ULONG)) modAddr;
|
---|
[4] | 124 |
|
---|
| 125 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryNumClasses", &modAddr );
|
---|
| 126 | if ( rc ) return rc;
|
---|
[21916] | 127 | pfnMidiQueryNumClasses = (ULONG(APIENTRY *)(PULONG, ULONG)) modAddr;
|
---|
[4] | 128 |
|
---|
| 129 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryNumInstances", &modAddr );
|
---|
| 130 | if ( rc ) return rc;
|
---|
[21916] | 131 | pfnMidiQueryNumInstances = (ULONG(APIENTRY *)(PULONG, ULONG)) modAddr;
|
---|
[4] | 132 |
|
---|
| 133 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISendMessages", &modAddr );
|
---|
| 134 | if ( rc ) return rc;
|
---|
[21916] | 135 | pfnMidiSendMessages = (ULONG(APIENTRY *)(PMESSAGE, ULONG, ULONG)) modAddr;
|
---|
[4] | 136 |
|
---|
| 137 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISendSysexMessage", &modAddr );
|
---|
| 138 | if ( rc ) return rc;
|
---|
[21916] | 139 | pfnMidiSendSysexMessage = (ULONG(APIENTRY *)(PMESSAGE, ULONG, ULONG)) modAddr;
|
---|
[4] | 140 |
|
---|
| 141 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIRetrieveMessages", &modAddr );
|
---|
| 142 | if ( rc ) return rc;
|
---|
[21916] | 143 | pfnMidiRetrieveMessages = (ULONG(APIENTRY *)(MINSTANCE, PVOID, PULONG, ULONG)) modAddr;
|
---|
[4] | 144 |
|
---|
| 145 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISetup", &modAddr );
|
---|
| 146 | if ( rc ) return rc;
|
---|
[21916] | 147 | pfnMidiSetup = (ULONG(APIENTRY *)(PMIDISETUP, ULONG)) modAddr;
|
---|
[4] | 148 |
|
---|
| 149 | rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDITimer", &modAddr );
|
---|
| 150 | if ( rc ) return rc;
|
---|
[21916] | 151 | pfnMidiTimer = (ULONG(APIENTRY *)(ULONG, ULONG)) modAddr;
|
---|
[4] | 152 |
|
---|
| 153 | return 0;
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | //------------------------------------------------------------------------------
|
---|
| 157 | // IRTMidi::~IRTMidi
|
---|
| 158 | //------------------------------------------------------------------------------
|
---|
| 159 | IRTMidi::~IRTMidi()
|
---|
| 160 | {
|
---|
| 161 | stopTimer();
|
---|
| 162 | delInstances();
|
---|
| 163 | iTheIRTMidiSingleton = NULL;
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | void IRTMidi::setLastRC(unsigned long theRC)
|
---|
| 167 | {
|
---|
| 168 | iLastRC = theRC;
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | void IRTMidi::resetLastRC()
|
---|
| 172 | {
|
---|
| 173 | setLastRC( 0 );
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | //------------------------------------------------------------------------------
|
---|
| 177 | // IRTMidi :: RCExplanation
|
---|
| 178 | //------------------------------------------------------------------------------
|
---|
[21916] | 179 | const char * IRTMidi::RCExplanation() const
|
---|
[4] | 180 | {
|
---|
[21916] | 181 | const char * DebugString;
|
---|
[4] | 182 | switch( iLastRC )
|
---|
| 183 | {
|
---|
| 184 | case 0:
|
---|
| 185 | DebugString = "OK";
|
---|
| 186 | break;
|
---|
| 187 |
|
---|
| 188 | // Timer error messages
|
---|
| 189 | case TIMERERR_INVALID_PARAMETER:
|
---|
| 190 | DebugString = "MIDI Timer: Invalid Parameter";
|
---|
| 191 | break;
|
---|
| 192 | case TIMERERR_INTERNAL_SYSTEM:
|
---|
| 193 | DebugString = "MIDI Timer: Internal System Error";
|
---|
| 194 | break;
|
---|
| 195 |
|
---|
| 196 | // RTMIDI messages
|
---|
| 197 | case MIDIERR_DUPLICATE_INSTANCE_NAME:
|
---|
| 198 | DebugString = "MIDIERR_DUPLICATE_INSTANCE_NAME";
|
---|
| 199 | break;
|
---|
| 200 | case MIDIERR_HARDWARE_FAILED:
|
---|
| 201 | DebugString = "MIDIERR_HARDWARE_FAILED";
|
---|
| 202 | break;
|
---|
| 203 | case MIDIERR_INTERNAL_SYSTEM:
|
---|
| 204 | DebugString = "MIDIERR_INTERNAL_SYSTEM";
|
---|
| 205 | break;
|
---|
| 206 | case MIDIERR_INVALID_BUFFER_LENGTH:
|
---|
| 207 | DebugString = "MIDIERR_INVALID_BUFFER_LENGTH";
|
---|
| 208 | break;
|
---|
| 209 | case MIDIERR_INVALID_CLASS_NUMBER:
|
---|
| 210 | DebugString = "MIDIERR_INVALID_CLASS_NUMBER";
|
---|
| 211 | break;
|
---|
| 212 | case MIDIERR_INVALID_CONFIG_DATA:
|
---|
| 213 | DebugString = "MIDIERR_INVALID_CONFIG_DATA";
|
---|
| 214 | break;
|
---|
| 215 | case MIDIERR_INVALID_FLAG:
|
---|
| 216 | DebugString = "MIDIERR_INVALID_FLAG";
|
---|
| 217 | break;
|
---|
| 218 | case MIDIERR_INVALID_INSTANCE_NAME:
|
---|
| 219 | DebugString = "MIDIERR_INVALID_INSTANCE_NAME";
|
---|
| 220 | break;
|
---|
| 221 | case MIDIERR_INVALID_INSTANCE_NUMBER:
|
---|
| 222 | DebugString = "MIDIERR_INVALID_INSTANCE_NUMBER";
|
---|
| 223 | break;
|
---|
| 224 | case MIDIERR_INVALID_PARAMETER:
|
---|
| 225 | DebugString = "MIDIERR_INVALID_PARAMETER";
|
---|
| 226 | break;
|
---|
| 227 | case MIDIERR_INVALID_SETUP:
|
---|
| 228 | DebugString = "MIDIERR_INVALID_SETUP";
|
---|
| 229 | break;
|
---|
| 230 | case MIDIERR_NO_DRIVER:
|
---|
| 231 | DebugString = "MIDIERR_NO_DRIVER";
|
---|
| 232 | break;
|
---|
| 233 | case MIDIERR_NO_DEFAULT_HW_NODE:
|
---|
| 234 | DebugString = "MIDIERR_NO_DEFAULT_HW_NODE";
|
---|
| 235 | break;
|
---|
| 236 | case MIDIERR_NOT_ALLOWED:
|
---|
| 237 | DebugString = "MIDIERR_NOT_ALLOWED";
|
---|
| 238 | break;
|
---|
| 239 | case MIDIERR_NOTIFY_MISSED:
|
---|
| 240 | DebugString = "MIDIERR_NOTIFY_MISSED";
|
---|
| 241 | break;
|
---|
| 242 | case MIDIERR_RESOURCE_NOT_AVAILABLE:
|
---|
| 243 | DebugString = "MIDIERR_RESOURCE_NOT_AVAILABLE";
|
---|
| 244 | break;
|
---|
| 245 | case MIDIERR_SENDONLY:
|
---|
| 246 | DebugString = "MIDIERR_SENDONLY";
|
---|
| 247 | break;
|
---|
| 248 | case MIDIERR_RECEIVEONLY:
|
---|
| 249 | DebugString = "MIDIERR_RECEIVEONLY";
|
---|
| 250 | break;
|
---|
| 251 |
|
---|
| 252 | default:
|
---|
| 253 | DebugString = "Beats Me!";
|
---|
| 254 | break;
|
---|
| 255 | }
|
---|
| 256 | return DebugString;
|
---|
| 257 | }
|
---|
| 258 |
|
---|
| 259 | //------------------------------------------------------------------------------
|
---|
| 260 | // IRTMidi :: getClasses (private)
|
---|
| 261 | //------------------------------------------------------------------------------
|
---|
| 262 | unsigned long IRTMidi::getClasses()
|
---|
| 263 | {
|
---|
| 264 | unsigned long rc;
|
---|
| 265 | unsigned long nc = 0;
|
---|
| 266 | PMIDICLASSINFO ci = NULL;
|
---|
| 267 |
|
---|
| 268 | // Query classes and get the Hardware & Application class numbers
|
---|
[5269] | 269 | rc = MidiQueryNumClasses( &nc, 0 );
|
---|
[4] | 270 | if ( rc == 0 && nc > 0 )
|
---|
| 271 | {
|
---|
| 272 | ci = new MIDICLASSINFO[ nc ];
|
---|
[5269] | 273 | rc = MidiQueryClassList( nc, ci, 0 );
|
---|
[4] | 274 | }
|
---|
| 275 | if ( rc == 0 && ci )
|
---|
| 276 | {
|
---|
| 277 | for ( int i = 0; i < nc; i++ )
|
---|
| 278 | {
|
---|
| 279 | if ( strcmp( ci[i].szmClassName, "Application" ) == 0 )
|
---|
| 280 | iApplicationClass = ci[i].ulClassNumber;
|
---|
| 281 | if ( strcmp( ci[i].szmClassName, "Hardware" ) == 0 )
|
---|
| 282 | iHardwareClass = ci[i].ulClassNumber;
|
---|
| 283 | }
|
---|
| 284 | }
|
---|
| 285 | if ( ci )
|
---|
| 286 | {
|
---|
| 287 | delete[] ci;
|
---|
| 288 | }
|
---|
| 289 | return rc;
|
---|
| 290 | }
|
---|
| 291 |
|
---|
| 292 | unsigned long IRTMidi::findFreeInstance() const
|
---|
| 293 | {
|
---|
| 294 | unsigned long i;
|
---|
| 295 | for ( i = 0; i < MAX_INSTANCES; i++ )
|
---|
| 296 | {
|
---|
| 297 | if ( iInstances[ i ] == NULL )
|
---|
| 298 | return i;
|
---|
| 299 | }
|
---|
| 300 | return MAX_INSTANCES; // should not happen to a dog
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | //------------------------------------------------------------------------------
|
---|
| 304 | // IRTMidi :: addInstance
|
---|
| 305 | //------------------------------------------------------------------------------
|
---|
| 306 | MINSTANCE IRTMidi::addInstance( IMidiInstance * theInstance,
|
---|
| 307 | ULONG classNum, char * instanceName )
|
---|
| 308 | {
|
---|
| 309 | unsigned long rc;
|
---|
| 310 | MINSTANCE newInstance;
|
---|
| 311 | unsigned long ni = 0;
|
---|
| 312 | PMIDIINSTANCEINFO ci = NULL;
|
---|
| 313 |
|
---|
| 314 | // Add new instance
|
---|
[5269] | 315 | rc = MidiCreateInstance( classNum,
|
---|
[4] | 316 | &newInstance,
|
---|
| 317 | instanceName,
|
---|
| 318 | 0 );
|
---|
| 319 | // Now find it to initialize the Instance Object
|
---|
| 320 | if ( rc == 0 )
|
---|
| 321 | {
|
---|
[5269] | 322 | rc = MidiQueryNumInstances( &ni, 0 );
|
---|
[4] | 323 | if ( rc == 0 && ni > 0 )
|
---|
| 324 | {
|
---|
| 325 | ci = new MIDIINSTANCEINFO[ ni ];
|
---|
[5269] | 326 | rc = MidiQueryInstanceList( ni, ci, 0 );
|
---|
[4] | 327 | }
|
---|
| 328 | }
|
---|
| 329 | if ( rc == 0 && ci )
|
---|
| 330 | {
|
---|
| 331 | for ( int i = 0; i < ni; i++ )
|
---|
| 332 | {
|
---|
| 333 | if ( ci[i].minstance == newInstance )
|
---|
| 334 | {
|
---|
| 335 | theInstance->setInstanceInfo( &ci[i] );
|
---|
| 336 | iInstances[ findFreeInstance() ] = theInstance;
|
---|
| 337 | }
|
---|
| 338 | }
|
---|
| 339 | }
|
---|
| 340 | if ( ci )
|
---|
| 341 | {
|
---|
| 342 | delete[] ci;
|
---|
| 343 | }
|
---|
| 344 | setLastRC( rc );
|
---|
| 345 | return newInstance;
|
---|
| 346 | }
|
---|
| 347 |
|
---|
| 348 | //------------------------------------------------------------------------------
|
---|
| 349 | // IRTMidi :: delInstance
|
---|
| 350 | //------------------------------------------------------------------------------
|
---|
| 351 | void IRTMidi::delInstance( IMidiInstance * theInstance )
|
---|
| 352 | {
|
---|
| 353 | unsigned long rc;
|
---|
| 354 |
|
---|
| 355 | // Find instance in array and null it
|
---|
| 356 | for( unsigned int i = 0; i < MAX_INSTANCES; i++ )
|
---|
| 357 | {
|
---|
| 358 | if ( iInstances[ i ] == theInstance )
|
---|
| 359 | {
|
---|
| 360 | iInstances[ i ] = NULL;
|
---|
| 361 | }
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | // Delete MIDI Instance
|
---|
[5269] | 365 | rc = MidiDeleteInstance( theInstance->instance(), 0 );
|
---|
[4] | 366 | setLastRC( rc );
|
---|
| 367 | }
|
---|
| 368 |
|
---|
| 369 | //------------------------------------------------------------------------------
|
---|
| 370 | // IRTMidi :: delInstances (private)
|
---|
| 371 | //------------------------------------------------------------------------------
|
---|
| 372 | void IRTMidi::delInstances()
|
---|
| 373 | {
|
---|
| 374 | // Delete all instances this way as delete of an instance removes
|
---|
| 375 | // it from the instance list through the miracle of double
|
---|
| 376 | // dispatching. See above.
|
---|
| 377 | for( unsigned int i = 0; i < MAX_INSTANCES; i++ )
|
---|
| 378 | {
|
---|
| 379 | IMidiInstance * ins = iInstances[ i ];
|
---|
| 380 | if ( ins )
|
---|
| 381 | delete ins;
|
---|
| 382 | }
|
---|
| 383 | }
|
---|
| 384 |
|
---|
| 385 | //------------------------------------------------------------------------------
|
---|
| 386 | // IRTMidi :: getInstances (hardware only)
|
---|
| 387 | //------------------------------------------------------------------------------
|
---|
| 388 | unsigned long IRTMidi::getInstances()
|
---|
| 389 | {
|
---|
| 390 | // Query all Instances
|
---|
| 391 | unsigned long rc;
|
---|
| 392 | unsigned long ni = 0;
|
---|
| 393 | PMIDIINSTANCEINFO ci = NULL;
|
---|
| 394 |
|
---|
| 395 | iNumInInstances = 0;
|
---|
| 396 | iNumOutInstances = 0;
|
---|
| 397 |
|
---|
| 398 | // Query instances and post them
|
---|
[5269] | 399 | rc = MidiQueryNumInstances( &ni, 0 );
|
---|
[4] | 400 | if ( rc == 0 && ni > 0 )
|
---|
| 401 | {
|
---|
| 402 | ci = new MIDIINSTANCEINFO[ ni ];
|
---|
[5269] | 403 | rc = MidiQueryInstanceList( ni, ci, 0 );
|
---|
[4] | 404 | }
|
---|
| 405 | if ( rc == 0 && ci )
|
---|
| 406 | {
|
---|
| 407 | for ( int i = 0; i < ni; i++ )
|
---|
| 408 | {
|
---|
| 409 | if ( ci[i].ulClassNumber == hardwareClass() )
|
---|
| 410 | {
|
---|
| 411 | IMidiInstance * ins = new IMidiInstance();
|
---|
| 412 | ins ->setInstanceInfo( &ci[i] );
|
---|
| 413 | iInstances[ i ] = ins;
|
---|
| 414 | if ( ins->canSend() )
|
---|
| 415 | {
|
---|
| 416 | iInInstances[ iNumInInstances ] = ins;
|
---|
| 417 | iNumInInstances++;
|
---|
| 418 | }
|
---|
| 419 | if ( ins->canReceive() )
|
---|
| 420 | {
|
---|
| 421 | iOutInstances[ iNumOutInstances ] = ins;
|
---|
| 422 | iNumOutInstances++;
|
---|
| 423 | }
|
---|
| 424 | }
|
---|
| 425 | }
|
---|
| 426 | }
|
---|
| 427 | if ( ci )
|
---|
| 428 | {
|
---|
| 429 | delete[] ci;
|
---|
| 430 | }
|
---|
| 431 | return rc;
|
---|
| 432 | }
|
---|
| 433 |
|
---|
[5269] | 434 | void IRTMidi::startTimer()
|
---|
[4] | 435 | {
|
---|
[5269] | 436 | ((IRTMidi*)this)->setLastRC( MidiTimer( MIDI_START_TIMER, 0 ) );
|
---|
[4] | 437 | }
|
---|
| 438 |
|
---|
[5269] | 439 | void IRTMidi::stopTimer()
|
---|
[4] | 440 | {
|
---|
[5269] | 441 | ((IRTMidi*)this)->setLastRC( MidiTimer( MIDI_STOP_TIMER, 0 ) );
|
---|
[4] | 442 | }
|
---|
| 443 |
|
---|
| 444 | IRTMidi* IRTMidi::instance()
|
---|
| 445 | {
|
---|
| 446 | if ( iTheIRTMidiSingleton == NULL )
|
---|
| 447 | iTheIRTMidiSingleton = new IRTMidi();
|
---|
| 448 | return iTheIRTMidiSingleton;
|
---|
| 449 | }
|
---|
| 450 |
|
---|
| 451 | void IRTMidiShutdown()
|
---|
| 452 | {
|
---|
| 453 | IRTMidi::shutdown();
|
---|
| 454 | }
|
---|
| 455 |
|
---|
| 456 | void IRTMidi::shutdown()
|
---|
| 457 | {
|
---|
| 458 | if ( iTheIRTMidiSingleton != NULL )
|
---|
| 459 | delete iTheIRTMidiSingleton;
|
---|
| 460 | }
|
---|
| 461 |
|
---|
[21916] | 462 | ULONG IRTMidi::MidiCreateInstance( ULONG a, MINSTANCE* b, PCSZ c, ULONG d)
|
---|
[5269] | 463 | {
|
---|
| 464 | ULONG ret;
|
---|
| 465 | USHORT sel = GetFS();
|
---|
| 466 | ret = (*pfnMidiCreateInstance)(a,b,c,d);
|
---|
| 467 | SetFS(sel);
|
---|
| 468 | return ret;
|
---|
| 469 | }
|
---|
| 470 | ULONG IRTMidi::MidiDeleteInstance( MINSTANCE a, ULONG b)
|
---|
| 471 | {
|
---|
| 472 | ULONG ret;
|
---|
| 473 | USHORT sel = GetFS();
|
---|
| 474 | ret = (*pfnMidiDeleteInstance)(a,b);
|
---|
| 475 | SetFS(sel);
|
---|
| 476 | return ret;
|
---|
| 477 | }
|
---|
| 478 | ULONG IRTMidi::MidiEnableInstance( MINSTANCE a, ULONG b )
|
---|
| 479 | {
|
---|
| 480 | ULONG ret;
|
---|
| 481 | USHORT sel = GetFS();
|
---|
| 482 | ret = (*pfnMidiEnableInstance)(a,b);
|
---|
| 483 | SetFS(sel);
|
---|
| 484 | return ret;
|
---|
| 485 | }
|
---|
| 486 | ULONG IRTMidi::MidiDisableInstance( MINSTANCE a, ULONG b)
|
---|
| 487 | {
|
---|
| 488 | ULONG ret;
|
---|
| 489 | USHORT sel = GetFS();
|
---|
| 490 | ret = (*pfnMidiDisableInstance)(a,b);
|
---|
| 491 | SetFS(sel);
|
---|
| 492 | return ret;
|
---|
| 493 | }
|
---|
| 494 | ULONG IRTMidi::MidiAddLink( MINSTANCE a, MINSTANCE b, ULONG c, ULONG d )
|
---|
| 495 | {
|
---|
| 496 | ULONG ret;
|
---|
| 497 | USHORT sel = GetFS();
|
---|
| 498 | ret = (*pfnMidiAddLink)(a,b,c,d);
|
---|
| 499 | SetFS(sel);
|
---|
| 500 | return ret;
|
---|
| 501 | }
|
---|
| 502 | ULONG IRTMidi::MidiRemoveLink( MINSTANCE a, MINSTANCE b, ULONG c, ULONG d )
|
---|
| 503 | {
|
---|
| 504 | ULONG ret;
|
---|
| 505 | USHORT sel = GetFS();
|
---|
| 506 | ret = (*pfnMidiRemoveLink)(a,b,c,d);
|
---|
| 507 | SetFS(sel);
|
---|
| 508 | return ret;
|
---|
| 509 | }
|
---|
| 510 | ULONG IRTMidi::MidiQueryClassList( ULONG a, PMIDICLASSINFO b, ULONG c)
|
---|
| 511 | {
|
---|
| 512 | ULONG ret;
|
---|
| 513 | USHORT sel = GetFS();
|
---|
| 514 | ret = (*pfnMidiQueryClassList)(a,b,c);
|
---|
| 515 | SetFS(sel);
|
---|
| 516 | return ret;
|
---|
| 517 | }
|
---|
| 518 | ULONG IRTMidi::MidiQueryInstanceList ( ULONG a, PMIDIINSTANCEINFO b, ULONG c)
|
---|
| 519 | {
|
---|
| 520 | ULONG ret;
|
---|
| 521 | USHORT sel = GetFS();
|
---|
| 522 | ret = (*pfnMidiQueryInstanceList)(a,b,c);
|
---|
| 523 | SetFS(sel);
|
---|
| 524 | return ret;
|
---|
| 525 | }
|
---|
| 526 | ULONG IRTMidi::MidiQueryNumClasses ( PULONG a, ULONG b)
|
---|
| 527 | {
|
---|
| 528 | ULONG ret;
|
---|
| 529 | USHORT sel = GetFS();
|
---|
| 530 | ret = (*pfnMidiQueryNumClasses)(a,b);
|
---|
| 531 | SetFS(sel);
|
---|
| 532 | return ret;
|
---|
| 533 | }
|
---|
| 534 | ULONG IRTMidi::MidiQueryNumInstances ( PULONG a, ULONG b)
|
---|
| 535 | {
|
---|
| 536 | ULONG ret;
|
---|
| 537 | USHORT sel = GetFS();
|
---|
| 538 | ret = (*pfnMidiQueryNumInstances)(a,b);
|
---|
| 539 | SetFS(sel);
|
---|
| 540 | return ret;
|
---|
| 541 | }
|
---|
| 542 | ULONG IRTMidi::MidiSendMessages( PMESSAGE a, ULONG b, ULONG c )
|
---|
| 543 | {
|
---|
| 544 | ULONG ret;
|
---|
| 545 | USHORT sel = GetFS();
|
---|
| 546 | ret = (*pfnMidiSendMessages)(a,b,c);
|
---|
| 547 | SetFS(sel);
|
---|
| 548 | return ret;
|
---|
| 549 | }
|
---|
| 550 | ULONG IRTMidi::MidiSendSysexMessage( PMESSAGE a, ULONG b, ULONG c )
|
---|
| 551 | {
|
---|
| 552 | ULONG ret;
|
---|
| 553 | USHORT sel = GetFS();
|
---|
| 554 | ret = (*pfnMidiSendSysexMessage)(a,b,c);
|
---|
| 555 | SetFS(sel);
|
---|
| 556 | return ret;
|
---|
| 557 | }
|
---|
| 558 | ULONG IRTMidi::MidiRetrieveMessages( MINSTANCE a, PVOID b, PULONG c, ULONG d)
|
---|
| 559 | {
|
---|
| 560 | ULONG ret;
|
---|
| 561 | USHORT sel = GetFS();
|
---|
| 562 | ret = (*pfnMidiRetrieveMessages)(a,b,c,d);
|
---|
| 563 | SetFS(sel);
|
---|
| 564 | return ret;
|
---|
| 565 | }
|
---|
| 566 | ULONG IRTMidi::MidiSetup( PMIDISETUP a, ULONG b)
|
---|
| 567 | {
|
---|
| 568 | ULONG ret;
|
---|
| 569 | USHORT sel = GetFS();
|
---|
| 570 | ret = (*pfnMidiSetup)(a,b);
|
---|
| 571 | SetFS(sel);
|
---|
| 572 | return ret;
|
---|
| 573 | }
|
---|
| 574 |
|
---|
| 575 | ULONG IRTMidi::MidiTimer( ULONG a, ULONG b )
|
---|
| 576 | {
|
---|
| 577 | ULONG ret;
|
---|
| 578 | USHORT sel = GetFS();
|
---|
| 579 | ret = (*pfnMidiTimer)(a,b);
|
---|
| 580 | SetFS(sel);
|
---|
| 581 | return ret;
|
---|
| 582 | }
|
---|
| 583 |
|
---|
[4] | 584 | //------------------------------------------------------------------------------
|
---|
| 585 | // IMidiInstance::IMidiInstance
|
---|
| 586 | //------------------------------------------------------------------------------
|
---|
| 587 | IMidiInstance::IMidiInstance()
|
---|
| 588 | {
|
---|
| 589 | }
|
---|
| 590 |
|
---|
| 591 | //------------------------------------------------------------------------------
|
---|
| 592 | // IMidiInstance::~IMidiInstance
|
---|
| 593 | //------------------------------------------------------------------------------
|
---|
| 594 | IMidiInstance::~IMidiInstance()
|
---|
| 595 | {
|
---|
| 596 | // Disable send and receive if set
|
---|
| 597 | if ( isReceive() ) enableReceive( FALSE );
|
---|
| 598 | if ( isSend() ) enableSend( FALSE );
|
---|
| 599 | // Remove from RTMIDI
|
---|
| 600 | IRTMIDI->delInstance( this );
|
---|
| 601 | }
|
---|
| 602 |
|
---|
| 603 | //------------------------------------------------------------------------------
|
---|
| 604 | // IMidiInstance :: setInfo
|
---|
| 605 | //------------------------------------------------------------------------------
|
---|
| 606 | void IMidiInstance::setInstanceInfo( MIDIINSTANCEINFO* i )
|
---|
| 607 | {
|
---|
| 608 | memcpy( &iInfo, i, sizeof( MIDIINSTANCEINFO ) );
|
---|
| 609 | }
|
---|
| 610 |
|
---|
| 611 | MINSTANCE IMidiInstance::instance() const
|
---|
| 612 | {
|
---|
| 613 | return iInfo.minstance;
|
---|
| 614 | }
|
---|
| 615 |
|
---|
| 616 | unsigned long IMidiInstance::classNum() const
|
---|
| 617 | {
|
---|
| 618 | return iInfo.ulClassNumber;
|
---|
| 619 | }
|
---|
| 620 |
|
---|
| 621 | char * IMidiInstance::name()
|
---|
| 622 | {
|
---|
| 623 | return iInfo.szmInstanceName;
|
---|
| 624 | }
|
---|
| 625 |
|
---|
| 626 | unsigned long IMidiInstance::numLinks() const
|
---|
| 627 | {
|
---|
| 628 | return iInfo.ulNumLinks;
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | unsigned long IMidiInstance::attributes() const
|
---|
| 632 | {
|
---|
| 633 | return iInfo.ulAttributes;
|
---|
| 634 | }
|
---|
| 635 |
|
---|
| 636 | BOOL IMidiInstance::isSend() const
|
---|
| 637 | {
|
---|
| 638 | return ( iInfo.ulAttributes & MIDI_INST_ATTR_ENABLE_S );
|
---|
| 639 | }
|
---|
| 640 |
|
---|
| 641 | IMidiInstance& IMidiInstance::enableSend(BOOL enable)
|
---|
| 642 | {
|
---|
| 643 | if (!(isSend() == enable))
|
---|
| 644 | {
|
---|
| 645 | unsigned long rc;
|
---|
| 646 | if ( enable )
|
---|
| 647 | {
|
---|
| 648 | // Enable send
|
---|
[5269] | 649 | rc = IRTMIDI->MidiEnableInstance( instance(), MIDI_ENABLE_SEND );
|
---|
[4] | 650 | if ( rc == 0 )
|
---|
| 651 | iInfo.ulAttributes |= MIDI_INST_ATTR_ENABLE_S;
|
---|
| 652 | }
|
---|
| 653 | else
|
---|
| 654 | {
|
---|
| 655 | // Disable send
|
---|
[5269] | 656 | rc = IRTMIDI->MidiDisableInstance( instance(), MIDI_DISABLE_SEND );
|
---|
[4] | 657 | if ( rc == 0 )
|
---|
| 658 | iInfo.ulAttributes &= ~MIDI_INST_ATTR_ENABLE_S;
|
---|
| 659 | }
|
---|
| 660 | IRTMIDI->setLastRC( rc );
|
---|
| 661 | }
|
---|
| 662 | return *this;
|
---|
| 663 | }
|
---|
| 664 |
|
---|
| 665 | BOOL IMidiInstance::isReceive() const
|
---|
| 666 | {
|
---|
| 667 | return ( iInfo.ulAttributes & MIDI_INST_ATTR_ENABLE_R );
|
---|
| 668 | }
|
---|
| 669 |
|
---|
| 670 | IMidiInstance& IMidiInstance::enableReceive(BOOL enable)
|
---|
| 671 | {
|
---|
| 672 | if (!(isReceive() == enable))
|
---|
| 673 | {
|
---|
| 674 | unsigned long rc;
|
---|
| 675 | if ( enable )
|
---|
| 676 | {
|
---|
| 677 | // Enable receive
|
---|
[5269] | 678 | rc = IRTMIDI->MidiEnableInstance( instance(), MIDI_ENABLE_RECEIVE );
|
---|
[4] | 679 | if ( rc == 0 )
|
---|
| 680 | iInfo.ulAttributes |= MIDI_INST_ATTR_ENABLE_R;
|
---|
| 681 | }
|
---|
| 682 | else
|
---|
| 683 | {
|
---|
| 684 | // Disable receive
|
---|
[5269] | 685 | rc = IRTMIDI->MidiDisableInstance( instance(), MIDI_DISABLE_RECEIVE );
|
---|
[4] | 686 | if ( rc == 0 )
|
---|
| 687 | iInfo.ulAttributes &= ~MIDI_INST_ATTR_ENABLE_R;
|
---|
| 688 | }
|
---|
| 689 | IRTMIDI->setLastRC( rc );
|
---|
| 690 | }
|
---|
| 691 | return *this;
|
---|
| 692 | }
|
---|
| 693 |
|
---|
| 694 | BOOL IMidiInstance::canReceive() const
|
---|
| 695 | {
|
---|
| 696 | return ( iInfo.ulAttributes & MIDI_INST_ATTR_CAN_RECV );
|
---|
| 697 | }
|
---|
| 698 |
|
---|
| 699 | BOOL IMidiInstance::canSend() const
|
---|
| 700 | {
|
---|
| 701 | return ( iInfo.ulAttributes & MIDI_INST_ATTR_CAN_SEND );
|
---|
| 702 | }
|
---|
| 703 |
|
---|
| 704 | IMidiInstance& IMidiInstance::removeLink(IMidiInstance* toLink)
|
---|
| 705 | {
|
---|
| 706 | if ( canSend() && toLink->canReceive() )
|
---|
| 707 | {
|
---|
| 708 | IRTMIDI->setLastRC(
|
---|
[5269] | 709 | IRTMIDI->MidiRemoveLink( instance(), toLink->instance(),
|
---|
[4] | 710 | 0, // slot?
|
---|
| 711 | 0 ) );
|
---|
| 712 | }
|
---|
| 713 | return *this;
|
---|
| 714 | }
|
---|
| 715 |
|
---|
| 716 | IMidiInstance& IMidiInstance::addLink(IMidiInstance* toLink)
|
---|
| 717 | {
|
---|
| 718 | if ( canSend() && toLink->canReceive() )
|
---|
| 719 | {
|
---|
| 720 | if ( !isSend() )
|
---|
| 721 | {
|
---|
| 722 | enableSend();
|
---|
| 723 | }
|
---|
| 724 | if ( !toLink->isReceive() )
|
---|
| 725 | {
|
---|
| 726 | toLink->enableReceive();
|
---|
| 727 | }
|
---|
| 728 | IRTMIDI->setLastRC(
|
---|
[5269] | 729 | IRTMIDI->MidiAddLink( instance(), toLink->instance(),
|
---|
[4] | 730 | 0, // slot ?
|
---|
| 731 | 0 ) );
|
---|
| 732 | }
|
---|
| 733 | return *this;
|
---|
| 734 | }
|
---|
| 735 |
|
---|
| 736 | //------------------------------------------------------------------------------
|
---|
| 737 | // IMidiInstance :: sendMessage
|
---|
| 738 | //------------------------------------------------------------------------------
|
---|
| 739 | void IMidiInstance::sendMessage( UCHAR b1, UCHAR b2, UCHAR b3, UCHAR b4 ) const
|
---|
| 740 | {
|
---|
| 741 | // Build message
|
---|
| 742 | MESSAGE msg;
|
---|
| 743 | msg.ulSourceInstance = instance();
|
---|
| 744 | msg.ulTime = 0;
|
---|
| 745 | msg.ulTrack = 0;
|
---|
| 746 | msg.msg.abData[0] = b1;
|
---|
| 747 | msg.msg.abData[1] = b2;
|
---|
| 748 | msg.msg.abData[2] = b3;
|
---|
| 749 | msg.msg.abData[3] = b4;
|
---|
[5269] | 750 | IRTMIDI->setLastRC( IRTMIDI->MidiSendMessages( &msg, 1, 0 ) );
|
---|
[4] | 751 | }
|
---|
| 752 |
|
---|
| 753 | //------------------------------------------------------------------------------
|
---|
| 754 | // IMidiInstance :: sendMessage
|
---|
| 755 | //------------------------------------------------------------------------------
|
---|
| 756 | void IMidiInstance::sendMessage( ULONG inMsg ) const
|
---|
| 757 | {
|
---|
| 758 | // Build message
|
---|
| 759 | MESSAGE msg;
|
---|
| 760 | msg.ulSourceInstance = instance();
|
---|
| 761 | msg.ulTime = 0;
|
---|
| 762 | msg.ulTrack = 0;
|
---|
| 763 | msg.msg.ulMessage = inMsg;
|
---|
[5269] | 764 | IRTMIDI->setLastRC( IRTMIDI->MidiSendMessages( &msg, 1, 0 ) );
|
---|
[4] | 765 | }
|
---|
| 766 |
|
---|
| 767 | //------------------------------------------------------------------------------
|
---|
| 768 | // IMidiInstance :: sendSysexMessage
|
---|
| 769 | //------------------------------------------------------------------------------
|
---|
| 770 | void IMidiInstance::sendSysexMessage( UCHAR* theMsg, ULONG msgLen ) const
|
---|
| 771 | {
|
---|
| 772 | // Build message
|
---|
| 773 | MESSAGE* msg;
|
---|
| 774 | ULONG outLen = sizeof(MESSAGE) - 4 + msgLen;
|
---|
| 775 | msg = (MESSAGE*)malloc( outLen );
|
---|
| 776 |
|
---|
| 777 | msg->ulSourceInstance = instance();
|
---|
| 778 | msg->ulTime = 0;
|
---|
| 779 | msg->ulTrack = 0;
|
---|
| 780 | memcpy( msg->msg.abData, theMsg, outLen );
|
---|
[5269] | 781 | IRTMIDI->setLastRC( IRTMIDI->MidiSendSysexMessage( msg, outLen, 0 ) );
|
---|
[4] | 782 | free(msg);
|
---|
| 783 | }
|
---|
| 784 |
|
---|
| 785 | unsigned long IMidiInstance::getMessage( ULONG * pTime, ULONG * pMsg )
|
---|
| 786 | {
|
---|
| 787 | MESSAGE theMessage;
|
---|
| 788 | unsigned long numUCHARs;
|
---|
| 789 | unsigned long rc = 0;
|
---|
| 790 | numUCHARs = sizeof( theMessage );
|
---|
[5269] | 791 | rc = IRTMIDI->MidiRetrieveMessages( instance(), &theMessage, &numUCHARs, 0 );
|
---|
[4] | 792 | if ( rc == 0 )
|
---|
| 793 | {
|
---|
| 794 | *pTime = theMessage.ulTime;
|
---|
| 795 | *pMsg = theMessage.msg.ulMessage;
|
---|
| 796 | }
|
---|
| 797 | IRTMIDI->setLastRC( rc );
|
---|
| 798 | return rc;
|
---|
| 799 | }
|
---|
| 800 |
|
---|
| 801 | //------------------------------------------------------------------------------
|
---|
| 802 | // IAppMidiInstance::IAppMidiInstance
|
---|
| 803 | //------------------------------------------------------------------------------
|
---|
| 804 | unsigned long IAppMidiInstance::appNum = 0;
|
---|
| 805 |
|
---|
| 806 | IAppMidiInstance::IAppMidiInstance( unsigned long attrs )
|
---|
| 807 | {
|
---|
| 808 | iInfo.ulAttributes = attrs;
|
---|
| 809 | char name[32];
|
---|
| 810 | appNum++;
|
---|
| 811 | sprintf( name, "MIDI App(%d)", appNum );
|
---|
| 812 |
|
---|
| 813 | // Create application instance
|
---|
| 814 | MINSTANCE AppInstance = IRTMIDI->addInstance(
|
---|
| 815 | this,
|
---|
| 816 | IRTMIDI->applicationClass(),
|
---|
| 817 | name );
|
---|
| 818 | }
|
---|
| 819 |
|
---|
| 820 | IAppMidiInstance::~IAppMidiInstance()
|
---|
| 821 | {
|
---|
| 822 | }
|
---|
| 823 |
|
---|
[588] | 824 |
|
---|