Release 950727
[wine/multimedia.git] / multimedia / midi.c
blobfaa61b5c8b52e95765413af93f206dd7db3a5a7a
1 /*
2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
5 */
7 #ifndef WINELIB
8 #define BUILTIN_MMSYSTEM
9 #endif
11 #ifdef BUILTIN_MMSYSTEM
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <sys/ioctl.h>
18 #include "windows.h"
19 #include "ldt.h"
20 #include "driver.h"
21 #include "mmsystem.h"
23 #include "stddebug.h"
24 #include "debug.h"
26 #ifdef linux
27 #include <linux/soundcard.h>
28 #endif
30 #ifdef linux
31 #define MIDI_DEV "/dev/sequencer"
33 #ifdef SOUND_VERSION
34 #define IOCTL(a,b,c) ioctl(a,b,&c)
35 #else
36 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
37 #endif
39 #define MAX_MIDIINDRV 2
40 #define MAX_MIDIOUTDRV 2
41 #define MAX_MCIMIDIDRV 2
43 typedef struct {
44 int unixdev;
45 int state;
46 DWORD bufsize;
47 MIDIOPENDESC midiDesc;
48 WORD wFlags;
49 LPMIDIHDR lpQueueHdr;
50 DWORD dwTotalPlayed;
51 } LINUX_MIDIIN;
53 typedef struct {
54 int unixdev;
55 int state;
56 DWORD bufsize;
57 MIDIOPENDESC midiDesc;
58 WORD wFlags;
59 LPMIDIHDR lpQueueHdr;
60 DWORD dwTotalPlayed;
61 } LINUX_MIDIOUT;
63 typedef struct {
64 int nUseCount; /* Incremented for each shared open */
65 BOOL fShareable; /* TRUE if first open was shareable */
66 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
67 HANDLE hCallback; /* Callback handle for pending notification */
68 HMMIO hFile; /* mmio file handle open as Element */
69 DWORD dwBeginData;
70 DWORD dwTotalLen;
71 WORD wFormat;
72 WORD nTracks;
73 WORD nTempo;
74 MCI_OPEN_PARMS openParms;
75 MIDIHDR MidiHdr;
76 WORD dwStatus;
77 } LINUX_MCIMIDI;
79 static LINUX_MIDIIN MidiInDev[MAX_MIDIINDRV];
80 static LINUX_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
81 static LINUX_MCIMIDI MCIMidiDev[MAX_MCIMIDIDRV];
82 #endif
85 /**************************************************************************
86 * MIDI_NotifyClient [internal]
88 static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
89 DWORD dwParam1, DWORD dwParam2)
91 #ifdef linux
92 if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
93 MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags,
94 MidiInDev[wDevID].midiDesc.hMidi, wMsg,
95 MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
96 dprintf_midi(stddeb, "MIDI_NotifyClient // can't notify client !\n");
97 return MMSYSERR_NOERROR;
99 return 0;
100 #else
101 return MMSYSERR_NOTENABLED;
102 #endif
106 /**************************************************************************
107 * MIDI_ReadByte [internal]
109 static DWORD MIDI_ReadByte(UINT wDevID, BYTE FAR *lpbyt)
111 #ifdef linux
112 if (lpbyt != NULL) {
113 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
114 (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
115 return 0;
118 dprintf_midi(stddeb, "MIDI_ReadByte // error reading wDevID=%d \n", wDevID);
119 return MCIERR_INTERNAL;
121 #else
122 return MMSYSERR_NOTENABLED;
123 #endif
127 /**************************************************************************
128 * MIDI_ReadWord [internal]
130 static DWORD MIDI_ReadWord(UINT wDevID, LPWORD lpw)
132 BYTE hibyte, lobyte;
133 if (lpw != NULL) {
134 if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
135 if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
136 *lpw = ((WORD)hibyte << 8) + lobyte;
137 return 0;
141 dprintf_midi(stddeb, "MIDI_ReadWord // error reading wDevID=%d \n", wDevID);
142 return MCIERR_INTERNAL;
146 /**************************************************************************
147 * MIDI_ReadLong [internal]
149 static DWORD MIDI_ReadLong(UINT wDevID, LPDWORD lpdw)
151 WORD hiword, loword;
152 if (lpdw != NULL) {
153 if (MIDI_ReadWord(wDevID, &hiword) == 0) {
154 if (MIDI_ReadWord(wDevID, &loword) == 0) {
155 *lpdw = MAKELONG(loword, hiword);
156 return 0;
160 dprintf_midi(stddeb, "MIDI_ReadLong // error reading wDevID=%d \n", wDevID);
161 return MCIERR_INTERNAL;
165 /**************************************************************************
166 * MIDI_ReadVaryLen [internal]
168 static DWORD MIDI_ReadVaryLen(UINT wDevID, LPDWORD lpdw)
170 BYTE byte;
171 DWORD value;
172 if (lpdw == NULL) return MCIERR_INTERNAL;
173 if (MIDI_ReadByte(wDevID, &byte) != 0) {
174 dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
175 return MCIERR_INTERNAL;
177 value = (DWORD)(byte & 0x7F);
178 while (byte & 0x80) {
179 if (MIDI_ReadByte(wDevID, &byte) != 0) {
180 dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
181 return MCIERR_INTERNAL;
183 value = (value << 7) + (byte & 0x7F);
185 *lpdw = value;
187 dprintf_midi(stddeb, "MIDI_ReadVaryLen // val=%08lX \n", value);
189 return 0;
193 /**************************************************************************
194 * MIDI_ReadMThd [internal]
196 static DWORD MIDI_ReadMThd(UINT wDevID, DWORD dwOffset)
198 #ifdef linux
199 DWORD toberead;
200 FOURCC fourcc;
201 dprintf_midi(stddeb, "MIDI_ReadMThd(%04X, %08lX);\n", wDevID, dwOffset);
202 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
203 dprintf_midi(stddeb, "MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset);
204 return MCIERR_INTERNAL;
206 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
207 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
208 return MCIERR_INTERNAL;
210 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
211 return MCIERR_INTERNAL;
213 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0) {
214 return MCIERR_INTERNAL;
216 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0) {
217 return MCIERR_INTERNAL;
219 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0) {
220 return MCIERR_INTERNAL;
222 dprintf_midi(stddeb, "MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
223 toberead, MCIMidiDev[wDevID].wFormat,
224 MCIMidiDev[wDevID].nTracks,
225 MCIMidiDev[wDevID].nTempo);
226 toberead -= 3 * sizeof(WORD);
228 ntrks = read16bit ();
229 Mf_division = division = read16bit ();
231 return 0;
233 #else
234 return MMSYSERR_NOTENABLED;
235 #endif
239 static DWORD MIDI_ReadMTrk(UINT wDevID, DWORD dwOffset)
241 #ifdef linux
242 DWORD toberead;
243 FOURCC fourcc;
244 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
245 dprintf_midi(stddeb, "MIDI_ReadMTrk // can't seek at %08lX begin of 'MThd' \n", dwOffset);
247 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
248 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
249 return MCIERR_INTERNAL;
251 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
252 return MCIERR_INTERNAL;
254 dprintf_midi(stddeb, "MIDI_ReadMTrk // toberead=%08lX\n", toberead);
255 toberead -= 3 * sizeof(WORD);
256 MCIMidiDev[wDevID].dwTotalLen = toberead;
257 return 0;
258 #else
259 return MMSYSERR_NOTENABLED;
260 #endif
264 /**************************************************************************
265 * MIDI_mciOpen [internal]
267 static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
269 #ifdef linux
270 MIDIOPENDESC MidiDesc;
271 DWORD dwRet;
272 DWORD dwOffset;
273 LPSTR lpstrElementName;
274 char str[128];
276 dprintf_midi(stddeb, "MIDI_mciOpen(%08lX, %p)\n", dwFlags, lpParms);
277 if (lpParms == NULL) return MCIERR_INTERNAL;
278 if (MCIMidiDev[wDevID].nUseCount > 0) {
279 /* The driver already open on this channel */
280 /* If the driver was opened shareable before and this open specifies */
281 /* shareable then increment the use count */
282 if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
283 ++MCIMidiDev[wDevID].nUseCount;
284 else
285 return MCIERR_MUST_USE_SHAREABLE;
287 else {
288 MCIMidiDev[wDevID].nUseCount = 1;
289 MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
291 dprintf_midi(stddeb, "MIDI_mciOpen // wDevID=%04X\n", wDevID);
292 lpParms->wDeviceID = wDevID;
293 dprintf_midi(stddeb, "MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms->wDeviceID);
294 dprintf_midi(stddeb, "MIDI_mciOpen // before OPEN_ELEMENT\n");
295 if (dwFlags & MCI_OPEN_ELEMENT) {
296 lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
297 dprintf_midi(stddeb, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
298 /* dprintf_midi(stddeb, "MIDI_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
299 if (strlen(lpstrElementName) > 0) {
300 strcpy(str, lpstrElementName);
301 AnsiUpper(str);
302 MCIMidiDev[wDevID].hFile = mmioOpen(str, NULL,
303 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
304 if (MCIMidiDev[wDevID].hFile == 0) {
305 dprintf_midi(stddeb, "MIDI_mciOpen // can't find file='%s' !\n", str);
306 return MCIERR_FILE_NOT_FOUND;
309 else
310 MCIMidiDev[wDevID].hFile = 0;
312 dprintf_midi(stddeb, "MIDI_mciOpen // hFile=%u\n", MCIMidiDev[wDevID].hFile);
313 memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
314 MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
315 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
316 MCIMidiDev[wDevID].dwBeginData = 0;
317 MCIMidiDev[wDevID].dwTotalLen = 0;
318 MidiDesc.hMidi = 0;
319 if (MCIMidiDev[wDevID].hFile != 0) {
320 MMCKINFO ckMainRIFF;
321 if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
322 return MCIERR_INTERNAL;
324 dprintf_midi(stddeb,"MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
325 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
326 ckMainRIFF.cksize);
327 dwOffset = 0;
328 if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
329 dprintf_midi(stddeb, "MIDI_mciOpen // is a 'RMID' file \n");
330 dwOffset = ckMainRIFF.dwDataOffset;
332 if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
333 dprintf_midi(stddeb, "MIDI_mciOpen // unknown format !\n");
334 return MCIERR_INTERNAL;
336 if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
337 dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MThd' header \n");
338 return MCIERR_INTERNAL;
340 dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
341 if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
342 dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MTrk' header \n");
343 return MCIERR_INTERNAL;
345 dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
346 MCIMidiDev[wDevID].dwBeginData = dwOffset;
347 dprintf_midi(stddeb, "MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
348 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
349 ckMainRIFF.cksize);
351 dwRet = modMessage(0, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
352 dwRet = midMessage(0, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
353 return 0;
354 #else
355 return MMSYSERR_NOTENABLED;
356 #endif
360 /**************************************************************************
361 * MIDI_mciStop [internal]
363 static DWORD MIDI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
365 #ifdef linux
366 dprintf_midi(stddeb, "MIDI_mciStop(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
367 if (lpParms == NULL) return MCIERR_INTERNAL;
368 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
369 dprintf_midi(stddeb, "MIDI_mciStop // MCIMidiDev[wDevID].dwStatus=%p %d\n",
370 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
371 return 0;
372 #else
373 return MCIERR_INTERNAL;
374 #endif
378 /**************************************************************************
379 * MIDI_mciClose [internal]
381 static DWORD MIDI_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
383 #ifdef linux
384 DWORD dwRet;
385 dprintf_midi(stddeb, "MIDI_mciClose(%u, %08lX, %p);\n", wDevID, dwParam, lpParms);
386 if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
387 MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
389 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
390 MCIMidiDev[wDevID].nUseCount--;
391 if (MCIMidiDev[wDevID].nUseCount == 0) {
392 if (MCIMidiDev[wDevID].hFile != 0) {
393 mmioClose(MCIMidiDev[wDevID].hFile, 0);
394 MCIMidiDev[wDevID].hFile = 0;
395 dprintf_midi(stddeb, "MIDI_mciClose // hFile closed !\n");
397 dwRet = modMessage(0, MODM_CLOSE, 0, 0L, 0L);
398 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
399 dwRet = midMessage(0, MIDM_CLOSE, 0, 0L, 0L);
400 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
402 return 0;
403 #else
404 return 0;
405 #endif
409 /**************************************************************************
410 * MIDI_mciPlay [internal]
412 static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
414 #ifdef linux
415 int count;
416 int start, end;
417 LPMIDIHDR lpMidiHdr;
418 DWORD dwData;
419 LPWORD ptr;
420 DWORD dwRet;
421 dprintf_midi(stddeb, "MIDI_mciPlay(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
422 if (MCIMidiDev[wDevID].hFile == 0) {
423 dprintf_midi(stddeb, "MIDI_mciPlay // can't find file='%s' !\n",
424 MCIMidiDev[wDevID].openParms.lpstrElementName);
425 return MCIERR_FILE_NOT_FOUND;
427 start = 1; end = 99999;
428 if (dwFlags & MCI_FROM) {
429 start = lpParms->dwFrom;
430 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_FROM=%d \n", start);
432 if (dwFlags & MCI_TO) {
433 end = lpParms->dwTo;
434 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_TO=%d \n", end);
436 #if 0
437 if (dwFlags & MCI_NOTIFY) {
438 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
439 switch(fork()) {
440 case -1:
441 dprintf_midi(stddeb, "MIDI_mciPlay // Can't 'fork' process !\n");
442 break;
443 case 0:
444 dprintf_midi(stddeb, "MIDI_mciPlay // process started ! play in background ...\n");
445 break;
446 default:
447 dprintf_midi(stddeb, "MIDI_mciPlay // process started ! return to caller...\n");
448 return 0;
451 #endif
452 lpMidiHdr = &MCIMidiDev[wDevID].MidiHdr;
453 lpMidiHdr->lpData = (LPSTR) malloc(1200);
454 if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
455 lpMidiHdr->dwBufferLength = 1024;
456 lpMidiHdr->dwUser = 0L;
457 lpMidiHdr->dwFlags = 0L;
458 dwRet = modMessage(0, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
459 /* dprintf_midi(stddeb, "MIDI_mciPlay // after MODM_PREPARE \n"); */
460 MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
461 while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
462 dprintf_midi(stddeb, "MIDI_mciPlay // MCIMidiDev[wDevID].dwStatus=%p %d\n",
463 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
464 ptr = (LPWORD)lpMidiHdr->lpData;
465 for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
466 if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
467 *ptr = LOWORD(dwData);
470 count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
472 if (count < 1) break;
473 lpMidiHdr->dwBytesRecorded = count;
474 dprintf_midi(stddeb, "MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
475 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
476 dwRet = modMessage(0, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
478 dwRet = modMessage(0, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
479 if (lpMidiHdr->lpData != NULL) {
480 free(lpMidiHdr->lpData);
481 lpMidiHdr->lpData = NULL;
483 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
484 if (dwFlags & MCI_NOTIFY) {
485 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
486 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
487 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
488 exit(1);
490 return 0;
491 #else
492 return MMSYSERR_NOTENABLED;
493 #endif
497 /**************************************************************************
498 * MIDI_mciRecord [internal]
500 static DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
502 #ifdef linux
503 int start, end;
504 LPMIDIHDR lpMidiHdr;
505 DWORD dwRet;
507 dprintf_midi(stddeb, "MIDI_mciRecord(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
508 if (MCIMidiDev[wDevID].hFile == 0) {
509 dprintf_midi(stddeb, "MIDI_mciRecord // can't find file='%s' !\n",
510 MCIMidiDev[wDevID].openParms.lpstrElementName);
511 return MCIERR_FILE_NOT_FOUND;
513 start = 1; end = 99999;
514 if (dwFlags & MCI_FROM) {
515 start = lpParms->dwFrom;
516 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_FROM=%d \n", start);
518 if (dwFlags & MCI_TO) {
519 end = lpParms->dwTo;
520 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_TO=%d \n", end);
522 lpMidiHdr = &MCIMidiDev[wDevID].MidiHdr;
523 lpMidiHdr->lpData = (LPSTR) malloc(1200);
524 lpMidiHdr->dwBufferLength = 1024;
525 lpMidiHdr->dwUser = 0L;
526 lpMidiHdr->dwFlags = 0L;
527 dwRet = midMessage(0, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
528 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_PREPARE \n");
529 MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
530 while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
531 dprintf_midi(stddeb, "MIDI_mciRecord // MCIMidiDev[wDevID].dwStatus=%p %d\n",
532 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
533 lpMidiHdr->dwBytesRecorded = 0;
534 dwRet = midMessage(0, MIDM_START, 0, 0L, 0L);
535 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
536 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
537 if (lpMidiHdr->dwBytesRecorded == 0) break;
539 dprintf_midi(stddeb, "MIDI_mciRecord // before MIDM_UNPREPARE \n");
540 dwRet = midMessage(0, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
541 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_UNPREPARE \n");
542 if (lpMidiHdr->lpData != NULL) {
543 free(lpMidiHdr->lpData);
544 lpMidiHdr->lpData = NULL;
546 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
547 if (dwFlags & MCI_NOTIFY) {
548 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
549 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
550 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
552 return 0;
553 #else
554 return MMSYSERR_NOTENABLED;
555 #endif
559 /**************************************************************************
560 * MIDI_mciPause [internal]
562 static DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
564 #ifdef linux
565 dprintf_midi(stddeb, "MIDI_mciPause(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
566 if (lpParms == NULL) return MCIERR_INTERNAL;
567 return 0;
568 #else
569 return MCIERR_INTERNAL;
570 #endif
574 /**************************************************************************
575 * MIDI_mciResume [internal]
577 static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
579 #ifdef linux
580 dprintf_midi(stddeb, "MIDI_mciResume(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
581 if (lpParms == NULL) return MCIERR_INTERNAL;
582 return 0;
583 #else
584 return MCIERR_INTERNAL;
585 #endif
589 /**************************************************************************
590 * MIDI_mciSet [internal]
592 static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
594 #ifdef linux
595 dprintf_midi(stddeb, "MIDI_mciSet(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
596 if (lpParms == NULL) return MCIERR_INTERNAL;
597 dprintf_midi(stddeb, "MIDI_mciSet // dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
598 dprintf_midi(stddeb, "MIDI_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
599 if (dwFlags & MCI_SET_TIME_FORMAT) {
600 switch (lpParms->dwTimeFormat) {
601 case MCI_FORMAT_MILLISECONDS:
602 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
603 break;
604 case MCI_FORMAT_BYTES:
605 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
606 break;
607 case MCI_FORMAT_SAMPLES:
608 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
609 break;
610 default:
611 dprintf_midi(stddeb, "MIDI_mciSet // bad time format !\n");
612 return MCIERR_BAD_TIME_FORMAT;
615 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
616 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
617 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
618 if (dwFlags & MCI_SET_AUDIO) {
619 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO !\n");
621 if (dwFlags && MCI_SET_ON) {
622 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_ON !\n");
623 if (dwFlags && MCI_SET_AUDIO_LEFT) {
624 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
626 if (dwFlags && MCI_SET_AUDIO_RIGHT) {
627 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
630 if (dwFlags & MCI_SET_OFF) {
631 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_OFF !\n");
633 if (dwFlags & MCI_SEQ_SET_MASTER) {
634 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
636 if (dwFlags & MCI_SEQ_SET_SLAVE) {
637 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
639 if (dwFlags & MCI_SEQ_SET_OFFSET) {
640 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
642 if (dwFlags & MCI_SEQ_SET_PORT) {
643 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
645 if (dwFlags & MCI_SEQ_SET_TEMPO) {
646 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
648 return 0;
649 #else
650 return MCIERR_INTERNAL;
651 #endif
655 /**************************************************************************
656 * MIDI_mciStatus [internal]
658 static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
660 #ifdef linux
661 dprintf_midi(stddeb, "MIDI_mciStatus(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
662 if (lpParms == NULL) return MCIERR_INTERNAL;
663 if (dwFlags & MCI_STATUS_ITEM) {
664 switch(lpParms->dwItem) {
665 case MCI_STATUS_CURRENT_TRACK:
666 lpParms->dwReturn = 1;
667 break;
668 case MCI_STATUS_LENGTH:
669 lpParms->dwReturn = 5555;
670 if (dwFlags & MCI_TRACK) {
671 lpParms->dwTrack = 1;
672 lpParms->dwReturn = 2222;
674 break;
675 case MCI_STATUS_MODE:
676 lpParms->dwReturn = MCI_MODE_STOP;
677 break;
678 case MCI_STATUS_MEDIA_PRESENT:
679 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
680 lpParms->dwReturn = TRUE;
681 break;
682 case MCI_STATUS_NUMBER_OF_TRACKS:
683 lpParms->dwReturn = 1;
684 break;
685 case MCI_STATUS_POSITION:
686 lpParms->dwReturn = 3333;
687 if (dwFlags & MCI_STATUS_START) {
688 lpParms->dwItem = 1;
690 if (dwFlags & MCI_TRACK) {
691 lpParms->dwTrack = 1;
692 lpParms->dwReturn = 777;
694 break;
695 case MCI_STATUS_READY:
696 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_READY !\n");
697 lpParms->dwReturn = TRUE;
698 break;
699 case MCI_STATUS_TIME_FORMAT:
700 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
701 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
702 break;
703 case MCI_SEQ_STATUS_DIVTYPE:
704 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
705 lpParms->dwReturn = 0;
706 break;
707 case MCI_SEQ_STATUS_MASTER:
708 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
709 lpParms->dwReturn = 0;
710 break;
711 case MCI_SEQ_STATUS_SLAVE:
712 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
713 lpParms->dwReturn = 0;
714 break;
715 case MCI_SEQ_STATUS_OFFSET:
716 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
717 lpParms->dwReturn = 0;
718 break;
719 case MCI_SEQ_STATUS_PORT:
720 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
721 lpParms->dwReturn = 0;
722 break;
723 case MCI_SEQ_STATUS_TEMPO:
724 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
725 lpParms->dwReturn = 0;
726 break;
727 default:
728 dprintf_midi(stddeb, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms->dwItem);
729 return MCIERR_UNRECOGNIZED_COMMAND;
732 if (dwFlags & MCI_NOTIFY) {
733 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
734 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
735 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
737 return 0;
738 #else
739 return MCIERR_INTERNAL;
740 #endif
743 /**************************************************************************
744 * MIDI_mciGetDevCaps [internal]
746 static DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
747 LPMCI_GETDEVCAPS_PARMS lpParms)
749 #ifdef linux
750 dprintf_midi(stddeb, "MIDI_mciGetDevCaps(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
751 if (lpParms == NULL) return MCIERR_INTERNAL;
752 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
753 switch(lpParms->dwItem) {
754 case MCI_GETDEVCAPS_CAN_RECORD:
755 lpParms->dwReturn = TRUE;
756 break;
757 case MCI_GETDEVCAPS_HAS_AUDIO:
758 lpParms->dwReturn = TRUE;
759 break;
760 case MCI_GETDEVCAPS_HAS_VIDEO:
761 lpParms->dwReturn = FALSE;
762 break;
763 case MCI_GETDEVCAPS_DEVICE_TYPE:
764 lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
765 break;
766 case MCI_GETDEVCAPS_USES_FILES:
767 lpParms->dwReturn = TRUE;
768 break;
769 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
770 lpParms->dwReturn = TRUE;
771 break;
772 case MCI_GETDEVCAPS_CAN_EJECT:
773 lpParms->dwReturn = FALSE;
774 break;
775 case MCI_GETDEVCAPS_CAN_PLAY:
776 lpParms->dwReturn = TRUE;
777 break;
778 case MCI_GETDEVCAPS_CAN_SAVE:
779 lpParms->dwReturn = FALSE;
780 break;
781 default:
782 return MCIERR_UNRECOGNIZED_COMMAND;
785 return 0;
786 #else
787 return MCIERR_INTERNAL;
788 #endif
791 /**************************************************************************
792 * MIDI_mciInfo [internal]
794 static DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
796 #ifdef linux
797 dprintf_midi(stddeb, "MIDI_mciInfo(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
798 if (lpParms == NULL) return MCIERR_INTERNAL;
799 lpParms->lpstrReturn = NULL;
800 switch(dwFlags) {
801 case MCI_INFO_PRODUCT:
802 lpParms->lpstrReturn = "Linux Sound System 0.5";
803 break;
804 case MCI_INFO_FILE:
805 lpParms->lpstrReturn = "FileName";
806 break;
807 default:
808 return MCIERR_UNRECOGNIZED_COMMAND;
810 if (lpParms->lpstrReturn != NULL)
811 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
812 else
813 lpParms->dwRetSize = 0;
814 return 0;
815 #else
816 return MCIERR_INTERNAL;
817 #endif
821 /*-----------------------------------------------------------------------*/
824 /**************************************************************************
825 * midGetDevCaps [internal]
827 static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize)
829 dprintf_midi(stddeb, "midGetDevCaps(%u, %p, %08lX);\n", wDevID, lpCaps, dwSize);
830 return MMSYSERR_NOTENABLED;
833 /**************************************************************************
834 * midOpen [internal]
836 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
838 #ifdef linux
839 int midi;
840 dprintf_midi(stddeb,
841 "midOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
842 if (lpDesc == NULL) {
843 dprintf_midi(stddeb,"Linux 'midOpen' // Invalid Parameter !\n");
844 return MMSYSERR_INVALPARAM;
846 if (wDevID >= MAX_MIDIINDRV) {
847 dprintf_midi(stddeb,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
848 return MMSYSERR_ALLOCATED;
850 MidiInDev[wDevID].unixdev = 0;
851 midi = open (MIDI_DEV, O_RDONLY, 0);
852 if (midi == -1) {
853 dprintf_midi(stddeb,"Linux 'midOpen' // can't open !\n");
854 return MMSYSERR_NOTENABLED;
856 MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
857 switch(MidiInDev[wDevID].wFlags) {
858 case DCB_NULL:
859 dprintf_midi(stddeb,"Linux 'midOpen' // CALLBACK_NULL !\n");
860 break;
861 case DCB_WINDOW:
862 dprintf_midi(stddeb,
863 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
864 break;
865 case DCB_TASK:
866 dprintf_midi(stddeb,
867 "Linux 'midOpen' // CALLBACK_TASK !\n");
868 break;
869 case DCB_FUNCTION:
870 dprintf_midi(stddeb,
871 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
872 break;
874 MidiInDev[wDevID].lpQueueHdr = NULL;
875 MidiInDev[wDevID].unixdev = midi;
876 MidiInDev[wDevID].dwTotalPlayed = 0;
877 MidiInDev[wDevID].bufsize = 0x3FFF;
878 if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
879 dprintf_midi(stddeb,"Linux 'midOpen' // can't notify client !\n");
880 return MMSYSERR_INVALPARAM;
882 return MMSYSERR_NOERROR;
883 #else
884 return MMSYSERR_NOTENABLED;
885 #endif
888 /**************************************************************************
889 * midClose [internal]
891 static DWORD midClose(WORD wDevID)
893 #ifdef linux
894 dprintf_midi(stddeb, "midClose(%u);\n", wDevID);
895 if (MidiInDev[wDevID].unixdev == 0) {
896 dprintf_midi(stddeb,"Linux 'midClose' // can't close !\n");
897 return MMSYSERR_NOTENABLED;
899 close(MidiInDev[wDevID].unixdev);
900 MidiInDev[wDevID].unixdev = 0;
901 MidiInDev[wDevID].bufsize = 0;
902 if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
903 dprintf_midi(stddeb,"Linux 'midClose' // can't notify client !\n");
904 return MMSYSERR_INVALPARAM;
906 return MMSYSERR_NOERROR;
907 #else
908 return MMSYSERR_NOTENABLED;
909 #endif
912 /**************************************************************************
913 * midAddBuffer [internal]
915 static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
917 dprintf_midi(stddeb, "midAddBuffer(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
918 return MMSYSERR_NOTENABLED;
921 /**************************************************************************
922 * midPrepare [internal]
924 static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
926 dprintf_midi(stddeb, "midPrepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
927 return MMSYSERR_NOTENABLED;
930 /**************************************************************************
931 * midUnprepare [internal]
933 static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
935 dprintf_midi(stddeb, "midUnprepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
936 return MMSYSERR_NOTENABLED;
939 /**************************************************************************
940 * midReset [internal]
942 static DWORD midReset(WORD wDevID)
944 dprintf_midi(stddeb, "midReset(%u);\n", wDevID);
945 return MMSYSERR_NOTENABLED;
949 /**************************************************************************
950 * midStart [internal]
952 static DWORD midStart(WORD wDevID)
954 dprintf_midi(stddeb, "midStart(%u);\n", wDevID);
955 return MMSYSERR_NOTENABLED;
959 /**************************************************************************
960 * midStop [internal]
962 static DWORD midStop(WORD wDevID)
964 dprintf_midi(stddeb, "midStop(%u);\n", wDevID);
965 return MMSYSERR_NOTENABLED;
969 /**************************************************************************
970 * midMessage [sample driver]
972 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
973 DWORD dwParam1, DWORD dwParam2)
975 dprintf_midi(stddeb, "midMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
976 wDevID, wMsg, dwUser, dwParam1, dwParam2);
977 switch(wMsg) {
978 case MIDM_OPEN:
979 return midOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
980 case MIDM_CLOSE:
981 return midClose(wDevID);
982 case MIDM_ADDBUFFER:
983 return midAddBuffer(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
984 case MIDM_PREPARE:
985 return midPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
986 case MIDM_UNPREPARE:
987 return midUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
988 case MIDM_GETDEVCAPS:
989 return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
990 case MIDM_GETNUMDEVS:
991 return 0;
992 case MIDM_RESET:
993 return midReset(wDevID);
994 case MIDM_START:
995 return midStart(wDevID);
996 case MIDM_STOP:
997 return midStop(wDevID);
999 return MMSYSERR_NOTSUPPORTED;
1004 /*-----------------------------------------------------------------------*/
1007 /**************************************************************************
1008 * modGetDevCaps [internal]
1010 static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize)
1012 dprintf_midi(stddeb, "modGetDevCaps(%u, %p, %08lX);\n", wDevID, lpCaps, dwSize);
1013 return MMSYSERR_NOTENABLED;
1017 /**************************************************************************
1018 * modOpen [internal]
1020 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
1022 #ifdef linux
1023 int midi;
1024 dprintf_midi(stddeb,
1025 "modOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1026 if (lpDesc == NULL) {
1027 dprintf_midi(stddeb,"Linux 'modOpen' // Invalid Parameter !\n");
1028 return MMSYSERR_INVALPARAM;
1030 if (wDevID >= MAX_MIDIOUTDRV) {
1031 dprintf_midi(stddeb,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1032 return MMSYSERR_ALLOCATED;
1034 MidiOutDev[wDevID].unixdev = 0;
1035 midi = open (MIDI_DEV, O_WRONLY, 0);
1036 if (midi == -1) {
1037 dprintf_midi(stddeb,"Linux 'modOpen' // can't open !\n");
1038 return MMSYSERR_NOTENABLED;
1040 MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1041 switch(MidiOutDev[wDevID].wFlags) {
1042 case DCB_NULL:
1043 dprintf_midi(stddeb,"Linux 'modOpen' // CALLBACK_NULL !\n");
1044 break;
1045 case DCB_WINDOW:
1046 dprintf_midi(stddeb,
1047 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1048 break;
1049 case DCB_TASK:
1050 dprintf_midi(stddeb,
1051 "Linux 'modOpen' // CALLBACK_TASK !\n");
1052 break;
1053 case DCB_FUNCTION:
1054 dprintf_midi(stddeb,
1055 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1056 break;
1058 MidiOutDev[wDevID].lpQueueHdr = NULL;
1059 MidiOutDev[wDevID].unixdev = midi;
1060 MidiOutDev[wDevID].dwTotalPlayed = 0;
1061 MidiOutDev[wDevID].bufsize = 0x3FFF;
1062 if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1063 dprintf_midi(stddeb,"Linux 'modOpen' // can't notify client !\n");
1064 return MMSYSERR_INVALPARAM;
1066 dprintf_midi(stddeb,
1067 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi);
1068 return MMSYSERR_NOERROR;
1069 #else
1070 return MMSYSERR_NOTENABLED;
1071 #endif
1075 /**************************************************************************
1076 * modClose [internal]
1078 static DWORD modClose(WORD wDevID)
1080 #ifdef linux
1081 dprintf_midi(stddeb, "modClose(%u);\n", wDevID);
1082 if (MidiOutDev[wDevID].unixdev == 0) {
1083 dprintf_midi(stddeb,"Linux 'modClose' // can't close !\n");
1084 return MMSYSERR_NOTENABLED;
1086 close(MidiOutDev[wDevID].unixdev);
1087 MidiOutDev[wDevID].unixdev = 0;
1088 MidiOutDev[wDevID].bufsize = 0;
1089 if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1090 dprintf_midi(stddeb,"Linux 'modClose' // can't notify client !\n");
1091 return MMSYSERR_INVALPARAM;
1093 return MMSYSERR_NOERROR;
1094 #else
1095 return MMSYSERR_NOTENABLED;
1096 #endif
1099 /**************************************************************************
1100 * modData [internal]
1102 static DWORD modData(WORD wDevID, DWORD dwParam)
1104 #ifdef linux
1105 WORD event;
1106 dprintf_midi(stddeb,
1107 "modData(%u, %08lX);\n", wDevID, dwParam);
1108 if (MidiOutDev[wDevID].unixdev == 0) {
1109 dprintf_midi(stddeb,"Linux 'modData' // can't play !\n");
1110 return MIDIERR_NODEVICE;
1112 event = LOWORD(dwParam);
1113 if (write (MidiOutDev[wDevID].unixdev,
1114 &event, sizeof(WORD)) != sizeof(WORD)) {
1115 dprintf_midi(stddeb,
1116 "modData() // error writting unixdev !\n");
1118 return MMSYSERR_NOTENABLED;
1119 #else
1120 return MMSYSERR_NOTENABLED;
1121 #endif
1124 /**************************************************************************
1125 * modLongData [internal]
1127 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1129 #ifdef linux
1130 int count;
1131 LPWORD ptr;
1132 dprintf_midi(stddeb,
1133 "modLongData(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1134 dprintf_midi(stddeb, "modLongData(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1135 if (MidiOutDev[wDevID].unixdev == 0) {
1136 dprintf_midi(stddeb,"Linux 'modLongData' // can't play !\n");
1137 return MIDIERR_NODEVICE;
1139 if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
1140 if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
1141 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1142 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1143 lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1144 dprintf_midi(stddeb,
1145 "modLongData() // dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
1147 count = write (MidiOutDev[wDevID].unixdev,
1148 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1150 ptr = (LPWORD)lpMidiHdr->lpData;
1151 for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
1152 if (write (MidiOutDev[wDevID].unixdev, ptr,
1153 sizeof(WORD)) != sizeof(WORD)) break;
1154 ptr++;
1156 if (count != lpMidiHdr->dwBytesRecorded) {
1157 dprintf_midi(stddeb,
1158 "modLongData() // error writting unixdev #%d ! (%d != %ld)\n",
1159 MidiOutDev[wDevID].unixdev, count, lpMidiHdr->dwBytesRecorded);
1160 return MMSYSERR_NOTENABLED;
1162 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1163 lpMidiHdr->dwFlags |= MHDR_DONE;
1164 if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
1165 dprintf_midi(stddeb,"Linux 'modLongData' // can't notify client !\n");
1166 return MMSYSERR_INVALPARAM;
1168 return MMSYSERR_NOERROR;
1169 #else
1170 return MMSYSERR_NOTENABLED;
1171 #endif
1174 /**************************************************************************
1175 * modPrepare [internal]
1177 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1179 #ifdef linux
1180 dprintf_midi(stddeb,
1181 "modPrepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1182 if (MidiOutDev[wDevID].unixdev == 0) {
1183 dprintf_midi(stddeb,"Linux 'modPrepare' // can't prepare !\n");
1184 return MMSYSERR_NOTENABLED;
1186 if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
1187 dprintf_midi(stddeb,"Linux 'modPrepare' // already prepare !\n");
1188 return MMSYSERR_NOTENABLED;
1190 MidiOutDev[wDevID].dwTotalPlayed = 0;
1191 MidiOutDev[wDevID].lpQueueHdr = lpMidiHdr;
1192 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1193 lpMidiHdr->dwFlags |= MHDR_PREPARED;
1194 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1195 return MMSYSERR_NOERROR;
1196 #else
1197 return MMSYSERR_NOTENABLED;
1198 #endif
1201 /**************************************************************************
1202 * modUnprepare [internal]
1204 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1206 #ifdef linux
1207 dprintf_midi(stddeb,
1208 "modUnprepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1209 if (MidiOutDev[wDevID].unixdev == 0) {
1210 dprintf_midi(stddeb,"Linux 'modUnprepare' // can't unprepare !\n");
1211 return MMSYSERR_NOTENABLED;
1213 return MMSYSERR_NOERROR;
1214 #else
1215 return MMSYSERR_NOTENABLED;
1216 #endif
1219 /**************************************************************************
1220 * modReset [internal]
1222 static DWORD modReset(WORD wDevID)
1224 dprintf_midi(stddeb, "modReset(%u);\n", wDevID);
1225 return MMSYSERR_NOTENABLED;
1229 /**************************************************************************
1230 * modMessage [sample driver]
1232 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1233 DWORD dwParam1, DWORD dwParam2)
1235 dprintf_midi(stddeb, "modMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1236 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1237 switch(wMsg) {
1238 case MODM_OPEN:
1239 return modOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1240 case MODM_CLOSE:
1241 return modClose(wDevID);
1242 case MODM_DATA:
1243 return modData(wDevID, dwParam1);
1244 case MODM_LONGDATA:
1245 return modLongData(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1246 case MODM_PREPARE:
1247 return modPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1248 case MODM_UNPREPARE:
1249 return modUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1250 case MODM_GETDEVCAPS:
1251 return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1252 case MODM_GETNUMDEVS:
1253 return 1;
1254 case MODM_GETVOLUME:
1255 return 0;
1256 case MODM_SETVOLUME:
1257 return 0;
1258 case MODM_RESET:
1259 return modReset(wDevID);
1261 return MMSYSERR_NOTSUPPORTED;
1265 /**************************************************************************
1266 * MIDI_DriverProc [sample driver]
1268 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
1269 DWORD dwParam1, DWORD dwParam2)
1271 #ifdef linux
1272 switch(wMsg) {
1273 case DRV_LOAD:
1274 return 1;
1275 case DRV_FREE:
1276 return 1;
1277 case DRV_OPEN:
1278 return 1;
1279 case DRV_CLOSE:
1280 return 1;
1281 case DRV_ENABLE:
1282 return 1;
1283 case DRV_DISABLE:
1284 return 1;
1285 case DRV_QUERYCONFIGURE:
1286 return 1;
1287 case DRV_CONFIGURE:
1288 MessageBox(0, "Sample Midi Linux Driver !",
1289 "MMLinux Driver", MB_OK);
1290 return 1;
1291 case DRV_INSTALL:
1292 return DRVCNF_RESTART;
1293 case DRV_REMOVE:
1294 return DRVCNF_RESTART;
1295 case MCI_OPEN_DRIVER:
1296 case MCI_OPEN:
1297 return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
1298 case MCI_CLOSE_DRIVER:
1299 case MCI_CLOSE:
1300 return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1301 case MCI_PLAY:
1302 return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
1303 case MCI_RECORD:
1304 return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
1305 case MCI_STOP:
1306 return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1307 case MCI_SET:
1308 return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
1309 case MCI_PAUSE:
1310 return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1311 case MCI_RESUME:
1312 return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1313 case MCI_STATUS:
1314 return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1315 case MCI_GETDEVCAPS:
1316 return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1317 case MCI_INFO:
1318 return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
1319 default:
1320 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1322 #else
1323 return MMSYSERR_NOTENABLED;
1324 #endif
1328 /*-----------------------------------------------------------------------*/
1330 #endif /* #ifdef BUILTIN_MMSYSTEM */