2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
16 #include "multimedia.h"
23 static LINUX_MIDIIN MidiInDev
[MAX_MIDIINDRV
];
24 static LINUX_MIDIOUT MidiOutDev
[MAX_MIDIOUTDRV
];
25 static LINUX_MCIMIDI MCIMidiDev
[MAX_MCIMIDIDRV
];
27 /* this is the total number of MIDI devices found */
30 /* this structure holds pointers with information for each MIDI
33 LPMIDIOUTCAPS16 midiDevices
[MAX_MIDIOUTDRV
];
35 /**************************************************************************
36 * MIDI_NotifyClient [internal]
38 static DWORD
MIDI_NotifyClient(UINT16 wDevID
, WORD wMsg
,
39 DWORD dwParam1
, DWORD dwParam2
)
41 TRACE(midi
,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID
, wMsg
, dwParam1
, dwParam2
);
47 if (wDevID
> MAX_MIDIOUTDRV
) return MCIERR_INTERNAL
;
49 if (MidiOutDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
50 MidiOutDev
[wDevID
].midiDesc
.dwCallback
,
51 MidiOutDev
[wDevID
].wFlags
,
52 MidiOutDev
[wDevID
].midiDesc
.hMidi
,
54 MidiOutDev
[wDevID
].midiDesc
.dwInstance
,
57 WARN(midi
,"can't notify client !\n");
58 return MMSYSERR_NOERROR
;
64 if (wDevID
> MAX_MIDIINDRV
) return MCIERR_INTERNAL
;
66 if (MidiInDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
67 MidiInDev
[wDevID
].midiDesc
.dwCallback
, MidiInDev
[wDevID
].wFlags
,
68 MidiInDev
[wDevID
].midiDesc
.hMidi
, wMsg
,
69 MidiInDev
[wDevID
].midiDesc
.dwInstance
, dwParam1
, dwParam2
)) {
70 WARN(mciwave
,"can't notify client !\n");
71 return MMSYSERR_NOERROR
;
79 /**************************************************************************
80 * MIDI_ReadByte [internal]
82 static DWORD
MIDI_ReadByte(UINT16 wDevID
, BYTE
*lpbyt
)
85 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)lpbyt
,
86 (long) sizeof(BYTE
)) == (long) sizeof(BYTE
)) {
90 WARN(midi
, "error reading wDevID=%04X\n", wDevID
);
91 return MCIERR_INTERNAL
;
96 /**************************************************************************
97 * MIDI_ReadWord [internal]
99 static DWORD
MIDI_ReadWord(UINT16 wDevID
, LPWORD lpw
)
103 if (MIDI_ReadByte(wDevID
, &hibyte
) == 0) {
104 if (MIDI_ReadByte(wDevID
, &lobyte
) == 0) {
105 *lpw
= ((WORD
)hibyte
<< 8) + lobyte
;
110 WARN(midi
, "error reading wDevID=%04X\n", wDevID
);
111 return MCIERR_INTERNAL
;
115 /**************************************************************************
116 * MIDI_ReadLong [internal]
118 static DWORD
MIDI_ReadLong(UINT16 wDevID
, LPDWORD lpdw
)
122 if (MIDI_ReadWord(wDevID
, &hiword
) == 0) {
123 if (MIDI_ReadWord(wDevID
, &loword
) == 0) {
124 *lpdw
= MAKELONG(loword
, hiword
);
129 WARN(midi
, "error reading wDevID=%04X\n", wDevID
);
130 return MCIERR_INTERNAL
;
134 /**************************************************************************
135 * MIDI_ReadVaryLen [internal]
137 static DWORD
MIDI_ReadVaryLen(UINT16 wDevID
, LPDWORD lpdw
)
141 if (lpdw
== NULL
) return MCIERR_INTERNAL
;
142 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
143 WARN(midi
, "error reading wDevID=%04X\n", wDevID
);
144 return MCIERR_INTERNAL
;
146 value
= (DWORD
)(byte
& 0x7F);
147 while (byte
& 0x80) {
148 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
149 WARN(midi
, "error reading wDevID=%04X\n", wDevID
);
150 return MCIERR_INTERNAL
;
152 value
= (value
<< 7) + (byte
& 0x7F);
156 TRACE(midi, "val=%08lX \n", value);
162 /**************************************************************************
163 * MIDI_ReadMThd [internal]
165 static DWORD
MIDI_ReadMThd(UINT16 wDevID
, DWORD dwOffset
)
169 TRACE(midi
, "(%04X, %08lX);\n", wDevID
, dwOffset
);
170 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
171 WARN(midi
, "can't seek at %08lX begin of 'MThd' \n", dwOffset
);
172 return MCIERR_INTERNAL
;
174 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
175 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
))
176 return MCIERR_INTERNAL
;
177 if (MIDI_ReadLong(wDevID
, &toberead
) != 0)
178 return MCIERR_INTERNAL
;
179 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].wFormat
) != 0)
180 return MCIERR_INTERNAL
;
181 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTracks
) != 0)
182 return MCIERR_INTERNAL
;
183 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTempo
) != 0)
184 return MCIERR_INTERNAL
;
185 TRACE(midi
, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
186 toberead
, MCIMidiDev
[wDevID
].wFormat
,
187 MCIMidiDev
[wDevID
].nTracks
,
188 MCIMidiDev
[wDevID
].nTempo
);
189 toberead
-= 3 * sizeof(WORD
);
191 ntrks = read16bit ();
192 Mf_division = division = read16bit ();
198 static DWORD
MIDI_ReadMTrk(UINT16 wDevID
, DWORD dwOffset
)
202 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
203 WARN(midi
, "can't seek at %08lX begin of 'MThd' \n", dwOffset
);
205 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
206 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
)) {
207 return MCIERR_INTERNAL
;
209 if (MIDI_ReadLong(wDevID
, &toberead
) != 0) {
210 return MCIERR_INTERNAL
;
212 TRACE(midi
, "toberead=%08lX\n", toberead
);
213 toberead
-= 3 * sizeof(WORD
);
214 MCIMidiDev
[wDevID
].dwTotalLen
= toberead
;
219 /**************************************************************************
220 * MIDI_mciOpen [internal]
222 static DWORD
MIDI_mciOpen(UINT16 wDevID
, DWORD dwFlags
, LPMCI_OPEN_PARMS16 lpParms
)
224 MIDIOPENDESC MidiDesc
;
227 LPSTR lpstrElementName
;
230 TRACE(midi
, "(%08lX, %p)\n", dwFlags
, lpParms
);
231 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
233 if (MCIMidiDev
[wDevID
].nUseCount
> 0) {
234 /* The driver already open on this channel */
235 /* If the driver was opened shareable before and this open specifies */
236 /* shareable then increment the use count */
237 if (MCIMidiDev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
238 ++MCIMidiDev
[wDevID
].nUseCount
;
240 return MCIERR_MUST_USE_SHAREABLE
;
242 MCIMidiDev
[wDevID
].nUseCount
= 1;
243 MCIMidiDev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
244 MCIMidiDev
[wDevID
].hMidiHdr
= USER_HEAP_ALLOC(sizeof(MIDIHDR
));
247 TRACE(midi
, "wDevID=%04X\n", wDevID
);
248 /* lpParms->wDeviceID = wDevID;*/
249 TRACE(midi
, "lpParms->wDevID=%04X\n", lpParms
->wDeviceID
);
250 TRACE(midi
, "before OPEN_ELEMENT\n");
251 if (dwFlags
& MCI_OPEN_ELEMENT
) {
252 lpstrElementName
= (LPSTR
)PTR_SEG_TO_LIN(lpParms
->lpstrElementName
);
253 TRACE(midi
, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName
);
254 if (strlen(lpstrElementName
) > 0) {
255 strcpy(str
, lpstrElementName
);
257 MCIMidiDev
[wDevID
].hFile
= mmioOpen16(str
, NULL
,
258 MMIO_ALLOCBUF
| MMIO_READWRITE
| MMIO_EXCLUSIVE
);
259 if (MCIMidiDev
[wDevID
].hFile
== 0) {
260 WARN(midi
, "can't find file='%s' !\n", str
);
261 return MCIERR_FILE_NOT_FOUND
;
264 MCIMidiDev
[wDevID
].hFile
= 0;
266 TRACE(midi
, "hFile=%u\n", MCIMidiDev
[wDevID
].hFile
);
267 memcpy(&MCIMidiDev
[wDevID
].openParms
, lpParms
, sizeof(MCI_OPEN_PARMS16
));
268 MCIMidiDev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
269 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
270 MCIMidiDev
[wDevID
].dwBeginData
= 0;
271 MCIMidiDev
[wDevID
].dwTotalLen
= 0;
273 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
275 if (mmioDescend(MCIMidiDev
[wDevID
].hFile
, &ckMainRIFF
, NULL
, 0) != 0) {
276 return MCIERR_INTERNAL
;
278 TRACE(midi
,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
279 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
282 if (ckMainRIFF
.ckid
== mmioFOURCC('R', 'M', 'I', 'D')) {
283 TRACE(midi
, "is a 'RMID' file \n");
284 dwOffset
= ckMainRIFF
.dwDataOffset
;
286 if (ckMainRIFF
.ckid
!= mmioFOURCC('M', 'T', 'h', 'd')) {
287 WARN(midi
, "unknown format !\n");
288 return MCIERR_INTERNAL
;
290 if (MIDI_ReadMThd(wDevID
, dwOffset
) != 0) {
291 WARN(midi
, "can't read 'MThd' header \n");
292 return MCIERR_INTERNAL
;
294 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
295 if (MIDI_ReadMTrk(wDevID
, dwOffset
) != 0) {
296 WARN(midi
, "can't read 'MTrk' header \n");
297 return MCIERR_INTERNAL
;
299 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
300 MCIMidiDev
[wDevID
].dwBeginData
= dwOffset
;
301 TRACE(midi
, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
302 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
306 dwRet
= modMessage(wDevID
, MODM_OPEN
, 0, (DWORD
)&MidiDesc
, CALLBACK_NULL
);
307 /* dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
312 /**************************************************************************
313 * MIDI_mciStop [internal]
315 static DWORD
MIDI_mciStop(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
317 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
318 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
319 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
320 TRACE(midi
, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
321 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
326 /**************************************************************************
327 * MIDI_mciClose [internal]
329 static DWORD
MIDI_mciClose(UINT16 wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
333 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwParam
, lpParms
);
334 if (MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
335 MIDI_mciStop(wDevID
, MCI_WAIT
, lpParms
);
337 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
338 MCIMidiDev
[wDevID
].nUseCount
--;
339 if (MCIMidiDev
[wDevID
].nUseCount
== 0) {
340 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
341 mmioClose(MCIMidiDev
[wDevID
].hFile
, 0);
342 MCIMidiDev
[wDevID
].hFile
= 0;
343 TRACE(midi
, "hFile closed !\n");
345 USER_HEAP_FREE(MCIMidiDev
[wDevID
].hMidiHdr
);
346 dwRet
= modMessage(wDevID
, MODM_CLOSE
, 0, 0L, 0L);
347 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
349 dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
350 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
357 /**************************************************************************
358 * MIDI_mciPlay [internal]
360 static DWORD
MIDI_mciPlay(UINT16 wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
367 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
368 if (MCIMidiDev
[wDevID
].hFile
== 0) {
369 WARN(midi
, "can't find file='%08lx' !\n",
370 (DWORD
)MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
371 return MCIERR_FILE_NOT_FOUND
;
373 start
= 1; end
= 99999;
374 if (dwFlags
& MCI_FROM
) {
375 start
= lpParms
->dwFrom
;
376 TRACE(midi
, "MCI_FROM=%d \n", start
);
378 if (dwFlags
& MCI_TO
) {
380 TRACE(midi
, "MCI_TO=%d \n", end
);
383 if (dwFlags
& MCI_NOTIFY
) {
384 TRACE(midi
, "MCI_NOTIFY %08lX !\n", lpParms
->dwCallback
);
387 WARN(midi
, "Can't 'fork' process !\n");
390 TRACE(midi
, "process started ! play in background ...\n");
393 TRACE(midi
, "process started ! return to caller...\n");
399 lpMidiHdr
= USER_HEAP_LIN_ADDR(MCIMidiDev
[wDevID
].hMidiHdr
);
401 lpMidiHdr
->lpData
= (LPSTR
)xmalloc(1200);
402 if (lpMidiHdr
->lpData
== NULL
) return MCIERR_INTERNAL
;
403 lpMidiHdr
->dwBufferLength
= 1024;
404 lpMidiHdr
->dwUser
= 0L;
405 lpMidiHdr
->dwFlags
= 0L;
406 dwRet
= modMessage(wDevID
, MODM_PREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
408 /* TRACE(midi, "after MODM_PREPARE \n"); */
410 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_PLAY
;
411 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
412 TRACE(midi
, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
413 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
415 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
416 for (count
= 0; count
< lpMidiHdr
->dwBufferLength
; count
++) {
417 if (MIDI_ReadVaryLen(wDevID
, &dwData
) != 0) break;
418 *ptr
= LOWORD(dwData
);
421 count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
423 TRACE(midi
, "after read count = %d\n",count
);
425 if (count
< 1) break;
426 lpMidiHdr
->dwBytesRecorded
= count
;
427 TRACE(midi
, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
428 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
429 dwRet
= modMessage(wDevID
, MODM_LONGDATA
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
430 if (dwRet
!= MMSYSERR_NOERROR
) {
432 case MMSYSERR_NOTENABLED
:
433 return MCIERR_DEVICE_NOT_READY
;
435 case MIDIERR_NODEVICE
:
436 return MCIERR_INVALID_DEVICE_ID
;
438 case MIDIERR_UNPREPARED
:
439 return MCIERR_DRIVER_INTERNAL
;
441 case MIDIERR_STILLPLAYING
:
442 return MCIERR_SEQ_PORT_INUSE
;
444 case MMSYSERR_INVALPARAM
:
445 return MCIERR_CANNOT_LOAD_DRIVER
;
448 return MCIERR_DRIVER
;
452 dwRet
= modMessage(wDevID
, MODM_UNPREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
453 if (lpMidiHdr
->lpData
!= NULL
) {
454 free(lpMidiHdr
->lpData
);
455 lpMidiHdr
->lpData
= NULL
;
457 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
458 if (dwFlags
& MCI_NOTIFY
) {
459 TRACE(midi
, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
460 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
461 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
467 /**************************************************************************
468 * MIDI_mciRecord [internal]
470 static DWORD
MIDI_mciRecord(UINT16 wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
)
476 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
477 if (MCIMidiDev
[wDevID
].hFile
== 0) {
478 WARN(midi
, "can't find file='%08lx' !\n",
479 (DWORD
)MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
480 return MCIERR_FILE_NOT_FOUND
;
482 start
= 1; end
= 99999;
483 if (dwFlags
& MCI_FROM
) {
484 start
= lpParms
->dwFrom
;
485 TRACE(midi
, "MCI_FROM=%d \n", start
);
487 if (dwFlags
& MCI_TO
) {
489 TRACE(midi
, "MCI_TO=%d \n", end
);
491 lpMidiHdr
= USER_HEAP_LIN_ADDR(MCIMidiDev
[wDevID
].hMidiHdr
);
492 lpMidiHdr
->lpData
= (LPSTR
) xmalloc(1200);
493 lpMidiHdr
->dwBufferLength
= 1024;
494 lpMidiHdr
->dwUser
= 0L;
495 lpMidiHdr
->dwFlags
= 0L;
496 dwRet
= midMessage(wDevID
, MIDM_PREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
497 TRACE(midi
, "after MIDM_PREPARE \n");
498 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_RECORD
;
499 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
500 TRACE(midi
, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
501 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
502 lpMidiHdr
->dwBytesRecorded
= 0;
503 dwRet
= midMessage(wDevID
, MIDM_START
, 0, 0L, 0L);
504 TRACE(midi
, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
505 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
506 if (lpMidiHdr
->dwBytesRecorded
== 0) break;
508 TRACE(midi
, "before MIDM_UNPREPARE \n");
509 dwRet
= midMessage(wDevID
, MIDM_UNPREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
510 TRACE(midi
, "after MIDM_UNPREPARE \n");
511 if (lpMidiHdr
->lpData
!= NULL
) {
512 free(lpMidiHdr
->lpData
);
513 lpMidiHdr
->lpData
= NULL
;
515 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
516 if (dwFlags
& MCI_NOTIFY
) {
517 TRACE(midi
, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
518 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
519 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
525 /**************************************************************************
526 * MIDI_mciPause [internal]
528 static DWORD
MIDI_mciPause(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
530 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
531 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
536 /**************************************************************************
537 * MIDI_mciResume [internal]
539 static DWORD
MIDI_mciResume(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
541 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
542 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
547 /**************************************************************************
548 * MIDI_mciSet [internal]
550 static DWORD
MIDI_mciSet(UINT16 wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
552 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
553 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
554 TRACE(midi
, "dwTimeFormat=%08lX\n", lpParms
->dwTimeFormat
);
555 TRACE(midi
, "dwAudio=%08lX\n", lpParms
->dwAudio
);
556 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
557 switch (lpParms
->dwTimeFormat
) {
558 case MCI_FORMAT_MILLISECONDS
:
559 TRACE(midi
, "MCI_FORMAT_MILLISECONDS !\n");
561 case MCI_FORMAT_BYTES
:
562 TRACE(midi
, "MCI_FORMAT_BYTES !\n");
564 case MCI_FORMAT_SAMPLES
:
565 TRACE(midi
, "MCI_FORMAT_SAMPLES !\n");
568 WARN(midi
, "bad time format !\n");
569 return MCIERR_BAD_TIME_FORMAT
;
572 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
573 if (dwFlags
& MCI_SET_DOOR_OPEN
) return MCIERR_UNSUPPORTED_FUNCTION
;
574 if (dwFlags
& MCI_SET_DOOR_CLOSED
) return MCIERR_UNSUPPORTED_FUNCTION
;
575 if (dwFlags
& MCI_SET_AUDIO
)
576 TRACE(midi
, "MCI_SET_AUDIO !\n");
577 if (dwFlags
&& MCI_SET_ON
) {
578 TRACE(midi
, "MCI_SET_ON !\n");
579 if (dwFlags
&& MCI_SET_AUDIO_LEFT
)
580 TRACE(midi
, "MCI_SET_AUDIO_LEFT !\n");
581 if (dwFlags
&& MCI_SET_AUDIO_RIGHT
)
582 TRACE(midi
, "MCI_SET_AUDIO_RIGHT !\n");
584 if (dwFlags
& MCI_SET_OFF
)
585 TRACE(midi
, "MCI_SET_OFF !\n");
586 if (dwFlags
& MCI_SEQ_SET_MASTER
)
587 TRACE(midi
, "MCI_SEQ_SET_MASTER !\n");
588 if (dwFlags
& MCI_SEQ_SET_SLAVE
)
589 TRACE(midi
, "MCI_SEQ_SET_SLAVE !\n");
590 if (dwFlags
& MCI_SEQ_SET_OFFSET
)
591 TRACE(midi
, "MCI_SEQ_SET_OFFSET !\n");
592 if (dwFlags
& MCI_SEQ_SET_PORT
)
593 TRACE(midi
, "MCI_SEQ_SET_PORT !\n");
594 if (dwFlags
& MCI_SEQ_SET_TEMPO
)
595 TRACE(midi
, "MCI_SEQ_SET_TEMPO !\n");
600 /**************************************************************************
601 * MIDI_mciStatus [internal]
603 static DWORD
MIDI_mciStatus(UINT16 wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
605 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
606 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
607 if (dwFlags
& MCI_STATUS_ITEM
) {
608 switch(lpParms
->dwItem
) {
609 case MCI_STATUS_CURRENT_TRACK
:
610 lpParms
->dwReturn
= 1;
612 case MCI_STATUS_LENGTH
:
613 lpParms
->dwReturn
= 5555;
614 if (dwFlags
& MCI_TRACK
) {
615 lpParms
->dwTrack
= 1;
616 lpParms
->dwReturn
= 2222;
619 case MCI_STATUS_MODE
:
620 lpParms
->dwReturn
= MCI_MODE_STOP
;
622 case MCI_STATUS_MEDIA_PRESENT
:
623 TRACE(midi
, "MCI_STATUS_MEDIA_PRESENT !\n");
624 lpParms
->dwReturn
= TRUE
;
626 case MCI_STATUS_NUMBER_OF_TRACKS
:
627 lpParms
->dwReturn
= 1;
629 case MCI_STATUS_POSITION
:
630 lpParms
->dwReturn
= 3333;
631 if (dwFlags
& MCI_STATUS_START
)
633 if (dwFlags
& MCI_TRACK
) {
634 lpParms
->dwTrack
= 1;
635 lpParms
->dwReturn
= 777;
638 case MCI_STATUS_READY
:
639 TRACE(midi
, "MCI_STATUS_READY !\n");
640 lpParms
->dwReturn
= TRUE
;
642 case MCI_STATUS_TIME_FORMAT
:
643 TRACE(midi
, "MCI_STATUS_TIME_FORMAT !\n");
644 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
646 case MCI_SEQ_STATUS_DIVTYPE
:
647 TRACE(midi
, "MCI_SEQ_STATUS_DIVTYPE !\n");
648 lpParms
->dwReturn
= 0;
650 case MCI_SEQ_STATUS_MASTER
:
651 TRACE(midi
, "MCI_SEQ_STATUS_MASTER !\n");
652 lpParms
->dwReturn
= 0;
654 case MCI_SEQ_STATUS_SLAVE
:
655 TRACE(midi
, "MCI_SEQ_STATUS_SLAVE !\n");
656 lpParms
->dwReturn
= 0;
658 case MCI_SEQ_STATUS_OFFSET
:
659 TRACE(midi
, "MCI_SEQ_STATUS_OFFSET !\n");
660 lpParms
->dwReturn
= 0;
662 case MCI_SEQ_STATUS_PORT
:
663 TRACE(midi
, "MCI_SEQ_STATUS_PORT !\n");
664 lpParms
->dwReturn
= 0;
666 case MCI_SEQ_STATUS_TEMPO
:
667 TRACE(midi
, "MCI_SEQ_STATUS_TEMPO !\n");
668 lpParms
->dwReturn
= 0;
671 WARN(midi
, "unknowm command %08lX !\n", lpParms
->dwItem
);
672 return MCIERR_UNRECOGNIZED_COMMAND
;
675 if (dwFlags
& MCI_NOTIFY
) {
676 TRACE(midi
, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
677 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
678 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
683 /**************************************************************************
684 * MIDI_mciGetDevCaps [internal]
686 static DWORD
MIDI_mciGetDevCaps(UINT16 wDevID
, DWORD dwFlags
,
687 LPMCI_GETDEVCAPS_PARMS lpParms
)
689 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
690 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
691 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
692 switch(lpParms
->dwItem
) {
693 case MCI_GETDEVCAPS_CAN_RECORD
:
694 lpParms
->dwReturn
= TRUE
;
696 case MCI_GETDEVCAPS_HAS_AUDIO
:
697 lpParms
->dwReturn
= TRUE
;
699 case MCI_GETDEVCAPS_HAS_VIDEO
:
700 lpParms
->dwReturn
= FALSE
;
702 case MCI_GETDEVCAPS_DEVICE_TYPE
:
703 lpParms
->dwReturn
= MCI_DEVTYPE_SEQUENCER
;
705 case MCI_GETDEVCAPS_USES_FILES
:
706 lpParms
->dwReturn
= TRUE
;
708 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
709 lpParms
->dwReturn
= TRUE
;
711 case MCI_GETDEVCAPS_CAN_EJECT
:
712 lpParms
->dwReturn
= FALSE
;
714 case MCI_GETDEVCAPS_CAN_PLAY
:
715 lpParms
->dwReturn
= TRUE
;
717 case MCI_GETDEVCAPS_CAN_SAVE
:
718 lpParms
->dwReturn
= FALSE
;
721 return MCIERR_UNRECOGNIZED_COMMAND
;
728 /**************************************************************************
729 * MIDI_mciInfo [internal]
731 static DWORD
MIDI_mciInfo(UINT16 wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS16 lpParms
)
733 TRACE(midi
, "(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
734 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
735 lpParms
->lpstrReturn
= NULL
;
737 case MCI_INFO_PRODUCT
:
738 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
741 lpParms
->lpstrReturn
= "FileName";
744 return MCIERR_UNRECOGNIZED_COMMAND
;
746 if (lpParms
->lpstrReturn
!= NULL
)
747 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
749 lpParms
->dwRetSize
= 0;
754 /*-----------------------------------------------------------------------*/
757 /**************************************************************************
758 * midGetDevCaps [internal]
760 static DWORD
midGetDevCaps(WORD wDevID
, LPMIDIINCAPS16 lpCaps
, DWORD dwSize
)
762 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
763 lpCaps
->wMid
= 0x00FF; /* Manufac ID */
764 lpCaps
->wPid
= 0x0001; /* Product ID */
765 lpCaps
->vDriverVersion
= 0x001; /* Product Version */
766 strcpy(lpCaps
->szPname
, "Linux MIDIIN Driver");
768 return MMSYSERR_NOERROR
;
771 /**************************************************************************
774 static DWORD
midOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
777 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
778 if (lpDesc
== NULL
) {
779 WARN(midi
, "Invalid Parameter !\n");
780 return MMSYSERR_INVALPARAM
;
782 if (wDevID
>= MAX_MIDIINDRV
) {
783 TRACE(midi
,"MAX_MIDIINDRV reached !\n");
784 return MMSYSERR_ALLOCATED
;
786 MidiInDev
[wDevID
].unixdev
= 0;
787 midi
= open (MIDI_DEV
, O_RDONLY
, 0);
789 WARN(midi
,"can't open !\n");
790 return MMSYSERR_NOTENABLED
;
792 MidiInDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
793 switch(MidiInDev
[wDevID
].wFlags
) {
795 TRACE(midi
,"CALLBACK_NULL !\n");
798 TRACE(midi
, "CALLBACK_WINDOW !\n");
801 TRACE(midi
, "CALLBACK_TASK !\n");
804 TRACE(midi
, "CALLBACK_FUNCTION !\n");
807 MidiInDev
[wDevID
].lpQueueHdr
= NULL
;
808 MidiInDev
[wDevID
].unixdev
= midi
;
809 MidiInDev
[wDevID
].dwTotalPlayed
= 0;
810 MidiInDev
[wDevID
].bufsize
= 0x3FFF;
811 if (MIDI_NotifyClient(wDevID
, MIM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
812 WARN(midi
,"can't notify client !\n");
813 return MMSYSERR_INVALPARAM
;
815 return MMSYSERR_NOERROR
;
818 /**************************************************************************
819 * midClose [internal]
821 static DWORD
midClose(WORD wDevID
)
823 TRACE(midi
, "(%04X);\n", wDevID
);
824 if (MidiInDev
[wDevID
].unixdev
== 0) {
825 WARN(midi
,"can't close !\n");
826 return MMSYSERR_NOTENABLED
;
828 close(MidiInDev
[wDevID
].unixdev
);
829 MidiInDev
[wDevID
].unixdev
= 0;
830 MidiInDev
[wDevID
].bufsize
= 0;
831 if (MIDI_NotifyClient(wDevID
, MIM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
832 WARN(midi
,"can't notify client !\n");
833 return MMSYSERR_INVALPARAM
;
835 return MMSYSERR_NOERROR
;
838 /**************************************************************************
839 * midAddBuffer [internal]
841 static DWORD
midAddBuffer(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
843 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
844 return MMSYSERR_NOTENABLED
;
847 /**************************************************************************
848 * midPrepare [internal]
850 static DWORD
midPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
852 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
853 return MMSYSERR_NOTENABLED
;
856 /**************************************************************************
857 * midUnprepare [internal]
859 static DWORD
midUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
861 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
862 return MMSYSERR_NOTENABLED
;
865 /**************************************************************************
866 * midReset [internal]
868 static DWORD
midReset(WORD wDevID
)
870 TRACE(midi
, "(%04X);\n", wDevID
);
871 return MMSYSERR_NOTENABLED
;
875 /**************************************************************************
876 * midStart [internal]
878 static DWORD
midStart(WORD wDevID
)
880 TRACE(midi
, "(%04X);\n", wDevID
);
881 return MMSYSERR_NOTENABLED
;
885 /**************************************************************************
888 static DWORD
midStop(WORD wDevID
)
890 TRACE(midi
, "(%04X);\n", wDevID
);
891 return MMSYSERR_NOTENABLED
;
895 /**************************************************************************
896 * midMessage [sample driver]
898 DWORD
midMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
899 DWORD dwParam1
, DWORD dwParam2
)
901 TRACE(midi
, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
902 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
905 return midOpen(wDevID
,(LPMIDIOPENDESC
)dwParam1
, dwParam2
);
907 return midClose(wDevID
);
909 return midAddBuffer(wDevID
,(LPMIDIHDR
)dwParam1
, dwParam2
);
911 return midPrepare(wDevID
,(LPMIDIHDR
)dwParam1
, dwParam2
);
913 return midUnprepare(wDevID
,(LPMIDIHDR
)dwParam1
, dwParam2
);
914 case MIDM_GETDEVCAPS
:
915 return midGetDevCaps(wDevID
,(LPMIDIINCAPS16
)dwParam1
,dwParam2
);
916 case MIDM_GETNUMDEVS
:
919 return midReset(wDevID
);
921 return midStart(wDevID
);
923 return midStop(wDevID
);
925 return MMSYSERR_NOTSUPPORTED
;
928 /*-----------------------------------------------------------------------*/
930 /**************************************************************************
931 * modGetDevCaps [internal]
933 static DWORD
modGetDevCaps(WORD wDevID
, LPMIDIOUTCAPS16 lpCaps
, DWORD dwSize
)
935 LPMIDIOUTCAPS16 tmplpCaps
;
937 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
938 if (wDevID
== (WORD
) MIDI_MAPPER
) {
939 lpCaps
->wMid
= 0x00FF; /* Manufac ID */
940 lpCaps
->wPid
= 0x0001; /* Product ID */
941 lpCaps
->vDriverVersion
= 0x001; /* Product Version */
942 strcpy(lpCaps
->szPname
, "MIDI Maper (not functional yet)");
943 lpCaps
->wTechnology
= MOD_FMSYNTH
; /* FIXME Does it make any difference ? */
944 lpCaps
->wVoices
= 14; /* FIXME */
945 lpCaps
->wNotes
= 14; /* FIXME */
946 lpCaps
->dwSupport
= MIDICAPS_VOLUME
|MIDICAPS_LRVOLUME
; /* FIXME Does it make any difference ? */
948 /* FIXME There is a way to do it so easily, but I'm too
949 * sleepy to think and I want to test
951 tmplpCaps
= midiDevices
[wDevID
];
952 lpCaps
->wMid
= tmplpCaps
->wMid
;
953 lpCaps
->wPid
= tmplpCaps
->wPid
;
954 lpCaps
->vDriverVersion
= tmplpCaps
->vDriverVersion
;
955 strcpy(lpCaps
->szPname
, tmplpCaps
->szPname
);
956 lpCaps
->wTechnology
= tmplpCaps
->wTechnology
;
957 lpCaps
->wVoices
= tmplpCaps
->wVoices
;
958 lpCaps
->wNotes
= tmplpCaps
->wNotes
;
959 lpCaps
->dwSupport
= tmplpCaps
->dwSupport
;
961 return MMSYSERR_NOERROR
;
964 /**************************************************************************
967 static DWORD
modOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
971 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
972 if (lpDesc
== NULL
) {
973 WARN(midi
, "Invalid Parameter !\n");
974 return MMSYSERR_INVALPARAM
;
976 if (wDevID
>= MAX_MIDIOUTDRV
) {
977 TRACE(midi
,"MAX_MIDIOUTDRV reached !\n");
978 return MMSYSERR_ALLOCATED
; /* FIXME isn't MMSYSERR_BADDEVICEID the right answer ? */
980 MidiOutDev
[wDevID
].unixdev
= 0;
981 midi
= open (MIDI_DEV
, O_WRONLY
, 0);
983 WARN(midi
, "can't open !\n");
984 return MMSYSERR_NOTENABLED
;
986 MidiOutDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
987 switch(MidiOutDev
[wDevID
].wFlags
) {
989 TRACE(midi
,"CALLBACK_NULL !\n");
992 TRACE(midi
, "CALLBACK_WINDOW !\n");
995 TRACE(midi
, "CALLBACK_TASK !\n");
998 TRACE(midi
, "CALLBACK_FUNCTION !\n");
1001 MidiOutDev
[wDevID
].lpQueueHdr
= NULL
;
1002 MidiOutDev
[wDevID
].unixdev
= midi
;
1003 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1004 MidiOutDev
[wDevID
].bufsize
= 0x3FFF;
1005 if (MIDI_NotifyClient(wDevID
, MOM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
1006 WARN(midi
,"can't notify client !\n");
1007 return MMSYSERR_INVALPARAM
;
1009 TRACE(midi
, "Succesful unixdev=%d !\n", midi
);
1010 return MMSYSERR_NOERROR
;
1014 /**************************************************************************
1015 * modClose [internal]
1017 static DWORD
modClose(WORD wDevID
)
1019 TRACE(midi
, "(%04X);\n", wDevID
);
1020 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1021 WARN(midi
,"can't close !\n");
1022 return MMSYSERR_NOTENABLED
;
1024 close(MidiOutDev
[wDevID
].unixdev
);
1025 MidiOutDev
[wDevID
].unixdev
= 0;
1026 MidiOutDev
[wDevID
].bufsize
= 0;
1027 if (MIDI_NotifyClient(wDevID
, MOM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1028 WARN(midi
,"can't notify client !\n");
1029 return MMSYSERR_INVALPARAM
;
1031 return MMSYSERR_NOERROR
;
1034 /**************************************************************************
1035 * modData [internal]
1037 static DWORD
modData(WORD wDevID
, DWORD dwParam
)
1041 TRACE(midi
, "(%04X, %08lX);\n", wDevID
, dwParam
);
1042 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1043 WARN(midi
,"can't play !\n");
1044 return MIDIERR_NODEVICE
;
1046 event
= LOWORD(dwParam
);
1047 if (write (MidiOutDev
[wDevID
].unixdev
,
1048 &event
, sizeof(WORD
)) != sizeof(WORD
)) {
1049 WARN(midi
, "error writting unixdev !\n");
1051 return MMSYSERR_NOTENABLED
;
1054 /**************************************************************************
1055 * modLongData [internal]
1057 static DWORD
modLongData(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1063 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1064 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1065 WARN(midi
,"can't play !\n");
1066 return MIDIERR_NODEVICE
;
1068 if (lpMidiHdr
->lpData
== NULL
) return MIDIERR_UNPREPARED
;
1069 if (!(lpMidiHdr
->dwFlags
& MHDR_PREPARED
)) return MIDIERR_UNPREPARED
;
1070 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1071 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1072 lpMidiHdr
->dwFlags
|= MHDR_INQUEUE
;
1073 TRACE(midi
, "dwBytesRecorded %lu !\n", lpMidiHdr
->dwBytesRecorded
);
1074 TRACE(midi
, " %02X %02X %02X %02X\n",
1075 lpMidiHdr
->lpData
[0], lpMidiHdr
->lpData
[1],
1076 lpMidiHdr
->lpData
[2], lpMidiHdr
->lpData
[3]);
1078 count = write (MidiOutDev[wDevID].unixdev,
1079 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1081 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
1082 for (count
= 0; count
< lpMidiHdr
->dwBytesRecorded
; count
++) {
1083 if (write (MidiOutDev
[wDevID
].unixdev
, ptr
,
1084 sizeof(WORD
)) != sizeof(WORD
)) break;
1089 TRACE(midi
, "after write count = %d\n",count
);
1090 if (count
!= lpMidiHdr
->dwBytesRecorded
) {
1091 WARN(midi
, "error writting unixdev #%d ! (%d != %ld)\n",
1092 MidiOutDev
[wDevID
].unixdev
, count
,
1093 lpMidiHdr
->dwBytesRecorded
);
1094 TRACE(midi
, "\terrno = %d error = %s\n",en
,strerror(en
));
1095 return MMSYSERR_NOTENABLED
;
1097 lpMidiHdr
->dwFlags
&= ~MHDR_INQUEUE
;
1098 lpMidiHdr
->dwFlags
|= MHDR_DONE
;
1099 if (MIDI_NotifyClient(wDevID
, MOM_DONE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1100 WARN(midi
,"can't notify client !\n");
1101 return MMSYSERR_INVALPARAM
;
1103 return MMSYSERR_NOERROR
;
1106 /**************************************************************************
1107 * modPrepare [internal]
1109 static DWORD
modPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1111 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1112 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1113 WARN(midi
,"can't prepare !\n");
1114 return MMSYSERR_NOTENABLED
;
1116 if (MidiOutDev
[wDevID
].lpQueueHdr
!= NULL
) {
1117 TRACE(midi
,"already prepare !\n");
1118 return MMSYSERR_NOTENABLED
;
1120 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1121 MidiOutDev
[wDevID
].lpQueueHdr
= PTR_SEG_TO_LIN(lpMidiHdr
);
1122 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1123 lpMidiHdr
->dwFlags
|= MHDR_PREPARED
;
1124 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1125 return MMSYSERR_NOERROR
;
1128 /**************************************************************************
1129 * modUnprepare [internal]
1131 static DWORD
modUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1133 TRACE(midi
, "(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1134 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1135 WARN(midi
,"can't unprepare !\n");
1136 return MMSYSERR_NOTENABLED
;
1138 return MMSYSERR_NOERROR
;
1141 /**************************************************************************
1142 * modReset [internal]
1144 static DWORD
modReset(WORD wDevID
)
1146 TRACE(midi
, "(%04X);\n", wDevID
);
1147 return MMSYSERR_NOTENABLED
;
1151 /**************************************************************************
1152 * modMessage [sample driver]
1154 DWORD
modMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1155 DWORD dwParam1
, DWORD dwParam2
)
1157 TRACE(midi
, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
1158 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1161 return modOpen(wDevID
, (LPMIDIOPENDESC
)dwParam1
, dwParam2
);
1163 return modClose(wDevID
);
1165 return modData(wDevID
, dwParam1
);
1167 return modLongData(wDevID
, (LPMIDIHDR
)dwParam1
, dwParam2
);
1169 return modPrepare(wDevID
, (LPMIDIHDR
)dwParam1
, dwParam2
);
1170 case MODM_UNPREPARE
:
1171 return modUnprepare(wDevID
, (LPMIDIHDR
)dwParam1
, dwParam2
);
1172 case MODM_GETDEVCAPS
:
1173 return modGetDevCaps(wDevID
,(LPMIDIOUTCAPS16
)dwParam1
,dwParam2
);
1174 case MODM_GETNUMDEVS
:
1175 return MODM_NUMDEVS
;
1176 case MODM_GETVOLUME
:
1178 case MODM_SETVOLUME
:
1181 return modReset(wDevID
);
1183 return MMSYSERR_NOTSUPPORTED
;
1187 /**************************************************************************
1188 * MIDI_DriverProc [sample driver]
1190 LONG
MIDI_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
1191 DWORD dwParam1
, DWORD dwParam2
)
1206 case DRV_QUERYCONFIGURE
:
1209 MessageBox16(0, "Sample Midi Linux Driver !",
1210 "MMLinux Driver", MB_OK
);
1213 return DRVCNF_RESTART
;
1215 return DRVCNF_RESTART
;
1216 case MCI_OPEN_DRIVER
:
1218 return MIDI_mciOpen(dwDevID
, dwParam1
, (LPMCI_OPEN_PARMS16
)PTR_SEG_TO_LIN(dwParam2
));
1219 case MCI_CLOSE_DRIVER
:
1221 return MIDI_mciClose(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1223 return MIDI_mciPlay(dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1225 return MIDI_mciRecord(dwDevID
, dwParam1
, (LPMCI_RECORD_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1227 return MIDI_mciStop(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1229 return MIDI_mciSet(dwDevID
, dwParam1
, (LPMCI_SET_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1231 return MIDI_mciPause(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1233 return MIDI_mciResume(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1235 return MIDI_mciStatus(dwDevID
, dwParam1
, (LPMCI_STATUS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1236 case MCI_GETDEVCAPS
:
1237 return MIDI_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1239 return MIDI_mciInfo(dwDevID
, dwParam1
, (LPMCI_INFO_PARMS16
)PTR_SEG_TO_LIN(dwParam2
));
1241 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
1244 /*-----------------------------------------------------------------------*/