2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
6 static char Copyright[] = "Copyright Martin Ayotte, 1994";
9 #define BUILTIN_MMSYSTEM
12 #ifdef BUILTIN_MMSYSTEM
18 #include <sys/ioctl.h>
25 /* #define DEBUG_MIDI */
29 #include <linux/soundcard.h>
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 2
42 #define MAX_MIDIOUTDRV 2
43 #define MAX_MCIMIDIDRV 2
49 MIDIOPENDESC midiDesc
;
59 MIDIOPENDESC midiDesc
;
66 int nUseCount
; /* Incremented for each shared open */
67 BOOL fShareable
; /* TRUE if first open was shareable */
68 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
69 HANDLE hCallback
; /* Callback handle for pending notification */
70 HMMIO hFile
; /* mmio file handle open as Element */
76 MCI_OPEN_PARMS openParms
;
81 static LINUX_MIDIIN MidiInDev
[MAX_MIDIINDRV
];
82 static LINUX_MIDIOUT MidiOutDev
[MAX_MIDIOUTDRV
];
83 static LINUX_MCIMIDI MCIMidiDev
[MAX_MCIMIDIDRV
];
86 DWORD
MIDI_mciOpen(UINT wDevID
, DWORD dwFlags
, LPMCI_OPEN_PARMS lpParms
);
87 DWORD
MIDI_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
);
88 DWORD
MIDI_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
);
89 DWORD
MIDI_mciRecord(UINT wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
);
90 DWORD
MIDI_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
91 DWORD
MIDI_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
92 DWORD
MIDI_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
93 DWORD
MIDI_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
);
94 DWORD
MIDI_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
);
95 DWORD
MIDI_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
, LPMCI_GETDEVCAPS_PARMS lpParms
);
96 DWORD
MIDI_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
);
98 DWORD
modOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
);
99 DWORD
modClose(WORD wDevID
);
100 DWORD
modGetDevCaps(WORD wDevID
, LPMIDIOUTCAPS lpCaps
, DWORD dwSize
);
101 DWORD
modPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
);
102 DWORD
modUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
);
103 DWORD
modLongData(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
);
104 DWORD
modData(WORD wDevID
, DWORD dwParam
);
106 DWORD
midOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
);
107 DWORD
midClose(WORD wDevID
);
108 DWORD
midGetDevCaps(WORD wDevID
, LPMIDIINCAPS lpCaps
, DWORD dwSize
);
110 /**************************************************************************
111 * MIDI_NotifyClient [internal]
113 DWORD
MIDI_NotifyClient(UINT wDevID
, WORD wMsg
,
114 DWORD dwParam1
, DWORD dwParam2
)
117 if (MidiInDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
118 MidiInDev
[wDevID
].midiDesc
.dwCallback
, MidiInDev
[wDevID
].wFlags
,
119 MidiInDev
[wDevID
].midiDesc
.hMidi
, wMsg
,
120 MidiInDev
[wDevID
].midiDesc
.dwInstance
, dwParam1
, dwParam2
)) {
121 printf("MIDI_NotifyClient // can't notify client !\n");
122 return MMSYSERR_NOERROR
;
126 return MMSYSERR_NOTENABLED
;
131 /**************************************************************************
132 * AUDIO_DriverProc [sample driver]
134 LRESULT
MIDI_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
135 DWORD dwParam1
, DWORD dwParam2
)
151 case DRV_QUERYCONFIGURE
:
154 MessageBox((HWND
)NULL
, "Sample Midi Linux Driver !",
155 "MMLinux Driver", MB_OK
);
158 return (LRESULT
)DRVCNF_RESTART
;
160 return (LRESULT
)DRVCNF_RESTART
;
161 case MCI_OPEN_DRIVER
:
163 return MIDI_mciOpen(dwDevID
, dwParam1
, (LPMCI_OPEN_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
164 case MCI_CLOSE_DRIVER
:
166 return MIDI_mciClose(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
168 return MIDI_mciPlay(dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
170 return MIDI_mciRecord(dwDevID
, dwParam1
, (LPMCI_RECORD_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
172 return MIDI_mciStop(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
174 return MIDI_mciSet(dwDevID
, dwParam1
, (LPMCI_SET_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
176 return MIDI_mciPause(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
178 return MIDI_mciResume(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
180 return MIDI_mciStatus(dwDevID
, dwParam1
, (LPMCI_STATUS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
182 return MIDI_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
184 return MIDI_mciInfo(dwDevID
, dwParam1
, (LPMCI_INFO_PARMS
)PTR_SEG_TO_LIN(dwParam2
));
186 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
189 return MMSYSERR_NOTENABLED
;
194 /**************************************************************************
195 * MIDI_ReadByte [internal]
197 DWORD
MIDI_ReadByte(UINT wDevID
, BYTE FAR
*lpbyt
)
201 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)lpbyt
,
202 (long) sizeof(BYTE
)) == (long) sizeof(BYTE
)) {
206 printf("MIDI_ReadByte // error reading wDevID=%d \n", wDevID
);
207 return MCIERR_INTERNAL
;
210 return MMSYSERR_NOTENABLED
;
215 /**************************************************************************
216 * MIDI_ReadWord [internal]
218 DWORD
MIDI_ReadWord(UINT wDevID
, LPWORD lpw
)
222 if (MIDI_ReadByte(wDevID
, &hibyte
) == 0) {
223 if (MIDI_ReadByte(wDevID
, &lobyte
) == 0) {
224 *lpw
= ((WORD
)hibyte
<< 8) + lobyte
;
229 printf("MIDI_ReadWord // error reading wDevID=%d \n", wDevID
);
230 return MCIERR_INTERNAL
;
234 /**************************************************************************
235 * MIDI_ReadLong [internal]
237 DWORD
MIDI_ReadLong(UINT wDevID
, LPDWORD lpdw
)
241 if (MIDI_ReadWord(wDevID
, &hiword
) == 0) {
242 if (MIDI_ReadWord(wDevID
, &loword
) == 0) {
243 *lpdw
= MAKELONG(loword
, hiword
);
248 printf("MIDI_ReadLong // error reading wDevID=%d \n", wDevID
);
249 return MCIERR_INTERNAL
;
253 /**************************************************************************
254 * MIDI_ReadVaryLen [internal]
256 DWORD
MIDI_ReadVaryLen(UINT wDevID
, LPDWORD lpdw
)
260 if (lpdw
== NULL
) return MCIERR_INTERNAL
;
261 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
262 printf("MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID
);
263 return MCIERR_INTERNAL
;
265 value
= (DWORD
)(byte
& 0x7F);
266 while (byte
& 0x80) {
267 if (MIDI_ReadByte(wDevID
, &byte
) != 0) {
268 printf("MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID
);
269 return MCIERR_INTERNAL
;
271 value
= (value
<< 7) + (byte
& 0x7F);
275 printf("MIDI_ReadVaryLen // val=%08lX \n", value);
281 /**************************************************************************
282 * MIDI_ReadMThd [internal]
284 DWORD
MIDI_ReadMThd(UINT wDevID
, DWORD dwOffset
)
289 dprintf_midi(stddeb
, "MIDI_ReadMThd(%04X, %08lX);\n", wDevID
, dwOffset
);
290 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
291 printf("MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset
);
292 return MCIERR_INTERNAL
;
294 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
295 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
)) {
296 return MCIERR_INTERNAL
;
298 if (MIDI_ReadLong(wDevID
, &toberead
) != 0) {
299 return MCIERR_INTERNAL
;
301 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].wFormat
) != 0) {
302 return MCIERR_INTERNAL
;
304 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTracks
) != 0) {
305 return MCIERR_INTERNAL
;
307 if (MIDI_ReadWord(wDevID
, &MCIMidiDev
[wDevID
].nTempo
) != 0) {
308 return MCIERR_INTERNAL
;
310 printf("MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
311 toberead
, MCIMidiDev
[wDevID
].wFormat
,
312 MCIMidiDev
[wDevID
].nTracks
,
313 MCIMidiDev
[wDevID
].nTempo
);
314 toberead
-= 3 * sizeof(WORD
);
316 ntrks = read16bit ();
317 Mf_division = division = read16bit ();
322 return MMSYSERR_NOTENABLED
;
327 DWORD
MIDI_ReadMTrk(UINT wDevID
, DWORD dwOffset
)
332 if (mmioSeek(MCIMidiDev
[wDevID
].hFile
, dwOffset
, SEEK_SET
) != dwOffset
) {
333 printf("MIDI_ReadMTrk // can't seek at %08lX begin of 'MThd' \n", dwOffset
);
335 if (mmioRead(MCIMidiDev
[wDevID
].hFile
, (HPSTR
)&fourcc
,
336 (long) sizeof(FOURCC
)) != (long) sizeof(FOURCC
)) {
337 return MCIERR_INTERNAL
;
339 if (MIDI_ReadLong(wDevID
, &toberead
) != 0) {
340 return MCIERR_INTERNAL
;
342 printf("MIDI_ReadMTrk // toberead=%08lX\n", toberead
);
343 toberead
-= 3 * sizeof(WORD
);
344 MCIMidiDev
[wDevID
].dwTotalLen
= toberead
;
347 return MMSYSERR_NOTENABLED
;
352 /**************************************************************************
353 * MIDI_mciOpen [internal]
355 DWORD
MIDI_mciOpen(UINT wDevID
, DWORD dwFlags
, LPMCI_OPEN_PARMS lpParms
)
358 MIDIOPENDESC MidiDesc
;
361 LPSTR lpstrElementName
;
364 dprintf_midi( stddeb
, "MIDI_mciOpen(%08lX, %p)\n", dwFlags
, lpParms
);
365 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
366 if (MCIMidiDev
[wDevID
].nUseCount
> 0) {
367 /* The driver already open on this channel */
368 /* If the driver was opened shareable before and this open specifies */
369 /* shareable then increment the use count */
370 if (MCIMidiDev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
371 ++MCIMidiDev
[wDevID
].nUseCount
;
373 return MCIERR_MUST_USE_SHAREABLE
;
376 MCIMidiDev
[wDevID
].nUseCount
= 1;
377 MCIMidiDev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
379 dprintf_midi(stddeb
,"MIDI_mciOpen // wDevID=%04X\n", wDevID
);
380 lpParms
->wDeviceID
= wDevID
;
381 dprintf_midi(stddeb
,"MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms
->wDeviceID
);
382 dprintf_midi(stddeb
,"MIDI_mciOpen // before OPEN_ELEMENT\n");
383 if (dwFlags
& MCI_OPEN_ELEMENT
) {
384 lpstrElementName
= (LPSTR
)PTR_SEG_TO_LIN(lpParms
->lpstrElementName
);
385 dprintf_midi( stddeb
, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName
);
386 /* printf("MIDI_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
387 if (strlen(lpstrElementName
) > 0) {
388 strcpy(str
, lpstrElementName
);
390 MCIMidiDev
[wDevID
].hFile
= mmioOpen(str
, NULL
,
391 MMIO_ALLOCBUF
| MMIO_READWRITE
| MMIO_EXCLUSIVE
);
392 if (MCIMidiDev
[wDevID
].hFile
== 0) {
393 printf("MIDI_mciOpen // can't find file='%s' !\n", str
);
394 return MCIERR_FILE_NOT_FOUND
;
398 MCIMidiDev
[wDevID
].hFile
= 0;
400 printf("MIDI_mciOpen // hFile=%u\n", MCIMidiDev
[wDevID
].hFile
);
401 memcpy(&MCIMidiDev
[wDevID
].openParms
, lpParms
, sizeof(MCI_OPEN_PARMS
));
402 MCIMidiDev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
403 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
404 MCIMidiDev
[wDevID
].dwBeginData
= 0;
405 MCIMidiDev
[wDevID
].dwTotalLen
= 0;
407 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
409 if (mmioDescend(MCIMidiDev
[wDevID
].hFile
, &ckMainRIFF
, NULL
, 0) != 0) {
410 return MCIERR_INTERNAL
;
412 dprintf_midi(stddeb
,"MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
413 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
416 if (ckMainRIFF
.ckid
== mmioFOURCC('R', 'M', 'I', 'D')) {
417 printf("MIDI_mciOpen // is a 'RMID' file \n");
418 dwOffset
= ckMainRIFF
.dwDataOffset
;
420 if (ckMainRIFF
.ckid
!= mmioFOURCC('M', 'T', 'h', 'd')) {
421 printf("MIDI_mciOpen // unknown format !\n");
422 return MCIERR_INTERNAL
;
424 if (MIDI_ReadMThd(wDevID
, dwOffset
) != 0) {
425 printf("MIDI_mciOpen // can't read 'MThd' header \n");
426 return MCIERR_INTERNAL
;
428 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
429 if (MIDI_ReadMTrk(wDevID
, dwOffset
) != 0) {
430 printf("MIDI_mciOpen // can't read 'MTrk' header \n");
431 return MCIERR_INTERNAL
;
433 dwOffset
= mmioSeek(MCIMidiDev
[wDevID
].hFile
, 0, SEEK_CUR
);
434 MCIMidiDev
[wDevID
].dwBeginData
= dwOffset
;
435 dprintf_midi(stddeb
,"MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
436 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
439 dwRet
= modMessage(0, MODM_OPEN
, 0, (DWORD
)&MidiDesc
, CALLBACK_NULL
);
440 dwRet
= midMessage(0, MIDM_OPEN
, 0, (DWORD
)&MidiDesc
, CALLBACK_NULL
);
443 return MMSYSERR_NOTENABLED
;
448 /**************************************************************************
449 * MIDI_mciClose [internal]
451 DWORD
MIDI_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
456 printf("MIDI_mciClose(%u, %08lX, %p);\n", wDevID
, dwParam
, lpParms
);
458 if (MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
459 MIDI_mciStop(wDevID
, MCI_WAIT
, lpParms
);
461 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
462 MCIMidiDev
[wDevID
].nUseCount
--;
463 if (MCIMidiDev
[wDevID
].nUseCount
== 0) {
464 if (MCIMidiDev
[wDevID
].hFile
!= 0) {
465 mmioClose(MCIMidiDev
[wDevID
].hFile
, 0);
466 MCIMidiDev
[wDevID
].hFile
= 0;
467 printf("MIDI_mciClose // hFile closed !\n");
469 dwRet
= modMessage(0, MODM_CLOSE
, 0, 0L, 0L);
470 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
471 dwRet
= midMessage(0, MIDM_CLOSE
, 0, 0L, 0L);
472 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
481 /**************************************************************************
482 * MIDI_mciPlay [internal]
484 DWORD
MIDI_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
494 printf("MIDI_mciPlay(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
496 if (MCIMidiDev
[wDevID
].hFile
== 0) {
497 printf("MIDI_mciPlay // can't find file='%s' !\n",
498 MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
499 return MCIERR_FILE_NOT_FOUND
;
501 start
= 1; end
= 99999;
502 if (dwFlags
& MCI_FROM
) {
503 start
= lpParms
->dwFrom
;
504 printf("MIDI_mciPlay // MCI_FROM=%d \n", start
);
506 if (dwFlags
& MCI_TO
) {
508 printf("MIDI_mciPlay // MCI_TO=%d \n", end
);
511 if (dwFlags
& MCI_NOTIFY
) {
512 printf("MIDI_mciPlay // MCI_NOTIFY %08lX !\n", lpParms
->dwCallback
);
515 printf("MIDI_mciPlay // Can't 'fork' process !\n");
518 printf("MIDI_mciPlay // process started ! play in background ...\n");
521 printf("MIDI_mciPlay // process started ! return to caller...\n");
526 lpMidiHdr
= &MCIMidiDev
[wDevID
].MidiHdr
;
527 lpMidiHdr
->lpData
= (LPSTR
) malloc(1200);
528 if (lpMidiHdr
->lpData
== NULL
) return MCIERR_INTERNAL
;
529 lpMidiHdr
->dwBufferLength
= 1024;
530 lpMidiHdr
->dwUser
= 0L;
531 lpMidiHdr
->dwFlags
= 0L;
532 dwRet
= modMessage(0, MODM_PREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
533 /* printf("MIDI_mciPlay // after MODM_PREPARE \n"); */
534 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_PLAY
;
535 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
536 printf("MIDI_mciPlay // MCIMidiDev[wDevID].dwStatus=%p %d\n",
537 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
538 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
539 for (count
= 0; count
< lpMidiHdr
->dwBufferLength
; count
++) {
540 if (MIDI_ReadVaryLen(wDevID
, &dwData
) != 0) break;
541 *ptr
= LOWORD(dwData
);
544 count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
546 if (count
< 1) break;
547 lpMidiHdr
->dwBytesRecorded
= count
;
549 printf("MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
550 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
552 dwRet
= modMessage(0, MODM_LONGDATA
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
554 dwRet
= modMessage(0, MODM_UNPREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
555 if (lpMidiHdr
->lpData
!= NULL
) {
556 free(lpMidiHdr
->lpData
);
557 lpMidiHdr
->lpData
= NULL
;
559 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
560 if (dwFlags
& MCI_NOTIFY
) {
562 printf("MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
564 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
565 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
570 return MMSYSERR_NOTENABLED
;
575 /**************************************************************************
576 * MIDI_mciRecord [internal]
578 DWORD
MIDI_mciRecord(UINT wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
)
585 dprintf_midi( stddeb
, "MIDI_mciRecord(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
586 if (MCIMidiDev
[wDevID
].hFile
== 0) {
587 printf("MIDI_mciRecord // can't find file='%s' !\n",
588 MCIMidiDev
[wDevID
].openParms
.lpstrElementName
);
589 return MCIERR_FILE_NOT_FOUND
;
591 start
= 1; end
= 99999;
592 if (dwFlags
& MCI_FROM
) {
593 start
= lpParms
->dwFrom
;
594 printf("MIDI_mciRecord // MCI_FROM=%d \n", start
);
596 if (dwFlags
& MCI_TO
) {
598 printf("MIDI_mciRecord // MCI_TO=%d \n", end
);
600 lpMidiHdr
= &MCIMidiDev
[wDevID
].MidiHdr
;
601 lpMidiHdr
->lpData
= (LPSTR
) malloc(1200);
602 lpMidiHdr
->dwBufferLength
= 1024;
603 lpMidiHdr
->dwUser
= 0L;
604 lpMidiHdr
->dwFlags
= 0L;
605 dwRet
= midMessage(0, MIDM_PREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
606 printf("MIDI_mciRecord // after MIDM_PREPARE \n");
607 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_RECORD
;
608 while(MCIMidiDev
[wDevID
].dwStatus
!= MCI_MODE_STOP
) {
609 printf("MIDI_mciRecord // MCIMidiDev[wDevID].dwStatus=%p %d\n",
610 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
611 lpMidiHdr
->dwBytesRecorded
= 0;
612 dwRet
= midMessage(0, MIDM_START
, 0, 0L, 0L);
613 printf("MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
614 lpMidiHdr
, lpMidiHdr
->dwBytesRecorded
);
615 if (lpMidiHdr
->dwBytesRecorded
== 0) break;
617 printf("MIDI_mciRecord // before MIDM_UNPREPARE \n");
618 dwRet
= midMessage(0, MIDM_UNPREPARE
, 0, (DWORD
)lpMidiHdr
, sizeof(MIDIHDR
));
619 printf("MIDI_mciRecord // after MIDM_UNPREPARE \n");
620 if (lpMidiHdr
->lpData
!= NULL
) {
621 free(lpMidiHdr
->lpData
);
622 lpMidiHdr
->lpData
= NULL
;
624 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
625 if (dwFlags
& MCI_NOTIFY
) {
627 printf("MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
629 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
630 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
634 return MMSYSERR_NOTENABLED
;
639 /**************************************************************************
640 * MIDI_mciStop [internal]
642 DWORD
MIDI_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
646 printf("MIDI_mciStop(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
648 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
649 MCIMidiDev
[wDevID
].dwStatus
= MCI_MODE_STOP
;
650 printf("MIDI_mciStop // MCIMidiDev[wDevID].dwStatus=%p %d\n",
651 &MCIMidiDev
[wDevID
].dwStatus
, MCIMidiDev
[wDevID
].dwStatus
);
654 return MCIERR_INTERNAL
;
659 /**************************************************************************
660 * MIDI_mciPause [internal]
662 DWORD
MIDI_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
666 printf("MIDI_mciPause(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
668 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
671 return MCIERR_INTERNAL
;
676 /**************************************************************************
677 * MIDI_mciResume [internal]
679 DWORD
MIDI_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
683 printf("MIDI_mciResume(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
685 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
688 return MCIERR_INTERNAL
;
693 /**************************************************************************
694 * MIDI_mciSet [internal]
696 DWORD
MIDI_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
700 printf("MIDI_mciSet(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
702 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
704 printf("MIDI_mciSet // dwTimeFormat=%08lX\n", lpParms
->dwTimeFormat
);
705 printf("MIDI_mciSet // dwAudio=%08lX\n", lpParms
->dwAudio
);
707 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
708 switch (lpParms
->dwTimeFormat
) {
709 case MCI_FORMAT_MILLISECONDS
:
710 printf("MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
712 case MCI_FORMAT_BYTES
:
713 printf("MIDI_mciSet // MCI_FORMAT_BYTES !\n");
715 case MCI_FORMAT_SAMPLES
:
716 printf("MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
719 printf("MIDI_mciSet // bad time format !\n");
720 return MCIERR_BAD_TIME_FORMAT
;
723 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
724 if (dwFlags
& MCI_SET_DOOR_OPEN
) return MCIERR_UNSUPPORTED_FUNCTION
;
725 if (dwFlags
& MCI_SET_DOOR_CLOSED
) return MCIERR_UNSUPPORTED_FUNCTION
;
726 if (dwFlags
& MCI_SET_AUDIO
) {
727 printf("MIDI_mciSet // MCI_SET_AUDIO !\n");
729 if (dwFlags
&& MCI_SET_ON
) {
730 printf("MIDI_mciSet // MCI_SET_ON !\n");
731 if (dwFlags
&& MCI_SET_AUDIO_LEFT
) {
732 printf("MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
734 if (dwFlags
&& MCI_SET_AUDIO_RIGHT
) {
735 printf("MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
738 if (dwFlags
& MCI_SET_OFF
) {
739 printf("MIDI_mciSet // MCI_SET_OFF !\n");
741 if (dwFlags
& MCI_SEQ_SET_MASTER
) {
742 printf("MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
744 if (dwFlags
& MCI_SEQ_SET_SLAVE
) {
745 printf("MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
747 if (dwFlags
& MCI_SEQ_SET_OFFSET
) {
748 printf("MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
750 if (dwFlags
& MCI_SEQ_SET_PORT
) {
751 printf("MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
753 if (dwFlags
& MCI_SEQ_SET_TEMPO
) {
754 printf("MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
758 return MCIERR_INTERNAL
;
763 /**************************************************************************
764 * MIDI_mciStatus [internal]
766 DWORD
MIDI_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
770 printf("MIDI_mciStatus(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
772 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
773 if (dwFlags
& MCI_STATUS_ITEM
) {
774 switch(lpParms
->dwItem
) {
775 case MCI_STATUS_CURRENT_TRACK
:
776 lpParms
->dwReturn
= 1;
778 case MCI_STATUS_LENGTH
:
779 lpParms
->dwReturn
= 5555;
780 if (dwFlags
& MCI_TRACK
) {
781 lpParms
->dwTrack
= 1;
782 lpParms
->dwReturn
= 2222;
785 case MCI_STATUS_MODE
:
786 lpParms
->dwReturn
= MCI_MODE_STOP
;
788 case MCI_STATUS_MEDIA_PRESENT
:
789 printf("MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
790 lpParms
->dwReturn
= TRUE
;
792 case MCI_STATUS_NUMBER_OF_TRACKS
:
793 lpParms
->dwReturn
= 1;
795 case MCI_STATUS_POSITION
:
796 lpParms
->dwReturn
= 3333;
797 if (dwFlags
& MCI_STATUS_START
) {
800 if (dwFlags
& MCI_TRACK
) {
801 lpParms
->dwTrack
= 1;
802 lpParms
->dwReturn
= 777;
805 case MCI_STATUS_READY
:
806 printf("MIDI_mciStatus // MCI_STATUS_READY !\n");
807 lpParms
->dwReturn
= TRUE
;
809 case MCI_STATUS_TIME_FORMAT
:
810 printf("MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
811 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
813 case MCI_SEQ_STATUS_DIVTYPE
:
814 printf("MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
815 lpParms
->dwReturn
= 0;
817 case MCI_SEQ_STATUS_MASTER
:
818 printf("MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
819 lpParms
->dwReturn
= 0;
821 case MCI_SEQ_STATUS_SLAVE
:
822 printf("MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
823 lpParms
->dwReturn
= 0;
825 case MCI_SEQ_STATUS_OFFSET
:
826 printf("MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
827 lpParms
->dwReturn
= 0;
829 case MCI_SEQ_STATUS_PORT
:
830 printf("MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
831 lpParms
->dwReturn
= 0;
833 case MCI_SEQ_STATUS_TEMPO
:
834 printf("MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
835 lpParms
->dwReturn
= 0;
838 printf("MIDI_mciStatus // unknowm command %08lX !\n", lpParms
->dwItem
);
839 return MCIERR_UNRECOGNIZED_COMMAND
;
842 if (dwFlags
& MCI_NOTIFY
) {
843 printf("MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
844 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
845 MCIMidiDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
849 return MCIERR_INTERNAL
;
853 /**************************************************************************
854 * MIDI_mciGetDevCaps [internal]
856 DWORD
MIDI_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
,
857 LPMCI_GETDEVCAPS_PARMS lpParms
)
860 printf("MIDI_mciGetDevCaps(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
861 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
862 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
863 switch(lpParms
->dwItem
) {
864 case MCI_GETDEVCAPS_CAN_RECORD
:
865 lpParms
->dwReturn
= TRUE
;
867 case MCI_GETDEVCAPS_HAS_AUDIO
:
868 lpParms
->dwReturn
= TRUE
;
870 case MCI_GETDEVCAPS_HAS_VIDEO
:
871 lpParms
->dwReturn
= FALSE
;
873 case MCI_GETDEVCAPS_DEVICE_TYPE
:
874 lpParms
->dwReturn
= MCI_DEVTYPE_SEQUENCER
;
876 case MCI_GETDEVCAPS_USES_FILES
:
877 lpParms
->dwReturn
= TRUE
;
879 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
880 lpParms
->dwReturn
= TRUE
;
882 case MCI_GETDEVCAPS_CAN_EJECT
:
883 lpParms
->dwReturn
= FALSE
;
885 case MCI_GETDEVCAPS_CAN_PLAY
:
886 lpParms
->dwReturn
= TRUE
;
888 case MCI_GETDEVCAPS_CAN_SAVE
:
889 lpParms
->dwReturn
= FALSE
;
892 return MCIERR_UNRECOGNIZED_COMMAND
;
897 return MCIERR_INTERNAL
;
901 /**************************************************************************
902 * MIDI_mciInfo [internal]
904 DWORD
MIDI_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
)
907 printf("MIDI_mciInfo(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
908 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
909 lpParms
->lpstrReturn
= NULL
;
911 case MCI_INFO_PRODUCT
:
912 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
915 lpParms
->lpstrReturn
= "FileName";
918 return MCIERR_UNRECOGNIZED_COMMAND
;
920 if (lpParms
->lpstrReturn
!= NULL
)
921 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
923 lpParms
->dwRetSize
= 0;
926 return MCIERR_INTERNAL
;
931 /*-----------------------------------------------------------------------*/
934 /**************************************************************************
935 * midGetDevCaps [internal]
937 DWORD
midGetDevCaps(WORD wDevID
, LPMIDIINCAPS lpCaps
, DWORD dwSize
)
939 printf("midGetDevCaps(%u, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
940 return MMSYSERR_NOTENABLED
;
943 /**************************************************************************
946 DWORD
midOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
951 "midOpen(%u, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
952 if (lpDesc
== NULL
) {
953 fprintf(stderr
,"Linux 'midOpen' // Invalid Parameter !\n");
954 return MMSYSERR_INVALPARAM
;
956 if (wDevID
>= MAX_MIDIINDRV
) {
957 fprintf(stderr
,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
958 return MMSYSERR_ALLOCATED
;
960 MidiInDev
[wDevID
].unixdev
= 0;
961 midi
= open (MIDI_DEV
, O_RDONLY
, 0);
963 fprintf(stderr
,"Linux 'midOpen' // can't open !\n");
964 return MMSYSERR_NOTENABLED
;
966 MidiInDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
967 switch(MidiInDev
[wDevID
].wFlags
) {
969 fprintf(stderr
,"Linux 'midOpen' // CALLBACK_NULL !\n");
973 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
977 "Linux 'midOpen' // CALLBACK_TASK !\n");
981 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
984 MidiInDev
[wDevID
].lpQueueHdr
= NULL
;
985 MidiInDev
[wDevID
].unixdev
= midi
;
986 MidiInDev
[wDevID
].dwTotalPlayed
= 0;
987 MidiInDev
[wDevID
].bufsize
= 0x3FFF;
988 if (MIDI_NotifyClient(wDevID
, MIM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
989 fprintf(stderr
,"Linux 'midOpen' // can't notify client !\n");
990 return MMSYSERR_INVALPARAM
;
992 return MMSYSERR_NOERROR
;
994 return MMSYSERR_NOTENABLED
;
998 /**************************************************************************
999 * midClose [internal]
1001 DWORD
midClose(WORD wDevID
)
1004 dprintf_midi(stddeb
,"midClose(%u);\n", wDevID
);
1005 if (MidiInDev
[wDevID
].unixdev
== 0) {
1006 fprintf(stderr
,"Linux 'midClose' // can't close !\n");
1007 return MMSYSERR_NOTENABLED
;
1009 close(MidiInDev
[wDevID
].unixdev
);
1010 MidiInDev
[wDevID
].unixdev
= 0;
1011 MidiInDev
[wDevID
].bufsize
= 0;
1012 if (MIDI_NotifyClient(wDevID
, MIM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1013 fprintf(stderr
,"Linux 'midClose' // can't notify client !\n");
1014 return MMSYSERR_INVALPARAM
;
1016 return MMSYSERR_NOERROR
;
1018 return MMSYSERR_NOTENABLED
;
1022 /**************************************************************************
1023 * midAddBuffer [internal]
1025 DWORD
midAddBuffer(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1027 printf("midAddBuffer(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1028 return MMSYSERR_NOTENABLED
;
1031 /**************************************************************************
1032 * midPrepare [internal]
1034 DWORD
midPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1036 printf("midPrepare(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1037 return MMSYSERR_NOTENABLED
;
1040 /**************************************************************************
1041 * midUnprepare [internal]
1043 DWORD
midUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1045 printf("midUnprepare(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1046 return MMSYSERR_NOTENABLED
;
1049 /**************************************************************************
1050 * midReset [internal]
1052 DWORD
midReset(WORD wDevID
)
1054 printf("midReset(%u);\n", wDevID
);
1055 return MMSYSERR_NOTENABLED
;
1059 /**************************************************************************
1060 * midStart [internal]
1062 DWORD
midStart(WORD wDevID
)
1064 printf("midStart(%u);\n", wDevID
);
1065 return MMSYSERR_NOTENABLED
;
1069 /**************************************************************************
1070 * midStop [internal]
1072 DWORD
midStop(WORD wDevID
)
1074 printf("midStop(%u);\n", wDevID
);
1075 return MMSYSERR_NOTENABLED
;
1079 /**************************************************************************
1080 * midMessage [sample driver]
1082 DWORD
midMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1083 DWORD dwParam1
, DWORD dwParam2
)
1085 printf("midMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1086 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1089 return midOpen(wDevID
, (LPMIDIOPENDESC
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1091 return midClose(wDevID
);
1092 case MIDM_ADDBUFFER
:
1093 return midAddBuffer(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1095 return midPrepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1096 case MIDM_UNPREPARE
:
1097 return midUnprepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1098 case MIDM_GETDEVCAPS
:
1099 return midGetDevCaps(wDevID
, (LPMIDIINCAPS
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1100 case MIDM_GETNUMDEVS
:
1103 return midReset(wDevID
);
1105 return midStart(wDevID
);
1107 return midStop(wDevID
);
1109 return MMSYSERR_NOTSUPPORTED
;
1114 /*-----------------------------------------------------------------------*/
1117 /**************************************************************************
1118 * modGetDevCaps [internal]
1120 DWORD
modGetDevCaps(WORD wDevID
, LPMIDIOUTCAPS lpCaps
, DWORD dwSize
)
1122 printf("modGetDevCaps(%u, %p, %08lX);\n", wDevID
, lpCaps
, dwSize
);
1123 return MMSYSERR_NOTENABLED
;
1127 /**************************************************************************
1128 * modOpen [internal]
1130 DWORD
modOpen(WORD wDevID
, LPMIDIOPENDESC lpDesc
, DWORD dwFlags
)
1134 dprintf_midi(stddeb
,
1135 "modOpen(%u, %p, %08lX);\n", wDevID
, lpDesc
, dwFlags
);
1136 if (lpDesc
== NULL
) {
1137 fprintf(stderr
,"Linux 'modOpen' // Invalid Parameter !\n");
1138 return MMSYSERR_INVALPARAM
;
1140 if (wDevID
>= MAX_MIDIOUTDRV
) {
1141 fprintf(stderr
,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1142 return MMSYSERR_ALLOCATED
;
1144 MidiOutDev
[wDevID
].unixdev
= 0;
1145 midi
= open (MIDI_DEV
, O_WRONLY
, 0);
1147 fprintf(stderr
,"Linux 'modOpen' // can't open !\n");
1148 return MMSYSERR_NOTENABLED
;
1150 MidiOutDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
1151 switch(MidiOutDev
[wDevID
].wFlags
) {
1153 fprintf(stderr
,"Linux 'modOpen' // CALLBACK_NULL !\n");
1156 dprintf_midi(stddeb
,
1157 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1160 dprintf_midi(stddeb
,
1161 "Linux 'modOpen' // CALLBACK_TASK !\n");
1164 dprintf_midi(stddeb
,
1165 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1168 MidiOutDev
[wDevID
].lpQueueHdr
= NULL
;
1169 MidiOutDev
[wDevID
].unixdev
= midi
;
1170 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1171 MidiOutDev
[wDevID
].bufsize
= 0x3FFF;
1172 if (MIDI_NotifyClient(wDevID
, MOM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
1173 fprintf(stderr
,"Linux 'modOpen' // can't notify client !\n");
1174 return MMSYSERR_INVALPARAM
;
1176 dprintf_midi(stddeb
,
1177 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi
);
1178 return MMSYSERR_NOERROR
;
1180 return MMSYSERR_NOTENABLED
;
1185 /**************************************************************************
1186 * modClose [internal]
1188 DWORD
modClose(WORD wDevID
)
1191 dprintf_midi(stddeb
,"modClose(%u);\n", wDevID
);
1192 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1193 fprintf(stderr
,"Linux 'modClose' // can't close !\n");
1194 return MMSYSERR_NOTENABLED
;
1196 close(MidiOutDev
[wDevID
].unixdev
);
1197 MidiOutDev
[wDevID
].unixdev
= 0;
1198 MidiOutDev
[wDevID
].bufsize
= 0;
1199 if (MIDI_NotifyClient(wDevID
, MOM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1200 fprintf(stderr
,"Linux 'modClose' // can't notify client !\n");
1201 return MMSYSERR_INVALPARAM
;
1203 return MMSYSERR_NOERROR
;
1205 return MMSYSERR_NOTENABLED
;
1209 /**************************************************************************
1210 * modData [internal]
1212 DWORD
modData(WORD wDevID
, DWORD dwParam
)
1216 dprintf_midi(stddeb
,
1217 "modData(%u, %08lX);\n", wDevID
, dwParam
);
1218 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1219 fprintf(stderr
,"Linux 'modData' // can't play !\n");
1220 return MIDIERR_NODEVICE
;
1222 event
= LOWORD(dwParam
);
1223 if (write (MidiOutDev
[wDevID
].unixdev
,
1224 &event
, sizeof(WORD
)) != sizeof(WORD
)) {
1225 dprintf_midi(stddeb
,
1226 "modData() // error writting unixdev !\n");
1228 return MMSYSERR_NOTENABLED
;
1230 return MMSYSERR_NOTENABLED
;
1234 /**************************************************************************
1235 * modLongData [internal]
1237 DWORD
modLongData(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1242 dprintf_midi(stddeb
,
1243 "modLongData(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1244 printf("modLongData(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1245 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1246 fprintf(stderr
,"Linux 'modLongData' // can't play !\n");
1247 return MIDIERR_NODEVICE
;
1249 if (lpMidiHdr
->lpData
== NULL
) return MIDIERR_UNPREPARED
;
1250 if (!(lpMidiHdr
->dwFlags
& MHDR_PREPARED
)) return MIDIERR_UNPREPARED
;
1251 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1252 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1253 lpMidiHdr
->dwFlags
|= MHDR_INQUEUE
;
1254 dprintf_midi(stddeb
,
1255 "modLongData() // dwBytesRecorded %lu !\n", lpMidiHdr
->dwBytesRecorded
);
1257 count = write (MidiOutDev[wDevID].unixdev,
1258 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1260 ptr
= (LPWORD
)lpMidiHdr
->lpData
;
1261 for (count
= 0; count
< lpMidiHdr
->dwBytesRecorded
; count
++) {
1262 if (write (MidiOutDev
[wDevID
].unixdev
, ptr
,
1263 sizeof(WORD
)) != sizeof(WORD
)) break;
1266 if (count
!= lpMidiHdr
->dwBytesRecorded
) {
1267 dprintf_midi(stddeb
,
1268 "modLongData() // error writting unixdev #%d ! (%d != %ld)\n",
1269 MidiOutDev
[wDevID
].unixdev
, count
, lpMidiHdr
->dwBytesRecorded
);
1270 return MMSYSERR_NOTENABLED
;
1272 lpMidiHdr
->dwFlags
&= ~MHDR_INQUEUE
;
1273 lpMidiHdr
->dwFlags
|= MHDR_DONE
;
1274 if (MIDI_NotifyClient(wDevID
, MOM_DONE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1275 fprintf(stderr
,"Linux 'modLongData' // can't notify client !\n");
1276 return MMSYSERR_INVALPARAM
;
1278 return MMSYSERR_NOERROR
;
1280 return MMSYSERR_NOTENABLED
;
1284 /**************************************************************************
1285 * modPrepare [internal]
1287 DWORD
modPrepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1290 dprintf_midi(stddeb
,
1291 "modPrepare(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1292 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1293 fprintf(stderr
,"Linux 'modPrepare' // can't prepare !\n");
1294 return MMSYSERR_NOTENABLED
;
1296 if (MidiOutDev
[wDevID
].lpQueueHdr
!= NULL
) {
1297 fprintf(stderr
,"Linux 'modPrepare' // already prepare !\n");
1298 return MMSYSERR_NOTENABLED
;
1300 MidiOutDev
[wDevID
].dwTotalPlayed
= 0;
1301 MidiOutDev
[wDevID
].lpQueueHdr
= lpMidiHdr
;
1302 if (lpMidiHdr
->dwFlags
& MHDR_INQUEUE
) return MIDIERR_STILLPLAYING
;
1303 lpMidiHdr
->dwFlags
|= MHDR_PREPARED
;
1304 lpMidiHdr
->dwFlags
&= ~MHDR_DONE
;
1305 return MMSYSERR_NOERROR
;
1307 return MMSYSERR_NOTENABLED
;
1311 /**************************************************************************
1312 * modUnprepare [internal]
1314 DWORD
modUnprepare(WORD wDevID
, LPMIDIHDR lpMidiHdr
, DWORD dwSize
)
1317 dprintf_midi(stddeb
,
1318 "modUnprepare(%u, %p, %08lX);\n", wDevID
, lpMidiHdr
, dwSize
);
1319 if (MidiOutDev
[wDevID
].unixdev
== 0) {
1320 fprintf(stderr
,"Linux 'modUnprepare' // can't unprepare !\n");
1321 return MMSYSERR_NOTENABLED
;
1323 return MMSYSERR_NOERROR
;
1325 return MMSYSERR_NOTENABLED
;
1329 /**************************************************************************
1330 * modReset [internal]
1332 DWORD
modReset(WORD wDevID
)
1334 printf("modReset(%u);\n", wDevID
);
1335 return MMSYSERR_NOTENABLED
;
1339 /**************************************************************************
1340 * modGetPosition [internal]
1342 DWORD
modGetPosition(WORD wDevID
, LPMMTIME lpTime
, DWORD uSize
)
1344 printf("modGetposition(%u, %p, %08lX);\n", wDevID
, lpTime
, uSize
);
1345 return MMSYSERR_NOTENABLED
;
1349 /**************************************************************************
1350 * modMessage [sample driver]
1352 DWORD
modMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1353 DWORD dwParam1
, DWORD dwParam2
)
1355 printf("modMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1356 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1359 return modOpen(wDevID
, (LPMIDIOPENDESC
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1361 return modClose(wDevID
);
1363 return modData(wDevID
, dwParam1
);
1365 return modLongData(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1367 return modPrepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1368 case MODM_UNPREPARE
:
1369 return modUnprepare(wDevID
, (LPMIDIHDR
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1370 case MODM_GETDEVCAPS
:
1371 return modGetDevCaps(wDevID
, (LPMIDIOUTCAPS
)PTR_SEG_TO_LIN(dwParam1
), dwParam2
);
1372 case MODM_GETNUMDEVS
:
1374 case MODM_GETVOLUME
:
1376 case MODM_SETVOLUME
:
1379 return modReset(wDevID
);
1381 return MMSYSERR_NOTSUPPORTED
;
1385 /*-----------------------------------------------------------------------*/
1387 #endif /* #ifdef BUILTIN_MMSYSTEM */