2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
14 #include <sys/ioctl.h>
26 #include <linux/soundcard.h>
28 #include <machine/soundcard.h>
29 #include <sys/errno.h>
32 #if defined(linux) || defined(__FreeBSD__)
33 #define MIDI_DEV "/dev/sequencer"
36 #define IOCTL(a,b,c) ioctl(a,b,&c)
38 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
41 #define MAX_MIDIINDRV (1)
42 #define MAX_MIDIOUTDRV (1)
43 #define MAX_MCIMIDIDRV (1)
49 MIDIOPENDESC midiDesc
;
59 MIDIOPENDESC midiDesc
;
66 int nUseCount
; /* Incremented for each shared open */
67 BOOL16 fShareable
; /* TRUE if first open was shareable */
68 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
69 HANDLE16 hCallback
; /* Callback handle for pending notification */
70 HMMIO16 hFile
; /* mmio file handle open as Element */
76 MCI_OPEN_PARMS openParms
;
77 /* MIDIHDR MidiHdr; */
82 static LINUX_MIDIIN MidiInDev
[MAX_MIDIINDRV
];
83 static LINUX_MIDIOUT MidiOutDev
[MAX_MIDIOUTDRV
];
84 static LINUX_MCIMIDI MCIMidiDev
[MAX_MCIMIDIDRV
];
88 /**************************************************************************
89 * MIDI_NotifyClient [internal]
91 static DWORD
MIDI_NotifyClient(UINT16 wDevID
, WORD wMsg
,
92 DWORD dwParam1
, DWORD dwParam2
)
94 dprintf_midi(stddeb
,"MIDI_NotifyClient // wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID
, wMsg
, dwParam1
, dwParam2
);
96 #if defined(linux) || defined(__FreeBSD__)
102 if (wDevID
> MAX_MIDIOUTDRV
) return MCIERR_INTERNAL
;
104 if (MidiOutDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
105 MidiOutDev
[wDevID
].midiDesc
.dwCallback
,
106 MidiOutDev
[wDevID
].wFlags
,
107 MidiOutDev
[wDevID
].midiDesc
.hMidi
,
109 MidiOutDev
[wDevID
].midiDesc
.dwInstance
,
112 dprintf_midi(stddeb
,"MIDI_NotifyClient // can't notify client !\n");
113 return MMSYSERR_NOERROR
;
119 if (wDevID
> MAX_MIDIINDRV
) return MCIERR_INTERNAL
;
121 if (MidiInDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
122 MidiInDev
[wDevID
].midiDesc
.dwCallback
, MidiInDev
[wDevID
].wFlags
,
123 MidiInDev
[wDevID
].midiDesc
.hMidi
, wMsg
,
124 MidiInDev
[wDevID
].midiDesc
.dwInstance
, dwParam1
, dwParam2
)) {
125 dprintf_mciwave(stddeb
,"MIDI_NotifyClient // can't notify client !\n");
126 return MMSYSERR_NOERROR
;
132 return MMSYSERR_NOTENABLED
;
137 /**************************************************************************
138 * MIDI_ReadByte [internal]
140 static DWORD
MIDI_ReadByte(UINT16 wDevID
, BYTE
*lpbyt
)
142 #if defined(linux) || defined(__FreeBSD__)
144 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)lpbyt
,
145 (long) sizeof(BYTE
)) == (long) sizeof(BYTE
)) {
149 dprintf_midi(stddeb
, "MIDI_ReadByte // error reading wDevID=%04X\n", wDevID
);
150 return MCIERR_INTERNAL
;
153 return MMSYSERR_NOTENABLED
;
158 /**************************************************************************
159 * MIDI_ReadWord [internal]
161 static DWORD
MIDI_ReadWord(UINT16 wDevID
, LPWORD lpw
)
165 if (MIDI_ReadByte(wDevID
, &hibyte
) == 0) {
166 if (MIDI_ReadByte(wDevID
, &lobyte
) == 0) {
167 *lpw
= ((WORD
)hibyte
<< 8) + lobyte
;
172 dprintf_midi(stddeb
, "MIDI_ReadWord // error reading wDevID=%04X\n", wDevID
);
173 return MCIERR_INTERNAL
;
177 /**************************************************************************
178 * MIDI_ReadLong [internal]
180 static DWORD
MIDI_ReadLong(UINT16 wDevID
, LPDWORD lpdw
)
184 if (MIDI_ReadWord(wDevID
, &hiword
) == 0) {
185 if (MIDI_ReadWord(wDevID
, &loword
) == 0) {
186 *lpdw
= MAKELONG(loword
, hiword
);
191 dprintf_midi(stddeb
, "MIDI_ReadLong // error reading wDevID=%04X\n", wDevID
);
192 return MCIERR_INTERNAL
;
196 /**************************************************************************
197 * MIDI_ReadVaryLen [internal]
199 static DWORD
MIDI_ReadVaryLen(UINT16 wDevID
, LPDWORD lpdw
)
203 if (lpdw
== NULL
) return MCIERR_INTERNAL
;
204 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
205 dprintf_midi(stddeb
, "MIDI_ReadVaryLen // error reading wDevID=%04X\n", wDevID
);
206 return MCIERR_INTERNAL
;
208 value
= (DWORD
)(byte
& 0x7F);
209 while (byte
& 0x80) {
210 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
211 dprintf_midi(stddeb
, "MIDI_ReadVaryLen // error reading wDevID=%04X\n", wDevID
);
212 return MCIERR_INTERNAL
;
214 value
= (value
<< 7) + (byte
& 0x7F);
218 dprintf_midi(stddeb, "MIDI_ReadVaryLen // val=%08lX \n", value);
224 /**************************************************************************
225 * MIDI_ReadMThd [internal]
227 static DWORD
MIDI_ReadMThd(UINT16 wDevID
, DWORD dwOffset
)
229 #if defined(linux) || defined(__FreeBSD__)
232 dprintf_midi(stddeb
, "MIDI_ReadMThd(%04X, %08lX);\n", wDevID
, dwOffset
);
233 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
234 dprintf_midi(stddeb
, "MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset
);
235 return MCIERR_INTERNAL
;
237 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
238 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
)) {
239 return MCIERR_INTERNAL
;
241 if (MIDI_ReadLong(wDevID
, &toberead
) != 0) {
242 return MCIERR_INTERNAL
;
244 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].wFormat
) != 0) {
245 return MCIERR_INTERNAL
;
247 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTracks
) != 0) {
248 return MCIERR_INTERNAL
;
250 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTempo
) != 0) {
251 return MCIERR_INTERNAL
;
253 dprintf_midi(stddeb
, "MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
254 toberead
, MCIMidiDev
[wDevID
].wFormat
,
255 MCIMidiDev
[wDevID
].nTracks
,
256 MCIMidiDev
[wDevID
].nTempo
);
257 toberead
-= 3 * sizeof(WORD
);
259 ntrks = read16bit ();
260 Mf_division = division = read16bit ();
265 return MMSYSERR_NOTENABLED
;
270 static DWORD
MIDI_ReadMTrk(UINT16 wDevID
, DWORD dwOffset
)
272 #if defined(linux) || defined(__FreeBSD__)
275 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
276 dprintf_midi(stddeb
, "MIDI_ReadMTrk // can't seek at %08lX begin of 'MThd' \n", dwOffset
);
278 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
279 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
)) {
280 return MCIERR_INTERNAL
;
282 if (MIDI_ReadLong(wDevID
, &toberead
) != 0) {
283 return MCIERR_INTERNAL
;
285 dprintf_midi(stddeb
, "MIDI_ReadMTrk // toberead=%08lX\n", toberead
);
286 toberead
-= 3 * sizeof(WORD
);
287 MCIMidiDev
[wDevID
].dwTotalLen
= toberead
;
290 return MMSYSERR_NOTENABLED
;
295 /**************************************************************************
296 * MIDI_mciOpen [internal]
298 static DWORD
MIDI_mciOpen(UINT16 wDevID
, DWORD dwFlags
, LPMCI_OPEN_PARMS lpParms
)
300 #if defined(linux) || defined(__FreeBSD__)
301 MIDIOPENDESC MidiDesc
;
304 LPSTR lpstrElementName
;
307 dprintf_midi(stddeb
, "MIDI_mciOpen(%08lX, %p)\n", dwFlags
, lpParms
);
308 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
310 if (MCIMidiDev
[wDevID
].nUseCount
> 0) {
311 /* The driver already open on this channel */
312 /* If the driver was opened shareable before and this open specifies */
313 /* shareable then increment the use count */
314 if (MCIMidiDev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
315 ++MCIMidiDev
[wDevID
].nUseCount
;
317 return MCIERR_MUST_USE_SHAREABLE
;
320 MCIMidiDev
[wDevID
].nUseCount
= 1;
321 MCIMidiDev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
322 MCIMidiDev
[wDevID
].hMidiHdr
= USER_HEAP_ALLOC(sizeof(MIDIHDR
));
325 dprintf_midi(stddeb
, "MIDI_mciOpen // wDevID=%04X\n", wDevID
);
326 /* lpParms->wDeviceID = wDevID;*/
327 dprintf_midi(stddeb
, "MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms
->wDeviceID
);
328 dprintf_midi(stddeb
, "MIDI_mciOpen // before OPEN_ELEMENT\n");
329 if (dwFlags
& MCI_OPEN_ELEMENT
) {
330 lpstrElementName
= (LPSTR
)PTR_SEG_TO_LIN(lpParms
->lpstrElementName
);
331 dprintf_midi(stddeb
, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName
);
332 if (strlen(lpstrElementName
) > 0) {
333 strcpy(str
, lpstrElementName
);
335 MCIMidiDev
[wDevID
].hFile
= mmioOpen(str
, NULL
,
336 MMIO_ALLOCBUF
| MMIO_READWRITE
| MMIO_EXCLUSIVE
);
337 if (MCIMidiDev
[wDevID
].hFile
== 0) {
338 dprintf_midi(stddeb
, "MIDI_mciOpen // can't find file='%s' !\n", str
);
339 return MCIERR_FILE_NOT_FOUND
;
343 MCIMidiDev
[wDevID
].hFile
= 0;
345 dprintf_midi(stddeb
, "MIDI_mciOpen // hFile=%u\n", MCIMidiDev
[wDevID
].hFile
);
346 memcpy(&MCIMidiDev
[wDevID
].openParms
, lpParms
, sizeof(MCI_OPEN_PARMS
));
347 MCIMidiDev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
348 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
349 MCIMidiDev
[wDevID
].dwBeginData
= 0;
350 MCIMidiDev
[wDevID
].dwTotalLen
= 0;
352 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
354 if (mmioDescend(MCIMidiDev
[wDevID
].hFile
, &ckMainRIFF
, NULL
, 0) != 0) {
355 return MCIERR_INTERNAL
;
357 dprintf_midi(stddeb
,"MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
358 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
361 if (ckMainRIFF
.ckid
== mmioFOURCC('R', 'M', 'I', 'D')) {
362 dprintf_midi(stddeb
, "MIDI_mciOpen // is a 'RMID' file \n");
363 dwOffset
= ckMainRIFF
.dwDataOffset
;
365 if (ckMainRIFF
.ckid
!= mmioFOURCC('M', 'T', 'h', 'd')) {
366 dprintf_midi(stddeb
, "MIDI_mciOpen // unknown format !\n");
367 return MCIERR_INTERNAL
;
369 if (MIDI_ReadMThd(wDevID
, dwOffset
) != 0) {
370 dprintf_midi(stddeb
, "MIDI_mciOpen // can't read 'MThd' header \n");
371 return MCIERR_INTERNAL
;
373 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
374 if (MIDI_ReadMTrk(wDevID
, dwOffset
) != 0) {
375 dprintf_midi(stddeb
, "MIDI_mciOpen // can't read 'MTrk' header \n");
376 return MCIERR_INTERNAL
;
378 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
379 MCIMidiDev
[wDevID
].dwBeginData
= dwOffset
;
380 dprintf_midi(stddeb
, "MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
381 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
385 dwRet
= modMessage(wDevID
, MODM_OPEN
, 0, (DWORD
)&MidiDesc
, CALLBACK_NULL
);
386 /* dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/
390 return MMSYSERR_NOTENABLED
;
394 /**************************************************************************
395 * MIDI_mciStop [internal]
397 static DWORD
MIDI_mciStop(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
399 #if defined(linux) || defined(__FreeBSD__)
400 dprintf_midi(stddeb
, "MIDI_mciStop(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
401 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
402 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
403 dprintf_midi(stddeb
, "MIDI_mciStop // MCIMidiDev[wDevID].dwStatus=%p %d\n",
404 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
407 return MCIERR_INTERNAL
;
412 /**************************************************************************
413 * MIDI_mciClose [internal]
415 static DWORD
MIDI_mciClose(UINT16 wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
417 #if defined(linux) || defined(__FreeBSD__)
420 dprintf_midi(stddeb
, "MIDI_mciClose(%04X, %08lX, %p);\n", wDevID
, dwParam
, lpParms
);
421 if (MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
422 MIDI_mciStop(wDevID
, MCI_WAIT
, lpParms
);
424 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
425 MCIMidiDev
[wDevID
].nUseCount
--;
426 if (MCIMidiDev
[wDevID
].nUseCount
== 0) {
427 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
428 mmioClose(MCIMidiDev
[wDevID
].hFile
, 0);
429 MCIMidiDev
[wDevID
].hFile
= 0;
430 dprintf_midi(stddeb
, "MIDI_mciClose // hFile closed !\n");
432 USER_HEAP_FREE(MCIMidiDev
[wDevID
].hMidiHdr
);
433 dwRet
= modMessage(wDevID
, MODM_CLOSE
, 0, 0L, 0L);
434 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
436 dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
437 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
447 /**************************************************************************
448 * MIDI_mciPlay [internal]
450 static DWORD
MIDI_mciPlay(UINT16 wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
452 #if defined(linux) || defined(__FreeBSD__)
461 dprintf_midi(stddeb
, "MIDI_mciPlay(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
462 if (MCIMidiDev
[wDevID
].hFile
== 0) {
463 dprintf_midi(stddeb
, "MIDI_mciPlay // can't find file='%08lx' !\n",
464 MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
465 return MCIERR_FILE_NOT_FOUND
;
467 start
= 1; end
= 99999;
468 if (dwFlags
& MCI_FROM
) {
469 start
= lpParms
->dwFrom
;
470 dprintf_midi(stddeb
, "MIDI_mciPlay // MCI_FROM=%d \n", start
);
472 if (dwFlags
& MCI_TO
) {
474 dprintf_midi(stddeb
, "MIDI_mciPlay // MCI_TO=%d \n", end
);
477 if (dwFlags
& MCI_NOTIFY
) {
478 dprintf_midi(stddeb
, "MIDI_mciPlay // MCI_NOTIFY %08lX !\n", lpParms
->dwCallback
);
481 dprintf_midi(stddeb
, "MIDI_mciPlay // Can't 'fork' process !\n");
484 dprintf_midi(stddeb
, "MIDI_mciPlay // process started ! play in background ...\n");
487 dprintf_midi(stddeb
, "MIDI_mciPlay // process started ! return to caller...\n");
493 lpMidiHdr
= USER_HEAP_LIN_ADDR(MCIMidiDev
[wDevID
].hMidiHdr
);
494 lp16MidiHdr
= USER_HEAP_SEG_ADDR(MCIMidiDev
[wDevID
].hMidiHdr
);
496 lpMidiHdr
->lpData
= (LPSTR
) malloc(1200);
497 if (lpMidiHdr
->lpData
== NULL
) return MCIERR_INTERNAL
;
498 lpMidiHdr
->dwBufferLength
= 1024;
499 lpMidiHdr
->dwUser
= 0L;
500 lpMidiHdr
->dwFlags
= 0L;
501 dwRet
= modMessage(wDevID
, MODM_PREPARE
, 0, (DWORD
)lp16MidiHdr
, sizeof(MIDIHDR
));
503 /* dprintf_midi(stddeb, "MIDI_mciPlay // after MODM_PREPARE \n"); */
505 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_PLAY
;
506 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
507 dprintf_midi(stddeb
, "MIDI_mciPlay // MCIMidiDev[wDevID].dwStatus=%p %d\n",
508 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
510 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
511 for (count
= 0; count
< lpMidiHdr
->dwBufferLength
; count
++) {
512 if (MIDI_ReadVaryLen(wDevID
, &dwData
) != 0) break;
513 *ptr
= LOWORD(dwData
);
516 count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
518 dprintf_midi(stddeb
, "MIDI_mciPlay // after read count = %d\n",count
);
520 if (count
< 1) break;
521 lpMidiHdr
->dwBytesRecorded
= count
;
522 dprintf_midi(stddeb
, "MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
523 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
524 dwRet
= modMessage(wDevID
, MODM_LONGDATA
, 0, (DWORD
)lp16MidiHdr
, sizeof(MIDIHDR
));
525 if (dwRet
!= MMSYSERR_NOERROR
) {
527 case MMSYSERR_NOTENABLED
:
528 return MCIERR_DEVICE_NOT_READY
;
530 case MIDIERR_NODEVICE
:
531 return MCIERR_INVALID_DEVICE_ID
;
533 case MIDIERR_UNPREPARED
:
534 return MCIERR_DRIVER_INTERNAL
;
536 case MIDIERR_STILLPLAYING
:
537 return MCIERR_SEQ_PORT_INUSE
;
539 case MMSYSERR_INVALPARAM
:
540 return MCIERR_CANNOT_LOAD_DRIVER
;
543 return MCIERR_DRIVER
;
547 dwRet
= modMessage(wDevID
, MODM_UNPREPARE
, 0, (DWORD
)lp16MidiHdr
, sizeof(MIDIHDR
));
548 if (lpMidiHdr
->lpData
!= NULL
) {
549 free(lpMidiHdr
->lpData
);
550 lpMidiHdr
->lpData
= NULL
;
552 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
553 if (dwFlags
& MCI_NOTIFY
) {
554 dprintf_midi(stddeb
, "MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
555 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
556 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
563 return MMSYSERR_NOTENABLED
;
568 /**************************************************************************
569 * MIDI_mciRecord [internal]
571 static DWORD
MIDI_mciRecord(UINT16 wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
)
573 #if defined(linux) || defined(__FreeBSD__)
578 dprintf_midi(stddeb
, "MIDI_mciRecord(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
579 if (MCIMidiDev
[wDevID
].hFile
== 0) {
580 dprintf_midi(stddeb
, "MIDI_mciRecord // can't find file='%08lx' !\n",
581 MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
582 return MCIERR_FILE_NOT_FOUND
;
584 start
= 1; end
= 99999;
585 if (dwFlags
& MCI_FROM
) {
586 start
= lpParms
->dwFrom
;
587 dprintf_midi(stddeb
, "MIDI_mciRecord // MCI_FROM=%d \n", start
);
589 if (dwFlags
& MCI_TO
) {
591 dprintf_midi(stddeb
, "MIDI_mciRecord // MCI_TO=%d \n", end
);
593 lpMidiHdr
= USER_HEAP_LIN_ADDR(MCIMidiDev
[wDevID
].hMidiHdr
);
594 lpMidiHdr
->lpData
= (LPSTR
) xmalloc(1200);
595 lpMidiHdr
->dwBufferLength
= 1024;
596 lpMidiHdr
->dwUser
= 0L;
597 lpMidiHdr
->dwFlags
= 0L;
598 dwRet
= midMessage(wDevID
, MIDM_PREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
599 dprintf_midi(stddeb
, "MIDI_mciRecord // after MIDM_PREPARE \n");
600 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_RECORD
;
601 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
602 dprintf_midi(stddeb
, "MIDI_mciRecord // MCIMidiDev[wDevID].dwStatus=%p %d\n",
603 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
604 lpMidiHdr
->dwBytesRecorded
= 0;
605 dwRet
= midMessage(wDevID
, MIDM_START
, 0, 0L, 0L);
606 dprintf_midi(stddeb
, "MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
607 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
608 if (lpMidiHdr
->dwBytesRecorded
== 0) break;
610 dprintf_midi(stddeb
, "MIDI_mciRecord // before MIDM_UNPREPARE \n");
611 dwRet
= midMessage(wDevID
, MIDM_UNPREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
612 dprintf_midi(stddeb
, "MIDI_mciRecord // after MIDM_UNPREPARE \n");
613 if (lpMidiHdr
->lpData
!= NULL
) {
614 free(lpMidiHdr
->lpData
);
615 lpMidiHdr
->lpData
= NULL
;
617 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
618 if (dwFlags
& MCI_NOTIFY
) {
619 dprintf_midi(stddeb
, "MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
620 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
621 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
625 return MMSYSERR_NOTENABLED
;
630 /**************************************************************************
631 * MIDI_mciPause [internal]
633 static DWORD
MIDI_mciPause(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
635 #if defined(linux) || defined(__FreeBSD__)
636 dprintf_midi(stddeb
, "MIDI_mciPause(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
637 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
640 return MCIERR_INTERNAL
;
645 /**************************************************************************
646 * MIDI_mciResume [internal]
648 static DWORD
MIDI_mciResume(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
650 #if defined(linux) || defined(__FreeBSD__)
651 dprintf_midi(stddeb
, "MIDI_mciResume(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
652 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
655 return MCIERR_INTERNAL
;
660 /**************************************************************************
661 * MIDI_mciSet [internal]
663 static DWORD
MIDI_mciSet(UINT16 wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
665 #if defined(linux) || defined(__FreeBSD__)
666 dprintf_midi(stddeb
, "MIDI_mciSet(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
667 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
668 dprintf_midi(stddeb
, "MIDI_mciSet // dwTimeFormat=%08lX\n", lpParms
->dwTimeFormat
);
669 dprintf_midi(stddeb
, "MIDI_mciSet // dwAudio=%08lX\n", lpParms
->dwAudio
);
670 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
671 switch (lpParms
->dwTimeFormat
) {
672 case MCI_FORMAT_MILLISECONDS
:
673 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
675 case MCI_FORMAT_BYTES
:
676 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
678 case MCI_FORMAT_SAMPLES
:
679 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
682 dprintf_midi(stddeb
, "MIDI_mciSet // bad time format !\n");
683 return MCIERR_BAD_TIME_FORMAT
;
686 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
687 if (dwFlags
& MCI_SET_DOOR_OPEN
) return MCIERR_UNSUPPORTED_FUNCTION
;
688 if (dwFlags
& MCI_SET_DOOR_CLOSED
) return MCIERR_UNSUPPORTED_FUNCTION
;
689 if (dwFlags
& MCI_SET_AUDIO
) {
690 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SET_AUDIO !\n");
692 if (dwFlags
&& MCI_SET_ON
) {
693 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SET_ON !\n");
694 if (dwFlags
&& MCI_SET_AUDIO_LEFT
) {
695 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
697 if (dwFlags
&& MCI_SET_AUDIO_RIGHT
) {
698 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
701 if (dwFlags
& MCI_SET_OFF
) {
702 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SET_OFF !\n");
704 if (dwFlags
& MCI_SEQ_SET_MASTER
) {
705 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
707 if (dwFlags
& MCI_SEQ_SET_SLAVE
) {
708 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
710 if (dwFlags
& MCI_SEQ_SET_OFFSET
) {
711 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
713 if (dwFlags
& MCI_SEQ_SET_PORT
) {
714 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
716 if (dwFlags
& MCI_SEQ_SET_TEMPO
) {
717 dprintf_midi(stddeb
, "MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
721 return MCIERR_INTERNAL
;
726 /**************************************************************************
727 * MIDI_mciStatus [internal]
729 static DWORD
MIDI_mciStatus(UINT16 wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
731 #if defined(linux) || defined(__FreeBSD__)
732 dprintf_midi(stddeb
, "MIDI_mciStatus(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
733 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
734 if (dwFlags
& MCI_STATUS_ITEM
) {
735 switch(lpParms
->dwItem
) {
736 case MCI_STATUS_CURRENT_TRACK
:
737 lpParms
->dwReturn
= 1;
739 case MCI_STATUS_LENGTH
:
740 lpParms
->dwReturn
= 5555;
741 if (dwFlags
& MCI_TRACK
) {
742 lpParms
->dwTrack
= 1;
743 lpParms
->dwReturn
= 2222;
746 case MCI_STATUS_MODE
:
747 lpParms
->dwReturn
= MCI_MODE_STOP
;
749 case MCI_STATUS_MEDIA_PRESENT
:
750 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
751 lpParms
->dwReturn
= TRUE
;
753 case MCI_STATUS_NUMBER_OF_TRACKS
:
754 lpParms
->dwReturn
= 1;
756 case MCI_STATUS_POSITION
:
757 lpParms
->dwReturn
= 3333;
758 if (dwFlags
& MCI_STATUS_START
) {
761 if (dwFlags
& MCI_TRACK
) {
762 lpParms
->dwTrack
= 1;
763 lpParms
->dwReturn
= 777;
766 case MCI_STATUS_READY
:
767 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_STATUS_READY !\n");
768 lpParms
->dwReturn
= TRUE
;
770 case MCI_STATUS_TIME_FORMAT
:
771 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
772 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
774 case MCI_SEQ_STATUS_DIVTYPE
:
775 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
776 lpParms
->dwReturn
= 0;
778 case MCI_SEQ_STATUS_MASTER
:
779 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
780 lpParms
->dwReturn
= 0;
782 case MCI_SEQ_STATUS_SLAVE
:
783 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
784 lpParms
->dwReturn
= 0;
786 case MCI_SEQ_STATUS_OFFSET
:
787 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
788 lpParms
->dwReturn
= 0;
790 case MCI_SEQ_STATUS_PORT
:
791 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
792 lpParms
->dwReturn
= 0;
794 case MCI_SEQ_STATUS_TEMPO
:
795 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
796 lpParms
->dwReturn
= 0;
799 dprintf_midi(stddeb
, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms
->dwItem
);
800 return MCIERR_UNRECOGNIZED_COMMAND
;
803 if (dwFlags
& MCI_NOTIFY
) {
804 dprintf_midi(stddeb
, "MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
805 mciDriverNotify((HWND16
)LOWORD(lpParms
->dwCallback
),
806 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
810 return MCIERR_INTERNAL
;
814 /**************************************************************************
815 * MIDI_mciGetDevCaps [internal]
817 static DWORD
MIDI_mciGetDevCaps(UINT16 wDevID
, DWORD dwFlags
,
818 LPMCI_GETDEVCAPS_PARMS lpParms
)
820 #if defined(linux) || defined(__FreeBSD__)
821 dprintf_midi(stddeb
, "MIDI_mciGetDevCaps(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
822 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
823 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
824 switch(lpParms
->dwItem
) {
825 case MCI_GETDEVCAPS_CAN_RECORD
:
826 lpParms
->dwReturn
= TRUE
;
828 case MCI_GETDEVCAPS_HAS_AUDIO
:
829 lpParms
->dwReturn
= TRUE
;
831 case MCI_GETDEVCAPS_HAS_VIDEO
:
832 lpParms
->dwReturn
= FALSE
;
834 case MCI_GETDEVCAPS_DEVICE_TYPE
:
835 lpParms
->dwReturn
= MCI_DEVTYPE_SEQUENCER
;
837 case MCI_GETDEVCAPS_USES_FILES
:
838 lpParms
->dwReturn
= TRUE
;
840 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
841 lpParms
->dwReturn
= TRUE
;
843 case MCI_GETDEVCAPS_CAN_EJECT
:
844 lpParms
->dwReturn
= FALSE
;
846 case MCI_GETDEVCAPS_CAN_PLAY
:
847 lpParms
->dwReturn
= TRUE
;
849 case MCI_GETDEVCAPS_CAN_SAVE
:
850 lpParms
->dwReturn
= FALSE
;
853 return MCIERR_UNRECOGNIZED_COMMAND
;
858 return MCIERR_INTERNAL
;
862 /**************************************************************************
863 * MIDI_mciInfo [internal]
865 static DWORD
MIDI_mciInfo(UINT16 wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
)
867 #if defined(linux) || defined(__FreeBSD__)
868 dprintf_midi(stddeb
, "MIDI_mciInfo(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
869 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
870 lpParms
->lpstrReturn
= NULL
;
872 case MCI_INFO_PRODUCT
:
873 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
876 lpParms
->lpstrReturn
= "FileName";
879 return MCIERR_UNRECOGNIZED_COMMAND
;
881 if (lpParms
->lpstrReturn
!= NULL
)
882 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
884 lpParms
->dwRetSize
= 0;
887 return MCIERR_INTERNAL
;
892 /*-----------------------------------------------------------------------*/
895 /**************************************************************************
896 * midGetDevCaps [internal]
898 static DWORD
midGetDevCaps(WORD wDevID
, LPMIDIINCAPS lpCaps
, DWORD dwSize
)
900 dprintf_midi(stddeb
, "midGetDevCaps(%04X, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
901 lpCaps
->wMid
= 0x00FF; /* Manufac ID */
902 lpCaps
->wPid
= 0x0001; /* Product ID */
903 lpCaps
->vDriverVersion
= 0x001; /* Product Version */
904 strcpy(lpCaps
->szPname
, "Linux MIDIIN Driver");
906 return MMSYSERR_NOERROR
;
909 /**************************************************************************
912 static DWORD
midOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
914 #if defined(linux) || defined(__FreeBSD__)
917 "midOpen(%04X, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
918 if (lpDesc
== NULL
) {
919 dprintf_midi(stddeb
,"Linux 'midOpen' // Invalid Parameter !\n");
920 return MMSYSERR_INVALPARAM
;
922 if (wDevID
>= MAX_MIDIINDRV
) {
923 dprintf_midi(stddeb
,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
924 return MMSYSERR_ALLOCATED
;
926 MidiInDev
[wDevID
].unixdev
= 0;
927 midi
= open (MIDI_DEV
, O_RDONLY
, 0);
929 dprintf_midi(stddeb
,"Linux 'midOpen' // can't open !\n");
930 return MMSYSERR_NOTENABLED
;
932 MidiInDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
933 switch(MidiInDev
[wDevID
].wFlags
) {
935 dprintf_midi(stddeb
,"Linux 'midOpen' // CALLBACK_NULL !\n");
939 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
943 "Linux 'midOpen' // CALLBACK_TASK !\n");
947 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
950 MidiInDev
[wDevID
].lpQueueHdr
= NULL
;
951 MidiInDev
[wDevID
].unixdev
= midi
;
952 MidiInDev
[wDevID
].dwTotalPlayed
= 0;
953 MidiInDev
[wDevID
].bufsize
= 0x3FFF;
954 if (MIDI_NotifyClient(wDevID
, MIM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
955 dprintf_midi(stddeb
,"Linux 'midOpen' // can't notify client !\n");
956 return MMSYSERR_INVALPARAM
;
958 return MMSYSERR_NOERROR
;
960 return MMSYSERR_NOTENABLED
;
964 /**************************************************************************
965 * midClose [internal]
967 static DWORD
midClose(WORD wDevID
)
969 #if defined(linux) || defined(__FreeBSD__)
970 dprintf_midi(stddeb
, "midClose(%04X);\n", wDevID
);
971 if (MidiInDev
[wDevID
].unixdev
== 0) {
972 dprintf_midi(stddeb
,"Linux 'midClose' // can't close !\n");
973 return MMSYSERR_NOTENABLED
;
975 close(MidiInDev
[wDevID
].unixdev
);
976 MidiInDev
[wDevID
].unixdev
= 0;
977 MidiInDev
[wDevID
].bufsize
= 0;
978 if (MIDI_NotifyClient(wDevID
, MIM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
979 dprintf_midi(stddeb
,"Linux 'midClose' // can't notify client !\n");
980 return MMSYSERR_INVALPARAM
;
982 return MMSYSERR_NOERROR
;
984 return MMSYSERR_NOTENABLED
;
988 /**************************************************************************
989 * midAddBuffer [internal]
991 static DWORD
midAddBuffer(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
993 dprintf_midi(stddeb
, "midAddBuffer(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
994 return MMSYSERR_NOTENABLED
;
997 /**************************************************************************
998 * midPrepare [internal]
1000 static DWORD
midPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1002 dprintf_midi(stddeb
, "midPrepare(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1003 return MMSYSERR_NOTENABLED
;
1006 /**************************************************************************
1007 * midUnprepare [internal]
1009 static DWORD
midUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1011 dprintf_midi(stddeb
, "midUnprepare(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1012 return MMSYSERR_NOTENABLED
;
1015 /**************************************************************************
1016 * midReset [internal]
1018 static DWORD
midReset(WORD wDevID
)
1020 dprintf_midi(stddeb
, "midReset(%04X);\n", wDevID
);
1021 return MMSYSERR_NOTENABLED
;
1025 /**************************************************************************
1026 * midStart [internal]
1028 static DWORD
midStart(WORD wDevID
)
1030 dprintf_midi(stddeb
, "midStart(%04X);\n", wDevID
);
1031 return MMSYSERR_NOTENABLED
;
1035 /**************************************************************************
1036 * midStop [internal]
1038 static DWORD
midStop(WORD wDevID
)
1040 dprintf_midi(stddeb
, "midStop(%04X);\n", wDevID
);
1041 return MMSYSERR_NOTENABLED
;
1045 /**************************************************************************
1046 * midMessage [sample driver]
1048 DWORD
midMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1049 DWORD dwParam1
, DWORD dwParam2
)
1051 dprintf_midi(stddeb
, "midMessage(%04X, %04X, %08lX, %08lX, %08lX);\n",
1052 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1055 return midOpen(wDevID
, (LPMIDIOPENDESC
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1057 return midClose(wDevID
);
1058 case MIDM_ADDBUFFER
:
1059 return midAddBuffer(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1061 return midPrepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1062 case MIDM_UNPREPARE
:
1063 return midUnprepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1064 case MIDM_GETDEVCAPS
:
1065 return midGetDevCaps(wDevID
, (LPMIDIINCAPS
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1066 case MIDM_GETNUMDEVS
:
1069 return midReset(wDevID
);
1071 return midStart(wDevID
);
1073 return midStop(wDevID
);
1075 return MMSYSERR_NOTSUPPORTED
;
1080 /*-----------------------------------------------------------------------*/
1083 /**************************************************************************
1084 * modGetDevCaps [internal]
1086 static DWORD
modGetDevCaps(WORD wDevID
, LPMIDIOUTCAPS lpCaps
, DWORD dwSize
)
1088 dprintf_midi(stddeb
, "modGetDevCaps(%04X, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
1089 lpCaps
->wMid
= 0x00FF; /* Manufac ID */
1090 lpCaps
->wPid
= 0x0001; /* Product ID */
1091 lpCaps
->vDriverVersion
= 0x001; /* Product Version */
1092 strcpy(lpCaps
->szPname
, "Linux MIDIOUT Driver v0.01");
1094 Values are the same as I get with Borland TC 4.5
1097 lpCaps
->wTechnology
= MOD_FMSYNTH
;
1098 lpCaps
->wVoices
= 14; /* make it ioctl */
1099 lpCaps
->wNotes
= 14; /* make it ioctl */
1100 lpCaps
->dwSupport
= MIDICAPS_VOLUME
|MIDICAPS_LRVOLUME
;
1101 dprintf_midi(stddeb
,"Linux modGetDevCaps // techn = %d voices=%d notes = %d support = %ld\n",lpCaps
->wTechnology
,lpCaps
->wVoices
,lpCaps
->wNotes
,lpCaps
->dwSupport
);
1103 return MMSYSERR_NOERROR
;
1107 /**************************************************************************
1108 * modOpen [internal]
1110 static DWORD
modOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
1112 #if defined(linux) || defined(__FreeBSD__)
1115 dprintf_midi(stddeb
,
1116 "modOpen(%04X, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
1117 if (lpDesc
== NULL
) {
1118 dprintf_midi(stddeb
,"Linux 'modOpen' // Invalid Parameter !\n");
1119 return MMSYSERR_INVALPARAM
;
1121 if (wDevID
>= MAX_MIDIOUTDRV
) {
1122 dprintf_midi(stddeb
,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1123 return MMSYSERR_ALLOCATED
;
1125 MidiOutDev
[wDevID
].unixdev
= 0;
1126 midi
= open (MIDI_DEV
, O_WRONLY
, 0);
1128 dprintf_midi(stddeb
,"Linux 'modOpen' // can't open !\n");
1129 return MMSYSERR_NOTENABLED
;
1131 MidiOutDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
1132 switch(MidiOutDev
[wDevID
].wFlags
) {
1134 dprintf_midi(stddeb
,"Linux 'modOpen' // CALLBACK_NULL !\n");
1137 dprintf_midi(stddeb
,
1138 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1141 dprintf_midi(stddeb
,
1142 "Linux 'modOpen' // CALLBACK_TASK !\n");
1145 dprintf_midi(stddeb
,
1146 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1149 MidiOutDev
[wDevID
].lpQueueHdr
= NULL
;
1150 MidiOutDev
[wDevID
].unixdev
= midi
;
1151 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1152 MidiOutDev
[wDevID
].bufsize
= 0x3FFF;
1153 if (MIDI_NotifyClient(wDevID
, MOM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
1154 dprintf_midi(stddeb
,"Linux 'modOpen' // can't notify client !\n");
1155 return MMSYSERR_INVALPARAM
;
1157 dprintf_midi(stddeb
,
1158 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi
);
1159 return MMSYSERR_NOERROR
;
1161 return MMSYSERR_NOTENABLED
;
1166 /**************************************************************************
1167 * modClose [internal]
1169 static DWORD
modClose(WORD wDevID
)
1171 #if defined(linux) || defined(__FreeBSD__)
1172 dprintf_midi(stddeb
, "modClose(%04X);\n", wDevID
);
1173 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1174 dprintf_midi(stddeb
,"Linux 'modClose' // can't close !\n");
1175 return MMSYSERR_NOTENABLED
;
1177 close(MidiOutDev
[wDevID
].unixdev
);
1178 MidiOutDev
[wDevID
].unixdev
= 0;
1179 MidiOutDev
[wDevID
].bufsize
= 0;
1180 if (MIDI_NotifyClient(wDevID
, MOM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1181 dprintf_midi(stddeb
,"Linux 'modClose' // can't notify client !\n");
1182 return MMSYSERR_INVALPARAM
;
1184 return MMSYSERR_NOERROR
;
1186 return MMSYSERR_NOTENABLED
;
1190 /**************************************************************************
1191 * modData [internal]
1193 static DWORD
modData(WORD wDevID
, DWORD dwParam
)
1195 #if defined(linux) || defined(__FreeBSD__)
1198 dprintf_midi(stddeb
,
1199 "modData(%04X, %08lX);\n", wDevID
, dwParam
);
1200 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1201 dprintf_midi(stddeb
,"Linux 'modData' // can't play !\n");
1202 return MIDIERR_NODEVICE
;
1204 event
= LOWORD(dwParam
);
1205 if (write (MidiOutDev
[wDevID
].unixdev
,
1206 &event
, sizeof(WORD
)) != sizeof(WORD
)) {
1207 dprintf_midi(stddeb
,
1208 "modData() // error writting unixdev !\n");
1210 return MMSYSERR_NOTENABLED
;
1212 return MMSYSERR_NOTENABLED
;
1216 /**************************************************************************
1217 * modLongData [internal]
1219 static DWORD
modLongData(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1221 #if defined(linux) || defined(__FreeBSD__)
1226 dprintf_midi(stddeb
,
1227 "modLongData(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1228 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1229 dprintf_midi(stddeb
,"Linux 'modLongData' // can't play !\n");
1230 return MIDIERR_NODEVICE
;
1232 if (lpMidiHdr
->lpData
== NULL
) return MIDIERR_UNPREPARED
;
1233 if (!(lpMidiHdr
->dwFlags
& MHDR_PREPARED
)) return MIDIERR_UNPREPARED
;
1234 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1235 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1236 lpMidiHdr
->dwFlags
|= MHDR_INQUEUE
;
1237 dprintf_midi(stddeb
,
1238 "modLongData() // dwBytesRecorded %lu !\n", lpMidiHdr
->dwBytesRecorded
);
1239 dprintf_midi(stddeb
,
1240 " %02X %02X %02X %02X\n",lpMidiHdr
->lpData
[0],
1241 lpMidiHdr
->lpData
[1],
1242 lpMidiHdr
->lpData
[2],
1243 lpMidiHdr
->lpData
[3]);
1245 count = write (MidiOutDev[wDevID].unixdev,
1246 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1248 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
1249 for (count
= 0; count
< lpMidiHdr
->dwBytesRecorded
; count
++) {
1250 if (write (MidiOutDev
[wDevID
].unixdev
, ptr
,
1251 sizeof(WORD
)) != sizeof(WORD
)) break;
1256 dprintf_midi(stddeb
, "Linux 'modLongData' // after write count = %d\n",count
);
1257 if (count
!= lpMidiHdr
->dwBytesRecorded
) {
1258 dprintf_midi(stddeb
,
1259 "modLongData() // error writting unixdev #%d ! (%d != %ld)\n",
1260 MidiOutDev
[wDevID
].unixdev
, count
, lpMidiHdr
->dwBytesRecorded
);
1261 dprintf_midi(stddeb
,
1262 " errno = %d error = %s\n",en
,strerror(en
));
1263 return MMSYSERR_NOTENABLED
;
1265 lpMidiHdr
->dwFlags
&= ~MHDR_INQUEUE
;
1266 lpMidiHdr
->dwFlags
|= MHDR_DONE
;
1267 if (MIDI_NotifyClient(wDevID
, MOM_DONE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1268 dprintf_midi(stddeb
,"Linux 'modLongData' // can't notify client !\n");
1269 return MMSYSERR_INVALPARAM
;
1271 return MMSYSERR_NOERROR
;
1273 return MMSYSERR_NOTENABLED
;
1277 /**************************************************************************
1278 * modPrepare [internal]
1280 static DWORD
modPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1282 #if defined(linux) || defined(__FreeBSD__)
1283 dprintf_midi(stddeb
,
1284 "modPrepare(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1285 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1286 dprintf_midi(stddeb
,"Linux 'modPrepare' // can't prepare !\n");
1287 return MMSYSERR_NOTENABLED
;
1289 if (MidiOutDev
[wDevID
].lpQueueHdr
!= NULL
) {
1290 dprintf_midi(stddeb
,"Linux 'modPrepare' // already prepare !\n");
1291 return MMSYSERR_NOTENABLED
;
1293 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1294 MidiOutDev
[wDevID
].lpQueueHdr
= PTR_SEG_TO_LIN(lpMidiHdr
);
1295 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1296 lpMidiHdr
->dwFlags
|= MHDR_PREPARED
;
1297 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1298 return MMSYSERR_NOERROR
;
1300 return MMSYSERR_NOTENABLED
;
1304 /**************************************************************************
1305 * modUnprepare [internal]
1307 static DWORD
modUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1309 #if defined(linux) || defined(__FreeBSD__)
1310 dprintf_midi(stddeb
,
1311 "modUnprepare(%04X, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1312 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1313 dprintf_midi(stddeb
,"Linux 'modUnprepare' // can't unprepare !\n");
1314 return MMSYSERR_NOTENABLED
;
1316 return MMSYSERR_NOERROR
;
1318 return MMSYSERR_NOTENABLED
;
1322 /**************************************************************************
1323 * modReset [internal]
1325 static DWORD
modReset(WORD wDevID
)
1327 dprintf_midi(stddeb
, "modReset(%04X);\n", wDevID
);
1328 return MMSYSERR_NOTENABLED
;
1332 /**************************************************************************
1333 * modMessage [sample driver]
1335 DWORD
modMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1336 DWORD dwParam1
, DWORD dwParam2
)
1338 dprintf_midi(stddeb
, "modMessage(%04X, %04X, %08lX, %08lX, %08lX);\n",
1339 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1342 return modOpen(wDevID
, (LPMIDIOPENDESC
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1344 return modClose(wDevID
);
1346 return modData(wDevID
, dwParam1
);
1348 return modLongData(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1350 return modPrepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1351 case MODM_UNPREPARE
:
1352 return modUnprepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1353 case MODM_GETDEVCAPS
:
1354 return modGetDevCaps(wDevID
, (LPMIDIOUTCAPS
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1355 case MODM_GETNUMDEVS
:
1357 case MODM_GETVOLUME
:
1359 case MODM_SETVOLUME
:
1362 return modReset(wDevID
);
1364 return MMSYSERR_NOTSUPPORTED
;
1368 /**************************************************************************
1369 * MIDI_DriverProc [sample driver]
1371 LONG
MIDI_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
1372 DWORD dwParam1
, DWORD dwParam2
)
1374 #if defined(linux) || defined(__FreeBSD__)
1388 case DRV_QUERYCONFIGURE
:
1391 MessageBox16(0, "Sample Midi Linux Driver !",
1392 "MMLinux Driver", MB_OK
);
1395 return DRVCNF_RESTART
;
1397 return DRVCNF_RESTART
;
1398 case MCI_OPEN_DRIVER
:
1400 return MIDI_mciOpen(dwDevID
, dwParam1
, (LPMCI_OPEN_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1401 case MCI_CLOSE_DRIVER
:
1403 return MIDI_mciClose(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1405 return MIDI_mciPlay(dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1407 return MIDI_mciRecord(dwDevID
, dwParam1
, (LPMCI_RECORD_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1409 return MIDI_mciStop(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1411 return MIDI_mciSet(dwDevID
, dwParam1
, (LPMCI_SET_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1413 return MIDI_mciPause(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1415 return MIDI_mciResume(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1417 return MIDI_mciStatus(dwDevID
, dwParam1
, (LPMCI_STATUS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1418 case MCI_GETDEVCAPS
:
1419 return MIDI_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1421 return MIDI_mciInfo(dwDevID
, dwParam1
, (LPMCI_INFO_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
1423 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
1426 return MMSYSERR_NOTENABLED
;
1431 /*-----------------------------------------------------------------------*/