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

Last change on this file since 4 was 4, checked in by ktk, 26 years ago

Import

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