source: trunk/src/winmm/IRTMidi.cpp@ 46

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

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