Release 960506
[wine/multimedia.git] / multimedia / midi.c
blob84a5210f993847acf44340e5b0a2c806c6f2674f
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"
22 #include "xmalloc.h"
24 #include "stddebug.h"
25 #include "debug.h"
27 #ifdef linux
28 #include <linux/soundcard.h>
29 #endif
31 #ifdef linux
32 #define MIDI_DEV "/dev/sequencer"
34 #ifdef SOUND_VERSION
35 #define IOCTL(a,b,c) ioctl(a,b,&c)
36 #else
37 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
38 #endif
40 #define MAX_MIDIINDRV 2
41 #define MAX_MIDIOUTDRV 2
42 #define MAX_MCIMIDIDRV 2
44 typedef struct {
45 int unixdev;
46 int state;
47 DWORD bufsize;
48 MIDIOPENDESC midiDesc;
49 WORD wFlags;
50 LPMIDIHDR lpQueueHdr;
51 DWORD dwTotalPlayed;
52 } LINUX_MIDIIN;
54 typedef struct {
55 int unixdev;
56 int state;
57 DWORD bufsize;
58 MIDIOPENDESC midiDesc;
59 WORD wFlags;
60 LPMIDIHDR lpQueueHdr;
61 DWORD dwTotalPlayed;
62 } LINUX_MIDIOUT;
64 typedef struct {
65 int nUseCount; /* Incremented for each shared open */
66 BOOL fShareable; /* TRUE if first open was shareable */
67 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
68 HANDLE hCallback; /* Callback handle for pending notification */
69 HMMIO hFile; /* mmio file handle open as Element */
70 DWORD dwBeginData;
71 DWORD dwTotalLen;
72 WORD wFormat;
73 WORD nTracks;
74 WORD nTempo;
75 MCI_OPEN_PARMS openParms;
76 MIDIHDR MidiHdr;
77 WORD dwStatus;
78 } LINUX_MCIMIDI;
80 static LINUX_MIDIIN MidiInDev[MAX_MIDIINDRV];
81 static LINUX_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
82 static LINUX_MCIMIDI MCIMidiDev[MAX_MCIMIDIDRV];
83 #endif
86 /**************************************************************************
87 * MIDI_NotifyClient [internal]
89 static DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
90 DWORD dwParam1, DWORD dwParam2)
92 #ifdef linux
93 if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
94 MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags,
95 MidiInDev[wDevID].midiDesc.hMidi, wMsg,
96 MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
97 dprintf_midi(stddeb, "MIDI_NotifyClient // can't notify client !\n");
98 return MMSYSERR_NOERROR;
100 return 0;
101 #else
102 return MMSYSERR_NOTENABLED;
103 #endif
107 /**************************************************************************
108 * MIDI_ReadByte [internal]
110 static DWORD MIDI_ReadByte(UINT wDevID, BYTE *lpbyt)
112 #ifdef linux
113 if (lpbyt != NULL) {
114 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
115 (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
116 return 0;
119 dprintf_midi(stddeb, "MIDI_ReadByte // error reading wDevID=%d \n", wDevID);
120 return MCIERR_INTERNAL;
122 #else
123 return MMSYSERR_NOTENABLED;
124 #endif
128 /**************************************************************************
129 * MIDI_ReadWord [internal]
131 static DWORD MIDI_ReadWord(UINT wDevID, LPWORD lpw)
133 BYTE hibyte, lobyte;
134 if (lpw != NULL) {
135 if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
136 if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
137 *lpw = ((WORD)hibyte << 8) + lobyte;
138 return 0;
142 dprintf_midi(stddeb, "MIDI_ReadWord // error reading wDevID=%d \n", wDevID);
143 return MCIERR_INTERNAL;
147 /**************************************************************************
148 * MIDI_ReadLong [internal]
150 static DWORD MIDI_ReadLong(UINT wDevID, LPDWORD lpdw)
152 WORD hiword, loword;
153 if (lpdw != NULL) {
154 if (MIDI_ReadWord(wDevID, &hiword) == 0) {
155 if (MIDI_ReadWord(wDevID, &loword) == 0) {
156 *lpdw = MAKELONG(loword, hiword);
157 return 0;
161 dprintf_midi(stddeb, "MIDI_ReadLong // error reading wDevID=%d \n", wDevID);
162 return MCIERR_INTERNAL;
166 /**************************************************************************
167 * MIDI_ReadVaryLen [internal]
169 static DWORD MIDI_ReadVaryLen(UINT wDevID, LPDWORD lpdw)
171 BYTE byte;
172 DWORD value;
173 if (lpdw == NULL) return MCIERR_INTERNAL;
174 if (MIDI_ReadByte(wDevID, &byte) != 0) {
175 dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
176 return MCIERR_INTERNAL;
178 value = (DWORD)(byte & 0x7F);
179 while (byte & 0x80) {
180 if (MIDI_ReadByte(wDevID, &byte) != 0) {
181 dprintf_midi(stddeb, "MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
182 return MCIERR_INTERNAL;
184 value = (value << 7) + (byte & 0x7F);
186 *lpdw = value;
188 dprintf_midi(stddeb, "MIDI_ReadVaryLen // val=%08lX \n", value);
190 return 0;
194 /**************************************************************************
195 * MIDI_ReadMThd [internal]
197 static DWORD MIDI_ReadMThd(UINT wDevID, DWORD dwOffset)
199 #ifdef linux
200 DWORD toberead;
201 FOURCC fourcc;
202 dprintf_midi(stddeb, "MIDI_ReadMThd(%04X, %08lX);\n", wDevID, dwOffset);
203 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
204 dprintf_midi(stddeb, "MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset);
205 return MCIERR_INTERNAL;
207 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
208 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
209 return MCIERR_INTERNAL;
211 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
212 return MCIERR_INTERNAL;
214 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0) {
215 return MCIERR_INTERNAL;
217 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0) {
218 return MCIERR_INTERNAL;
220 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0) {
221 return MCIERR_INTERNAL;
223 dprintf_midi(stddeb, "MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
224 toberead, MCIMidiDev[wDevID].wFormat,
225 MCIMidiDev[wDevID].nTracks,
226 MCIMidiDev[wDevID].nTempo);
227 toberead -= 3 * sizeof(WORD);
229 ntrks = read16bit ();
230 Mf_division = division = read16bit ();
232 return 0;
234 #else
235 return MMSYSERR_NOTENABLED;
236 #endif
240 static DWORD MIDI_ReadMTrk(UINT wDevID, DWORD dwOffset)
242 #ifdef linux
243 DWORD toberead;
244 FOURCC fourcc;
245 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
246 dprintf_midi(stddeb, "MIDI_ReadMTrk // can't seek at %08lX begin of 'MThd' \n", dwOffset);
248 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
249 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
250 return MCIERR_INTERNAL;
252 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
253 return MCIERR_INTERNAL;
255 dprintf_midi(stddeb, "MIDI_ReadMTrk // toberead=%08lX\n", toberead);
256 toberead -= 3 * sizeof(WORD);
257 MCIMidiDev[wDevID].dwTotalLen = toberead;
258 return 0;
259 #else
260 return MMSYSERR_NOTENABLED;
261 #endif
265 /**************************************************************************
266 * MIDI_mciOpen [internal]
268 static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
270 #ifdef linux
271 MIDIOPENDESC MidiDesc;
272 DWORD dwRet;
273 DWORD dwOffset;
274 LPSTR lpstrElementName;
275 char str[128];
277 dprintf_midi(stddeb, "MIDI_mciOpen(%08lX, %p)\n", dwFlags, lpParms);
278 if (lpParms == NULL) return MCIERR_INTERNAL;
279 if (MCIMidiDev[wDevID].nUseCount > 0) {
280 /* The driver already open on this channel */
281 /* If the driver was opened shareable before and this open specifies */
282 /* shareable then increment the use count */
283 if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
284 ++MCIMidiDev[wDevID].nUseCount;
285 else
286 return MCIERR_MUST_USE_SHAREABLE;
288 else {
289 MCIMidiDev[wDevID].nUseCount = 1;
290 MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
292 dprintf_midi(stddeb, "MIDI_mciOpen // wDevID=%04X\n", wDevID);
293 lpParms->wDeviceID = wDevID;
294 dprintf_midi(stddeb, "MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms->wDeviceID);
295 dprintf_midi(stddeb, "MIDI_mciOpen // before OPEN_ELEMENT\n");
296 if (dwFlags & MCI_OPEN_ELEMENT) {
297 lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
298 dprintf_midi(stddeb, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
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 #if 0
489 exit(1);
490 #endif
492 return 0;
493 #else
494 return MMSYSERR_NOTENABLED;
495 #endif
499 /**************************************************************************
500 * MIDI_mciRecord [internal]
502 static DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
504 #ifdef linux
505 int start, end;
506 LPMIDIHDR lpMidiHdr;
507 DWORD dwRet;
509 dprintf_midi(stddeb, "MIDI_mciRecord(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
510 if (MCIMidiDev[wDevID].hFile == 0) {
511 dprintf_midi(stddeb, "MIDI_mciRecord // can't find file='%s' !\n",
512 MCIMidiDev[wDevID].openParms.lpstrElementName);
513 return MCIERR_FILE_NOT_FOUND;
515 start = 1; end = 99999;
516 if (dwFlags & MCI_FROM) {
517 start = lpParms->dwFrom;
518 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_FROM=%d \n", start);
520 if (dwFlags & MCI_TO) {
521 end = lpParms->dwTo;
522 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_TO=%d \n", end);
524 lpMidiHdr = &MCIMidiDev[wDevID].MidiHdr;
525 lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
526 lpMidiHdr->dwBufferLength = 1024;
527 lpMidiHdr->dwUser = 0L;
528 lpMidiHdr->dwFlags = 0L;
529 dwRet = midMessage(0, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
530 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_PREPARE \n");
531 MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
532 while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
533 dprintf_midi(stddeb, "MIDI_mciRecord // MCIMidiDev[wDevID].dwStatus=%p %d\n",
534 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
535 lpMidiHdr->dwBytesRecorded = 0;
536 dwRet = midMessage(0, MIDM_START, 0, 0L, 0L);
537 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
538 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
539 if (lpMidiHdr->dwBytesRecorded == 0) break;
541 dprintf_midi(stddeb, "MIDI_mciRecord // before MIDM_UNPREPARE \n");
542 dwRet = midMessage(0, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
543 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_UNPREPARE \n");
544 if (lpMidiHdr->lpData != NULL) {
545 free(lpMidiHdr->lpData);
546 lpMidiHdr->lpData = NULL;
548 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
549 if (dwFlags & MCI_NOTIFY) {
550 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
551 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
552 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
554 return 0;
555 #else
556 return MMSYSERR_NOTENABLED;
557 #endif
561 /**************************************************************************
562 * MIDI_mciPause [internal]
564 static DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
566 #ifdef linux
567 dprintf_midi(stddeb, "MIDI_mciPause(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
568 if (lpParms == NULL) return MCIERR_INTERNAL;
569 return 0;
570 #else
571 return MCIERR_INTERNAL;
572 #endif
576 /**************************************************************************
577 * MIDI_mciResume [internal]
579 static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
581 #ifdef linux
582 dprintf_midi(stddeb, "MIDI_mciResume(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
583 if (lpParms == NULL) return MCIERR_INTERNAL;
584 return 0;
585 #else
586 return MCIERR_INTERNAL;
587 #endif
591 /**************************************************************************
592 * MIDI_mciSet [internal]
594 static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
596 #ifdef linux
597 dprintf_midi(stddeb, "MIDI_mciSet(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
598 if (lpParms == NULL) return MCIERR_INTERNAL;
599 dprintf_midi(stddeb, "MIDI_mciSet // dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
600 dprintf_midi(stddeb, "MIDI_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
601 if (dwFlags & MCI_SET_TIME_FORMAT) {
602 switch (lpParms->dwTimeFormat) {
603 case MCI_FORMAT_MILLISECONDS:
604 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
605 break;
606 case MCI_FORMAT_BYTES:
607 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
608 break;
609 case MCI_FORMAT_SAMPLES:
610 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
611 break;
612 default:
613 dprintf_midi(stddeb, "MIDI_mciSet // bad time format !\n");
614 return MCIERR_BAD_TIME_FORMAT;
617 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
618 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
619 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
620 if (dwFlags & MCI_SET_AUDIO) {
621 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO !\n");
623 if (dwFlags && MCI_SET_ON) {
624 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_ON !\n");
625 if (dwFlags && MCI_SET_AUDIO_LEFT) {
626 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
628 if (dwFlags && MCI_SET_AUDIO_RIGHT) {
629 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
632 if (dwFlags & MCI_SET_OFF) {
633 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_OFF !\n");
635 if (dwFlags & MCI_SEQ_SET_MASTER) {
636 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
638 if (dwFlags & MCI_SEQ_SET_SLAVE) {
639 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
641 if (dwFlags & MCI_SEQ_SET_OFFSET) {
642 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
644 if (dwFlags & MCI_SEQ_SET_PORT) {
645 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
647 if (dwFlags & MCI_SEQ_SET_TEMPO) {
648 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
650 return 0;
651 #else
652 return MCIERR_INTERNAL;
653 #endif
657 /**************************************************************************
658 * MIDI_mciStatus [internal]
660 static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
662 #ifdef linux
663 dprintf_midi(stddeb, "MIDI_mciStatus(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
664 if (lpParms == NULL) return MCIERR_INTERNAL;
665 if (dwFlags & MCI_STATUS_ITEM) {
666 switch(lpParms->dwItem) {
667 case MCI_STATUS_CURRENT_TRACK:
668 lpParms->dwReturn = 1;
669 break;
670 case MCI_STATUS_LENGTH:
671 lpParms->dwReturn = 5555;
672 if (dwFlags & MCI_TRACK) {
673 lpParms->dwTrack = 1;
674 lpParms->dwReturn = 2222;
676 break;
677 case MCI_STATUS_MODE:
678 lpParms->dwReturn = MCI_MODE_STOP;
679 break;
680 case MCI_STATUS_MEDIA_PRESENT:
681 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
682 lpParms->dwReturn = TRUE;
683 break;
684 case MCI_STATUS_NUMBER_OF_TRACKS:
685 lpParms->dwReturn = 1;
686 break;
687 case MCI_STATUS_POSITION:
688 lpParms->dwReturn = 3333;
689 if (dwFlags & MCI_STATUS_START) {
690 lpParms->dwItem = 1;
692 if (dwFlags & MCI_TRACK) {
693 lpParms->dwTrack = 1;
694 lpParms->dwReturn = 777;
696 break;
697 case MCI_STATUS_READY:
698 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_READY !\n");
699 lpParms->dwReturn = TRUE;
700 break;
701 case MCI_STATUS_TIME_FORMAT:
702 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
703 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
704 break;
705 case MCI_SEQ_STATUS_DIVTYPE:
706 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
707 lpParms->dwReturn = 0;
708 break;
709 case MCI_SEQ_STATUS_MASTER:
710 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
711 lpParms->dwReturn = 0;
712 break;
713 case MCI_SEQ_STATUS_SLAVE:
714 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
715 lpParms->dwReturn = 0;
716 break;
717 case MCI_SEQ_STATUS_OFFSET:
718 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
719 lpParms->dwReturn = 0;
720 break;
721 case MCI_SEQ_STATUS_PORT:
722 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
723 lpParms->dwReturn = 0;
724 break;
725 case MCI_SEQ_STATUS_TEMPO:
726 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
727 lpParms->dwReturn = 0;
728 break;
729 default:
730 dprintf_midi(stddeb, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms->dwItem);
731 return MCIERR_UNRECOGNIZED_COMMAND;
734 if (dwFlags & MCI_NOTIFY) {
735 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
736 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
737 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
739 return 0;
740 #else
741 return MCIERR_INTERNAL;
742 #endif
745 /**************************************************************************
746 * MIDI_mciGetDevCaps [internal]
748 static DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
749 LPMCI_GETDEVCAPS_PARMS lpParms)
751 #ifdef linux
752 dprintf_midi(stddeb, "MIDI_mciGetDevCaps(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
753 if (lpParms == NULL) return MCIERR_INTERNAL;
754 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
755 switch(lpParms->dwItem) {
756 case MCI_GETDEVCAPS_CAN_RECORD:
757 lpParms->dwReturn = TRUE;
758 break;
759 case MCI_GETDEVCAPS_HAS_AUDIO:
760 lpParms->dwReturn = TRUE;
761 break;
762 case MCI_GETDEVCAPS_HAS_VIDEO:
763 lpParms->dwReturn = FALSE;
764 break;
765 case MCI_GETDEVCAPS_DEVICE_TYPE:
766 lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
767 break;
768 case MCI_GETDEVCAPS_USES_FILES:
769 lpParms->dwReturn = TRUE;
770 break;
771 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
772 lpParms->dwReturn = TRUE;
773 break;
774 case MCI_GETDEVCAPS_CAN_EJECT:
775 lpParms->dwReturn = FALSE;
776 break;
777 case MCI_GETDEVCAPS_CAN_PLAY:
778 lpParms->dwReturn = TRUE;
779 break;
780 case MCI_GETDEVCAPS_CAN_SAVE:
781 lpParms->dwReturn = FALSE;
782 break;
783 default:
784 return MCIERR_UNRECOGNIZED_COMMAND;
787 return 0;
788 #else
789 return MCIERR_INTERNAL;
790 #endif
793 /**************************************************************************
794 * MIDI_mciInfo [internal]
796 static DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
798 #ifdef linux
799 dprintf_midi(stddeb, "MIDI_mciInfo(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
800 if (lpParms == NULL) return MCIERR_INTERNAL;
801 lpParms->lpstrReturn = NULL;
802 switch(dwFlags) {
803 case MCI_INFO_PRODUCT:
804 lpParms->lpstrReturn = "Linux Sound System 0.5";
805 break;
806 case MCI_INFO_FILE:
807 lpParms->lpstrReturn = "FileName";
808 break;
809 default:
810 return MCIERR_UNRECOGNIZED_COMMAND;
812 if (lpParms->lpstrReturn != NULL)
813 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
814 else
815 lpParms->dwRetSize = 0;
816 return 0;
817 #else
818 return MCIERR_INTERNAL;
819 #endif
823 /*-----------------------------------------------------------------------*/
826 /**************************************************************************
827 * midGetDevCaps [internal]
829 static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize)
831 dprintf_midi(stddeb, "midGetDevCaps(%u, %p, %08lX);\n", wDevID, lpCaps, dwSize);
832 return MMSYSERR_NOTENABLED;
835 /**************************************************************************
836 * midOpen [internal]
838 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
840 #ifdef linux
841 int midi;
842 dprintf_midi(stddeb,
843 "midOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
844 if (lpDesc == NULL) {
845 dprintf_midi(stddeb,"Linux 'midOpen' // Invalid Parameter !\n");
846 return MMSYSERR_INVALPARAM;
848 if (wDevID >= MAX_MIDIINDRV) {
849 dprintf_midi(stddeb,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
850 return MMSYSERR_ALLOCATED;
852 MidiInDev[wDevID].unixdev = 0;
853 midi = open (MIDI_DEV, O_RDONLY, 0);
854 if (midi == -1) {
855 dprintf_midi(stddeb,"Linux 'midOpen' // can't open !\n");
856 return MMSYSERR_NOTENABLED;
858 MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
859 switch(MidiInDev[wDevID].wFlags) {
860 case DCB_NULL:
861 dprintf_midi(stddeb,"Linux 'midOpen' // CALLBACK_NULL !\n");
862 break;
863 case DCB_WINDOW:
864 dprintf_midi(stddeb,
865 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
866 break;
867 case DCB_TASK:
868 dprintf_midi(stddeb,
869 "Linux 'midOpen' // CALLBACK_TASK !\n");
870 break;
871 case DCB_FUNCTION:
872 dprintf_midi(stddeb,
873 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
874 break;
876 MidiInDev[wDevID].lpQueueHdr = NULL;
877 MidiInDev[wDevID].unixdev = midi;
878 MidiInDev[wDevID].dwTotalPlayed = 0;
879 MidiInDev[wDevID].bufsize = 0x3FFF;
880 if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
881 dprintf_midi(stddeb,"Linux 'midOpen' // can't notify client !\n");
882 return MMSYSERR_INVALPARAM;
884 return MMSYSERR_NOERROR;
885 #else
886 return MMSYSERR_NOTENABLED;
887 #endif
890 /**************************************************************************
891 * midClose [internal]
893 static DWORD midClose(WORD wDevID)
895 #ifdef linux
896 dprintf_midi(stddeb, "midClose(%u);\n", wDevID);
897 if (MidiInDev[wDevID].unixdev == 0) {
898 dprintf_midi(stddeb,"Linux 'midClose' // can't close !\n");
899 return MMSYSERR_NOTENABLED;
901 close(MidiInDev[wDevID].unixdev);
902 MidiInDev[wDevID].unixdev = 0;
903 MidiInDev[wDevID].bufsize = 0;
904 if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
905 dprintf_midi(stddeb,"Linux 'midClose' // can't notify client !\n");
906 return MMSYSERR_INVALPARAM;
908 return MMSYSERR_NOERROR;
909 #else
910 return MMSYSERR_NOTENABLED;
911 #endif
914 /**************************************************************************
915 * midAddBuffer [internal]
917 static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
919 dprintf_midi(stddeb, "midAddBuffer(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
920 return MMSYSERR_NOTENABLED;
923 /**************************************************************************
924 * midPrepare [internal]
926 static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
928 dprintf_midi(stddeb, "midPrepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
929 return MMSYSERR_NOTENABLED;
932 /**************************************************************************
933 * midUnprepare [internal]
935 static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
937 dprintf_midi(stddeb, "midUnprepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
938 return MMSYSERR_NOTENABLED;
941 /**************************************************************************
942 * midReset [internal]
944 static DWORD midReset(WORD wDevID)
946 dprintf_midi(stddeb, "midReset(%u);\n", wDevID);
947 return MMSYSERR_NOTENABLED;
951 /**************************************************************************
952 * midStart [internal]
954 static DWORD midStart(WORD wDevID)
956 dprintf_midi(stddeb, "midStart(%u);\n", wDevID);
957 return MMSYSERR_NOTENABLED;
961 /**************************************************************************
962 * midStop [internal]
964 static DWORD midStop(WORD wDevID)
966 dprintf_midi(stddeb, "midStop(%u);\n", wDevID);
967 return MMSYSERR_NOTENABLED;
971 /**************************************************************************
972 * midMessage [sample driver]
974 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
975 DWORD dwParam1, DWORD dwParam2)
977 dprintf_midi(stddeb, "midMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
978 wDevID, wMsg, dwUser, dwParam1, dwParam2);
979 switch(wMsg) {
980 case MIDM_OPEN:
981 return midOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
982 case MIDM_CLOSE:
983 return midClose(wDevID);
984 case MIDM_ADDBUFFER:
985 return midAddBuffer(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
986 case MIDM_PREPARE:
987 return midPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
988 case MIDM_UNPREPARE:
989 return midUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
990 case MIDM_GETDEVCAPS:
991 return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
992 case MIDM_GETNUMDEVS:
993 return 0;
994 case MIDM_RESET:
995 return midReset(wDevID);
996 case MIDM_START:
997 return midStart(wDevID);
998 case MIDM_STOP:
999 return midStop(wDevID);
1001 return MMSYSERR_NOTSUPPORTED;
1006 /*-----------------------------------------------------------------------*/
1009 /**************************************************************************
1010 * modGetDevCaps [internal]
1012 static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize)
1014 dprintf_midi(stddeb, "modGetDevCaps(%u, %p, %08lX);\n", wDevID, lpCaps, dwSize);
1015 return MMSYSERR_NOTENABLED;
1019 /**************************************************************************
1020 * modOpen [internal]
1022 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
1024 #ifdef linux
1025 int midi;
1026 dprintf_midi(stddeb,
1027 "modOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1028 if (lpDesc == NULL) {
1029 dprintf_midi(stddeb,"Linux 'modOpen' // Invalid Parameter !\n");
1030 return MMSYSERR_INVALPARAM;
1032 if (wDevID >= MAX_MIDIOUTDRV) {
1033 dprintf_midi(stddeb,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1034 return MMSYSERR_ALLOCATED;
1036 MidiOutDev[wDevID].unixdev = 0;
1037 midi = open (MIDI_DEV, O_WRONLY, 0);
1038 if (midi == -1) {
1039 dprintf_midi(stddeb,"Linux 'modOpen' // can't open !\n");
1040 return MMSYSERR_NOTENABLED;
1042 MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1043 switch(MidiOutDev[wDevID].wFlags) {
1044 case DCB_NULL:
1045 dprintf_midi(stddeb,"Linux 'modOpen' // CALLBACK_NULL !\n");
1046 break;
1047 case DCB_WINDOW:
1048 dprintf_midi(stddeb,
1049 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1050 break;
1051 case DCB_TASK:
1052 dprintf_midi(stddeb,
1053 "Linux 'modOpen' // CALLBACK_TASK !\n");
1054 break;
1055 case DCB_FUNCTION:
1056 dprintf_midi(stddeb,
1057 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1058 break;
1060 MidiOutDev[wDevID].lpQueueHdr = NULL;
1061 MidiOutDev[wDevID].unixdev = midi;
1062 MidiOutDev[wDevID].dwTotalPlayed = 0;
1063 MidiOutDev[wDevID].bufsize = 0x3FFF;
1064 if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1065 dprintf_midi(stddeb,"Linux 'modOpen' // can't notify client !\n");
1066 return MMSYSERR_INVALPARAM;
1068 dprintf_midi(stddeb,
1069 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi);
1070 return MMSYSERR_NOERROR;
1071 #else
1072 return MMSYSERR_NOTENABLED;
1073 #endif
1077 /**************************************************************************
1078 * modClose [internal]
1080 static DWORD modClose(WORD wDevID)
1082 #ifdef linux
1083 dprintf_midi(stddeb, "modClose(%u);\n", wDevID);
1084 if (MidiOutDev[wDevID].unixdev == 0) {
1085 dprintf_midi(stddeb,"Linux 'modClose' // can't close !\n");
1086 return MMSYSERR_NOTENABLED;
1088 close(MidiOutDev[wDevID].unixdev);
1089 MidiOutDev[wDevID].unixdev = 0;
1090 MidiOutDev[wDevID].bufsize = 0;
1091 if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1092 dprintf_midi(stddeb,"Linux 'modClose' // can't notify client !\n");
1093 return MMSYSERR_INVALPARAM;
1095 return MMSYSERR_NOERROR;
1096 #else
1097 return MMSYSERR_NOTENABLED;
1098 #endif
1101 /**************************************************************************
1102 * modData [internal]
1104 static DWORD modData(WORD wDevID, DWORD dwParam)
1106 #ifdef linux
1107 WORD event;
1108 dprintf_midi(stddeb,
1109 "modData(%u, %08lX);\n", wDevID, dwParam);
1110 if (MidiOutDev[wDevID].unixdev == 0) {
1111 dprintf_midi(stddeb,"Linux 'modData' // can't play !\n");
1112 return MIDIERR_NODEVICE;
1114 event = LOWORD(dwParam);
1115 if (write (MidiOutDev[wDevID].unixdev,
1116 &event, sizeof(WORD)) != sizeof(WORD)) {
1117 dprintf_midi(stddeb,
1118 "modData() // error writting unixdev !\n");
1120 return MMSYSERR_NOTENABLED;
1121 #else
1122 return MMSYSERR_NOTENABLED;
1123 #endif
1126 /**************************************************************************
1127 * modLongData [internal]
1129 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1131 #ifdef linux
1132 int count;
1133 LPWORD ptr;
1134 dprintf_midi(stddeb,
1135 "modLongData(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1136 dprintf_midi(stddeb, "modLongData(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1137 if (MidiOutDev[wDevID].unixdev == 0) {
1138 dprintf_midi(stddeb,"Linux 'modLongData' // can't play !\n");
1139 return MIDIERR_NODEVICE;
1141 if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
1142 if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
1143 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1144 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1145 lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1146 dprintf_midi(stddeb,
1147 "modLongData() // dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
1149 count = write (MidiOutDev[wDevID].unixdev,
1150 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1152 ptr = (LPWORD)lpMidiHdr->lpData;
1153 for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
1154 if (write (MidiOutDev[wDevID].unixdev, ptr,
1155 sizeof(WORD)) != sizeof(WORD)) break;
1156 ptr++;
1158 if (count != lpMidiHdr->dwBytesRecorded) {
1159 dprintf_midi(stddeb,
1160 "modLongData() // error writting unixdev #%d ! (%d != %ld)\n",
1161 MidiOutDev[wDevID].unixdev, count, lpMidiHdr->dwBytesRecorded);
1162 return MMSYSERR_NOTENABLED;
1164 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1165 lpMidiHdr->dwFlags |= MHDR_DONE;
1166 if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
1167 dprintf_midi(stddeb,"Linux 'modLongData' // can't notify client !\n");
1168 return MMSYSERR_INVALPARAM;
1170 return MMSYSERR_NOERROR;
1171 #else
1172 return MMSYSERR_NOTENABLED;
1173 #endif
1176 /**************************************************************************
1177 * modPrepare [internal]
1179 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1181 #ifdef linux
1182 dprintf_midi(stddeb,
1183 "modPrepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1184 if (MidiOutDev[wDevID].unixdev == 0) {
1185 dprintf_midi(stddeb,"Linux 'modPrepare' // can't prepare !\n");
1186 return MMSYSERR_NOTENABLED;
1188 if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
1189 dprintf_midi(stddeb,"Linux 'modPrepare' // already prepare !\n");
1190 return MMSYSERR_NOTENABLED;
1192 MidiOutDev[wDevID].dwTotalPlayed = 0;
1193 MidiOutDev[wDevID].lpQueueHdr = lpMidiHdr;
1194 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1195 lpMidiHdr->dwFlags |= MHDR_PREPARED;
1196 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1197 return MMSYSERR_NOERROR;
1198 #else
1199 return MMSYSERR_NOTENABLED;
1200 #endif
1203 /**************************************************************************
1204 * modUnprepare [internal]
1206 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1208 #ifdef linux
1209 dprintf_midi(stddeb,
1210 "modUnprepare(%u, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1211 if (MidiOutDev[wDevID].unixdev == 0) {
1212 dprintf_midi(stddeb,"Linux 'modUnprepare' // can't unprepare !\n");
1213 return MMSYSERR_NOTENABLED;
1215 return MMSYSERR_NOERROR;
1216 #else
1217 return MMSYSERR_NOTENABLED;
1218 #endif
1221 /**************************************************************************
1222 * modReset [internal]
1224 static DWORD modReset(WORD wDevID)
1226 dprintf_midi(stddeb, "modReset(%u);\n", wDevID);
1227 return MMSYSERR_NOTENABLED;
1231 /**************************************************************************
1232 * modMessage [sample driver]
1234 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1235 DWORD dwParam1, DWORD dwParam2)
1237 dprintf_midi(stddeb, "modMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1238 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1239 switch(wMsg) {
1240 case MODM_OPEN:
1241 return modOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1242 case MODM_CLOSE:
1243 return modClose(wDevID);
1244 case MODM_DATA:
1245 return modData(wDevID, dwParam1);
1246 case MODM_LONGDATA:
1247 return modLongData(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1248 case MODM_PREPARE:
1249 return modPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1250 case MODM_UNPREPARE:
1251 return modUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1252 case MODM_GETDEVCAPS:
1253 return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1254 case MODM_GETNUMDEVS:
1255 return 1;
1256 case MODM_GETVOLUME:
1257 return 0;
1258 case MODM_SETVOLUME:
1259 return 0;
1260 case MODM_RESET:
1261 return modReset(wDevID);
1263 return MMSYSERR_NOTSUPPORTED;
1267 /**************************************************************************
1268 * MIDI_DriverProc [sample driver]
1270 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
1271 DWORD dwParam1, DWORD dwParam2)
1273 #ifdef linux
1274 switch(wMsg) {
1275 case DRV_LOAD:
1276 return 1;
1277 case DRV_FREE:
1278 return 1;
1279 case DRV_OPEN:
1280 return 1;
1281 case DRV_CLOSE:
1282 return 1;
1283 case DRV_ENABLE:
1284 return 1;
1285 case DRV_DISABLE:
1286 return 1;
1287 case DRV_QUERYCONFIGURE:
1288 return 1;
1289 case DRV_CONFIGURE:
1290 MessageBox(0, "Sample Midi Linux Driver !",
1291 "MMLinux Driver", MB_OK);
1292 return 1;
1293 case DRV_INSTALL:
1294 return DRVCNF_RESTART;
1295 case DRV_REMOVE:
1296 return DRVCNF_RESTART;
1297 case MCI_OPEN_DRIVER:
1298 case MCI_OPEN:
1299 return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
1300 case MCI_CLOSE_DRIVER:
1301 case MCI_CLOSE:
1302 return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1303 case MCI_PLAY:
1304 return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
1305 case MCI_RECORD:
1306 return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
1307 case MCI_STOP:
1308 return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1309 case MCI_SET:
1310 return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
1311 case MCI_PAUSE:
1312 return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1313 case MCI_RESUME:
1314 return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1315 case MCI_STATUS:
1316 return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1317 case MCI_GETDEVCAPS:
1318 return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1319 case MCI_INFO:
1320 return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
1321 default:
1322 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1324 #else
1325 return MMSYSERR_NOTENABLED;
1326 #endif
1330 /*-----------------------------------------------------------------------*/
1332 #endif /* #ifdef BUILTIN_MMSYSTEM */