source: cmedia/trunk/Drv16/rtmidi.cpp@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 7.0 KB
Line 
1/* $Id: rtmidi.cpp,v 1.1 2000/04/23 14:55:20 ktk Exp $ */
2
3/* SCCSID = %W% %E% */
4/****************************************************************************
5 * *
6 * Copyright (c) IBM Corporation 1994 - 1997. *
7 * *
8 * The following IBM OS/2 source code is provided to you solely for the *
9 * the purpose of assisting you in your development of OS/2 device drivers. *
10 * You may use this code in accordance with the IBM License Agreement *
11 * provided in the IBM Device Driver Source Kit for OS/2. *
12 * *
13 ****************************************************************************/
14/**@internal %W%
15 * RTMIDI object implementation. IDC Entry points shared between RTMIDI
16 * (MIDI.SYS) and this driver are implemented here.
17 * @version %I%
18 * @context
19 * Unless otherwise noted, all interfaces are Ring-0, 16-bit, kernel stack.
20 * @notes
21 * @history
22 */
23
24#define INCL_NOPMAPI
25#include <os2.h>
26#include <devhelp.h>
27#include <include.h>
28#include "midi_idc.h" // RTMIDI interfaces
29#include "maudio.hpp" // MIDIAUDIO
30#include "rtmidi.hpp" // Object definition.
31
32
33/**@internal RTMIDI::_bIsRTMIDIDevice
34 * Opens the MIDI device for either send or receive
35 * @param USHORT pMidiAudio - pointer to MIDI Audio hardware object of interest.
36 * @param USHORT usMode - either MIDIMODE_OPEN_RECEIVE or MIDIMODE_OPEN_SEND
37 * @notes
38 * This function initializes (opens) the MIDI device for either send or receive.
39 */
40static BOOL RTMIDI::_bIsRTMIDIDevice( MIDIAUDIO* pma )
41{
42 // FMSYNTH not included because the HW object has no ability to
43 // parse an incoming byte stream into MIDI commands at this time.
44 // This could be accomplished by packaging the existing MIDI
45 // parser as an object, and associating it with the hardware instead
46 // of organizing it with the stream.
47
48 return
49 (pma->usDeviceType == AUDIOHW_MPU401_CAPTURE) ||
50 (pma->usDeviceType == AUDIOHW_MPU401_PLAY) ;
51}
52
53
54static VOID RTMIDI::vConnect( VOID )
55{
56 static MIDI_ATTACH_DD DDTable; // It's got to be in DS, so make it static.
57 MIDI_REGISTER reg;
58 MIDIREG_TYPEA regA;
59 USHORT usRC;
60
61 if (DevHelp_AttachDD((NPSZ) "MIDI$ ", (NPBYTE) &DDTable)) {
62 return;
63 }
64
65 // Call the RTMIDI driver using the function pointer provided by the
66 // AttachDD. The function call returns void. We check for errors by
67 // verifying validity of returned data: All MIDI.SYS function entry
68 // points are in the same segment & must all have the same selector.
69
70 reg.pfnRegisterA = 0;
71 reg.usSize = sizeof(reg);
72 DDTable.pfn( &reg );
73 if (SELECTOROF(reg.pfnRegisterA) != SELECTOROF(DDTable.pfn)) {
74 return;
75 }
76
77 regA.usSize = sizeof(regA);
78
79 regA.in.pfnOpen = RTMIDI::Open;
80 regA.in.pfnClose = RTMIDI::Close;
81 regA.in.pfnRecvString = RTMIDI::RecvString; // Required
82 regA.in.pfnRecvByte = RTMIDI::RecvByte; // Required
83
84 // This is also an MMPM driver, so we don't want to support the MMPM bridge
85 regA.in.pfnIOCtl=NULL;
86
87 // Now register each MIDI hardware object.
88 // We assume that all MIDI hardware objects are setup at INIT time,
89 // and assume szName and ulCapabilities fields are properly init'd.
90 // We use the MIDI hw object address as its device ID.
91
92 MIDIAUDIO* pma = (MIDIAUDIO *) pAudioHWList->Head();
93 while (pma) {
94 if ( _bIsRTMIDIDevice( pma )) {
95 regA.in.pszInstanceName = pma->szRTMIDI_Name;
96 regA.in.flCapabilities = pma->ulRTMIDI_Caps;
97 regA.in.usDevId = (USHORT) pma;
98 // The device ID is the pointer to the object
99
100 usRC = reg.pfnRegisterA( &regA );
101 if (!usRC) {
102 pma->ulRTMIDI_Handle = regA.out.ulHandle;
103 pma->pfnSendByte = regA.out.pfnSendByte;
104 pma->pfnDeregister = regA.out.pfnDeregister;
105 }
106 }
107 pma = (MIDIAUDIO *) pma->pNext;
108 }
109
110 return;
111}
112
113
114/**@external RTMIDI::Open
115 * Opens the MIDI device for either send or receive
116 * @param USHORT pMidiAudio - pointer to MIDI Audio hardware object of interest.
117 * @param USHORT usMode - either MIDIMODE_OPEN_RECEIVE or MIDIMODE_OPEN_SEND
118 * @notes
119 * This function initializes (opens) the MIDI device for either send or receive.
120 */
121static USHORT __far __loadds __cdecl
122RTMIDI::Open(USHORT pMidiAudio, USHORT usMode)
123{
124 MIDIAUDIO *pma = (MIDIAUDIO *) pMidiAudio;
125
126 switch (usMode) {
127 case MIDIMODE_OPEN_RECEIVE:
128 return pma->RTMIDI_OpenReceive();
129 case MIDIMODE_OPEN_SEND:
130 return pma->RTMIDI_OpenSend();
131 }
132
133 // Invalid mode requested, so just return general failure
134 return MIDIERRA_GEN_FAILURE;
135}
136
137
138/**@external RTMIDI::Close
139 * Closes the MIDI device for either send or receive
140 * @param USHORT pMidiAudio - pointer to MIDI Audio hardware object of interest.
141 * @param USHORT usMode - either MIDIMODE_OPEN_RECEIVE or MIDIMODE_OPEN_SEND
142 * @notes
143 * This function closes the MIDI device.
144 */
145static USHORT __far __loadds __cdecl
146RTMIDI::Close(USHORT pMidiAudio, USHORT usMode)
147{
148 MIDIAUDIO *pma = (MIDIAUDIO *) pMidiAudio;
149
150 switch (usMode) {
151 case MIDIMODE_OPEN_RECEIVE:
152 return pma->RTMIDI_CloseReceive();
153 case MIDIMODE_OPEN_SEND:
154 return pma->RTMIDI_CloseSend();
155 }
156
157 // Invalid mode requested, so just return general failure
158 return MIDIERRA_GEN_FAILURE;
159}
160
161
162/**@external RTMIDI::RecvByte
163 * Receives a single byte of MIDI data from the MIDI driver
164 * @param USHORT pMidiAudio - pointer to MIDI Audio hardware object of interest.
165 * @param BYTE b - the byte to write out to the MIDI hardware
166 * @notes
167 * The MIDI driver calls this function to send a single byte of MIDI data.
168 * If this function returns error, the MIDI driver will probably close device.
169 */
170static USHORT __far __loadds __cdecl
171RTMIDI::RecvByte(USHORT pMidiAudio, BYTE b)
172{
173 MIDIAUDIO *pma = (MIDIAUDIO *) pMidiAudio;
174
175 return pma->writeByte(b) ? 0 : MIDIERRA_HW_FAILED;
176}
177
178
179/**@external RecvString
180 * Receives a string (not null-terminated) of MIDI data from the MIDI driver
181 * @param USHORT pMidiAudio - pointer to MIDI Audio hardware object of interest.
182 * @param BYTE* pb - far pointer to the string
183 * @param USHORT usLength - length of that string
184 * @notes
185 * The MIDI driver calls this function to send a string of MIDI data. Typically,
186 * this will be used only for large chunks of bytes, such as a SysEx message.
187 * If this function returns error, the MIDI driver will probably close device.
188 */
189static USHORT __far __loadds __cdecl
190RTMIDI::RecvString(USHORT pMidiAudio, BYTE __far *pb, USHORT usLength)
191{
192 MIDIAUDIO *pma = (MIDIAUDIO *) pMidiAudio;
193
194 while (usLength--)
195 if (!pma->writeByte(*pb++))
196 return MIDIERRA_HW_FAILED;
197
198 return 0;
199}
200
Note: See TracBrowser for help on using the repository browser.