source: trunk/src/winmm/IRTMidi.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 22.2 KB
Line 
1/* $Id: IRTMidi.cpp,v 1.7 2001-02-26 20:14:38 sandervl 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
16
17/****************************************************************************
18 * Includes *
19 ****************************************************************************/
20
21#define INCL_DOS
22#include <os2wrap.h> //Odin32 OS/2 api wrappers
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
30#define DBG_LOCALLOG DBG_irtmidi
31#include "dbglocal.h"
32
33IRTMidi * IRTMidi::iTheIRTMidiSingleton = NULL;
34
35//------------------------------------------------------------------------------
36// IRTMidi::IRTMidi
37//------------------------------------------------------------------------------
38IRTMidi::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 )
63 rc = MidiSetup( &iSetup, 0 );
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
85unsigned 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;
95 pfnMidiCreateInstance = (ULONG(APIENTRY *)( ULONG, MINSTANCE*, PCSZ, ULONG)) modAddr;
96
97 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIDeleteInstance", &modAddr );
98 if ( rc ) return rc;
99 pfnMidiDeleteInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
100
101 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIEnableInstance", &modAddr );
102 if ( rc ) return rc;
103 pfnMidiEnableInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
104
105 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIDisableInstance", &modAddr );
106 if ( rc ) return rc;
107 pfnMidiDisableInstance = (ULONG(APIENTRY *)(MINSTANCE, ULONG)) modAddr;
108
109 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIAddLink", &modAddr );
110 if ( rc ) return rc;
111 pfnMidiAddLink = (ULONG(APIENTRY *)(MINSTANCE, MINSTANCE, ULONG, ULONG)) modAddr;
112
113 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIRemoveLink", &modAddr );
114 if ( rc ) return rc;
115 pfnMidiRemoveLink = (ULONG(APIENTRY *)(MINSTANCE, MINSTANCE, ULONG, ULONG)) modAddr;
116
117 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryClassList", &modAddr );
118 if ( rc ) return rc;
119 pfnMidiQueryClassList = (ULONG(APIENTRY *)(ULONG, PMIDICLASSINFO, ULONG)) modAddr;
120
121 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryInstanceList", &modAddr );
122 if ( rc ) return rc;
123 pfnMidiQueryInstanceList = (ULONG(APIENTRY *)(ULONG, PMIDIINSTANCEINFO, ULONG)) modAddr;
124
125 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryNumClasses", &modAddr );
126 if ( rc ) return rc;
127 pfnMidiQueryNumClasses = (ULONG(APIENTRY *)(PULONG, ULONG)) modAddr;
128
129 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIQueryNumInstances", &modAddr );
130 if ( rc ) return rc;
131 pfnMidiQueryNumInstances = (ULONG(APIENTRY *)(PULONG, ULONG)) modAddr;
132
133 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISendMessages", &modAddr );
134 if ( rc ) return rc;
135 pfnMidiSendMessages = (ULONG(APIENTRY *)(PMESSAGE, ULONG, ULONG)) modAddr;
136
137 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISendSysexMessage", &modAddr );
138 if ( rc ) return rc;
139 pfnMidiSendSysexMessage = (ULONG(APIENTRY *)(PMESSAGE, ULONG, ULONG)) modAddr;
140
141 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDIRetrieveMessages", &modAddr );
142 if ( rc ) return rc;
143 pfnMidiRetrieveMessages = (ULONG(APIENTRY *)(MINSTANCE, PVOID, PULONG, ULONG)) modAddr;
144
145 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDISetup", &modAddr );
146 if ( rc ) return rc;
147 pfnMidiSetup = (ULONG(APIENTRY *)(PMIDISETUP, ULONG)) modAddr;
148
149 rc = DosQueryProcAddr( iRTMidiModule, 0L, "MIDITimer", &modAddr );
150 if ( rc ) return rc;
151 pfnMidiTimer = (ULONG(APIENTRY *)(ULONG, ULONG)) modAddr;
152
153 return 0;
154}
155
156//------------------------------------------------------------------------------
157// IRTMidi::~IRTMidi
158//------------------------------------------------------------------------------
159IRTMidi::~IRTMidi()
160{
161 stopTimer();
162 delInstances();
163 iTheIRTMidiSingleton = NULL;
164}
165
166void IRTMidi::setLastRC(unsigned long theRC)
167{
168 iLastRC = theRC;
169}
170
171void IRTMidi::resetLastRC()
172{
173 setLastRC( 0 );
174}
175
176//------------------------------------------------------------------------------
177// IRTMidi :: RCExplanation
178//------------------------------------------------------------------------------
179const char * IRTMidi::RCExplanation() const
180{
181 const char * DebugString;
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//------------------------------------------------------------------------------
262unsigned 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
269 rc = MidiQueryNumClasses( &nc, 0 );
270 if ( rc == 0 && nc > 0 )
271 {
272 ci = new MIDICLASSINFO[ nc ];
273 rc = MidiQueryClassList( nc, ci, 0 );
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
292unsigned 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//------------------------------------------------------------------------------
306MINSTANCE 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
315 rc = MidiCreateInstance( classNum,
316 &newInstance,
317 instanceName,
318 0 );
319 // Now find it to initialize the Instance Object
320 if ( rc == 0 )
321 {
322 rc = MidiQueryNumInstances( &ni, 0 );
323 if ( rc == 0 && ni > 0 )
324 {
325 ci = new MIDIINSTANCEINFO[ ni ];
326 rc = MidiQueryInstanceList( ni, ci, 0 );
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//------------------------------------------------------------------------------
351void 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
365 rc = MidiDeleteInstance( theInstance->instance(), 0 );
366 setLastRC( rc );
367}
368
369//------------------------------------------------------------------------------
370// IRTMidi :: delInstances (private)
371//------------------------------------------------------------------------------
372void 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//------------------------------------------------------------------------------
388unsigned 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
399 rc = MidiQueryNumInstances( &ni, 0 );
400 if ( rc == 0 && ni > 0 )
401 {
402 ci = new MIDIINSTANCEINFO[ ni ];
403 rc = MidiQueryInstanceList( ni, ci, 0 );
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
434void IRTMidi::startTimer()
435{
436 ((IRTMidi*)this)->setLastRC( MidiTimer( MIDI_START_TIMER, 0 ) );
437}
438
439void IRTMidi::stopTimer()
440{
441 ((IRTMidi*)this)->setLastRC( MidiTimer( MIDI_STOP_TIMER, 0 ) );
442}
443
444IRTMidi* IRTMidi::instance()
445{
446 if ( iTheIRTMidiSingleton == NULL )
447 iTheIRTMidiSingleton = new IRTMidi();
448 return iTheIRTMidiSingleton;
449}
450
451void IRTMidiShutdown()
452{
453 IRTMidi::shutdown();
454}
455
456void IRTMidi::shutdown()
457{
458 if ( iTheIRTMidiSingleton != NULL )
459 delete iTheIRTMidiSingleton;
460}
461
462ULONG IRTMidi::MidiCreateInstance( ULONG a, MINSTANCE* b, PCSZ c, ULONG d)
463{
464 ULONG ret;
465 USHORT sel = GetFS();
466 ret = (*pfnMidiCreateInstance)(a,b,c,d);
467 SetFS(sel);
468 return ret;
469}
470ULONG 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}
478ULONG 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}
486ULONG 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}
494ULONG 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}
502ULONG 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}
510ULONG 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}
518ULONG 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}
526ULONG 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}
534ULONG 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}
542ULONG 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}
550ULONG 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}
558ULONG 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}
566ULONG 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
575ULONG 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
584//------------------------------------------------------------------------------
585// IMidiInstance::IMidiInstance
586//------------------------------------------------------------------------------
587IMidiInstance::IMidiInstance()
588{
589}
590
591//------------------------------------------------------------------------------
592// IMidiInstance::~IMidiInstance
593//------------------------------------------------------------------------------
594IMidiInstance::~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//------------------------------------------------------------------------------
606void IMidiInstance::setInstanceInfo( MIDIINSTANCEINFO* i )
607{
608 memcpy( &iInfo, i, sizeof( MIDIINSTANCEINFO ) );
609}
610
611MINSTANCE IMidiInstance::instance() const
612{
613 return iInfo.minstance;
614}
615
616unsigned long IMidiInstance::classNum() const
617{
618 return iInfo.ulClassNumber;
619}
620
621char * IMidiInstance::name()
622{
623 return iInfo.szmInstanceName;
624}
625
626unsigned long IMidiInstance::numLinks() const
627{
628 return iInfo.ulNumLinks;
629}
630
631unsigned long IMidiInstance::attributes() const
632{
633 return iInfo.ulAttributes;
634}
635
636BOOL IMidiInstance::isSend() const
637{
638 return ( iInfo.ulAttributes & MIDI_INST_ATTR_ENABLE_S );
639}
640
641IMidiInstance& IMidiInstance::enableSend(BOOL enable)
642{
643 if (!(isSend() == enable))
644 {
645 unsigned long rc;
646 if ( enable )
647 {
648 // Enable send
649 rc = IRTMIDI->MidiEnableInstance( instance(), MIDI_ENABLE_SEND );
650 if ( rc == 0 )
651 iInfo.ulAttributes |= MIDI_INST_ATTR_ENABLE_S;
652 }
653 else
654 {
655 // Disable send
656 rc = IRTMIDI->MidiDisableInstance( instance(), MIDI_DISABLE_SEND );
657 if ( rc == 0 )
658 iInfo.ulAttributes &= ~MIDI_INST_ATTR_ENABLE_S;
659 }
660 IRTMIDI->setLastRC( rc );
661 }
662 return *this;
663}
664
665BOOL IMidiInstance::isReceive() const
666{
667 return ( iInfo.ulAttributes & MIDI_INST_ATTR_ENABLE_R );
668}
669
670IMidiInstance& IMidiInstance::enableReceive(BOOL enable)
671{
672 if (!(isReceive() == enable))
673 {
674 unsigned long rc;
675 if ( enable )
676 {
677 // Enable receive
678 rc = IRTMIDI->MidiEnableInstance( instance(), MIDI_ENABLE_RECEIVE );
679 if ( rc == 0 )
680 iInfo.ulAttributes |= MIDI_INST_ATTR_ENABLE_R;
681 }
682 else
683 {
684 // Disable receive
685 rc = IRTMIDI->MidiDisableInstance( instance(), MIDI_DISABLE_RECEIVE );
686 if ( rc == 0 )
687 iInfo.ulAttributes &= ~MIDI_INST_ATTR_ENABLE_R;
688 }
689 IRTMIDI->setLastRC( rc );
690 }
691 return *this;
692}
693
694BOOL IMidiInstance::canReceive() const
695{
696 return ( iInfo.ulAttributes & MIDI_INST_ATTR_CAN_RECV );
697}
698
699BOOL IMidiInstance::canSend() const
700{
701 return ( iInfo.ulAttributes & MIDI_INST_ATTR_CAN_SEND );
702}
703
704IMidiInstance& IMidiInstance::removeLink(IMidiInstance* toLink)
705{
706 if ( canSend() && toLink->canReceive() )
707 {
708 IRTMIDI->setLastRC(
709 IRTMIDI->MidiRemoveLink( instance(), toLink->instance(),
710 0, // slot?
711 0 ) );
712 }
713 return *this;
714}
715
716IMidiInstance& 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(
729 IRTMIDI->MidiAddLink( instance(), toLink->instance(),
730 0, // slot ?
731 0 ) );
732 }
733 return *this;
734}
735
736//------------------------------------------------------------------------------
737// IMidiInstance :: sendMessage
738//------------------------------------------------------------------------------
739void 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;
750 IRTMIDI->setLastRC( IRTMIDI->MidiSendMessages( &msg, 1, 0 ) );
751}
752
753//------------------------------------------------------------------------------
754// IMidiInstance :: sendMessage
755//------------------------------------------------------------------------------
756void 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;
764 IRTMIDI->setLastRC( IRTMIDI->MidiSendMessages( &msg, 1, 0 ) );
765}
766
767//------------------------------------------------------------------------------
768// IMidiInstance :: sendSysexMessage
769//------------------------------------------------------------------------------
770void 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 );
781 IRTMIDI->setLastRC( IRTMIDI->MidiSendSysexMessage( msg, outLen, 0 ) );
782 free(msg);
783}
784
785unsigned long IMidiInstance::getMessage( ULONG * pTime, ULONG * pMsg )
786{
787 MESSAGE theMessage;
788 unsigned long numUCHARs;
789 unsigned long rc = 0;
790 numUCHARs = sizeof( theMessage );
791 rc = IRTMIDI->MidiRetrieveMessages( instance(), &theMessage, &numUCHARs, 0 );
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//------------------------------------------------------------------------------
804unsigned long IAppMidiInstance::appNum = 0;
805
806IAppMidiInstance::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
820IAppMidiInstance::~IAppMidiInstance()
821{
822}
823
824
Note: See TracBrowser for help on using the repository browser.