Release 970305
[wine/multimedia.git] / multimedia / midi.c
blob7a52f87f7fbf5610997790b9d7519a06eadccb53
1 /*
2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 #include "windows.h"
13 #include "ldt.h"
14 #include "driver.h"
15 #include "mmsystem.h"
16 #include "xmalloc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 #ifdef linux
22 #include <linux/soundcard.h>
23 #elif __FreeBSD__
24 #include <machine/soundcard.h>
25 #endif
27 int MMSYSTEM_DevIDToIndex(UINT16);
29 #if defined(linux) || defined(__FreeBSD__)
30 #define MIDI_DEV "/dev/sequencer"
32 #ifdef SOUND_VERSION
33 #define IOCTL(a,b,c) ioctl(a,b,&c)
34 #else
35 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
36 #endif
38 #define MAX_MIDIINDRV 2
39 #define MAX_MIDIOUTDRV 2
40 #define MAX_MCIMIDIDRV 2
42 typedef struct {
43 int unixdev;
44 int state;
45 DWORD bufsize;
46 MIDIOPENDESC midiDesc;
47 WORD wFlags;
48 LPMIDIHDR lpQueueHdr;
49 DWORD dwTotalPlayed;
50 } LINUX_MIDIIN;
52 typedef struct {
53 int unixdev;
54 int state;
55 DWORD bufsize;
56 MIDIOPENDESC midiDesc;
57 WORD wFlags;
58 LPMIDIHDR lpQueueHdr;
59 DWORD dwTotalPlayed;
60 } LINUX_MIDIOUT;
62 typedef struct {
63 int nUseCount; /* Incremented for each shared open */
64 BOOL16 fShareable; /* TRUE if first open was shareable */
65 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
66 HANDLE16 hCallback; /* Callback handle for pending notification */
67 HMMIO16 hFile; /* mmio file handle open as Element */
68 DWORD dwBeginData;
69 DWORD dwTotalLen;
70 WORD wFormat;
71 WORD nTracks;
72 WORD nTempo;
73 MCI_OPEN_PARMS openParms;
74 MIDIHDR MidiHdr;
75 WORD dwStatus;
76 } LINUX_MCIMIDI;
78 static LINUX_MIDIIN MidiInDev[MAX_MIDIINDRV];
79 static LINUX_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
80 static LINUX_MCIMIDI MCIMidiDev[MAX_MCIMIDIDRV];
81 #endif
84 /**************************************************************************
85 * MIDI_NotifyClient [internal]
87 static DWORD MIDI_NotifyClient(UINT16 wDevID, WORD wMsg,
88 DWORD dwParam1, DWORD dwParam2)
90 #if defined(linux) || defined(__FreeBSD__)
91 int index = MMSYSTEM_DevIDToIndex(wDevID);
92 if (MidiInDev[index].wFlags != DCB_NULL && !DriverCallback(
93 MidiInDev[index].midiDesc.dwCallback, MidiInDev[index].wFlags,
94 MidiInDev[index].midiDesc.hMidi, wMsg,
95 MidiInDev[index].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(UINT16 wDevID, BYTE *lpbyt)
111 int index = MMSYSTEM_DevIDToIndex(wDevID);
112 #if defined(linux) || defined(__FreeBSD__)
113 if (lpbyt != NULL) {
114 if (mmioRead(MCIMidiDev[index].hFile, (HPSTR)lpbyt,
115 (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
116 return 0;
119 dprintf_midi(stddeb, "MIDI_ReadByte // error reading wDevID=%04X\n", wDevID);
120 return MCIERR_INTERNAL;
122 #else
123 return MMSYSERR_NOTENABLED;
124 #endif
128 /**************************************************************************
129 * MIDI_ReadWord [internal]
131 static DWORD MIDI_ReadWord(UINT16 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=%04X\n", wDevID);
143 return MCIERR_INTERNAL;
147 /**************************************************************************
148 * MIDI_ReadLong [internal]
150 static DWORD MIDI_ReadLong(UINT16 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=%04X\n", wDevID);
162 return MCIERR_INTERNAL;
166 /**************************************************************************
167 * MIDI_ReadVaryLen [internal]
169 static DWORD MIDI_ReadVaryLen(UINT16 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=%04X\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=%04X\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(UINT16 wDevID, DWORD dwOffset)
199 #if defined(linux) || defined(__FreeBSD__)
200 int index = MMSYSTEM_DevIDToIndex(wDevID);
201 DWORD toberead;
202 FOURCC fourcc;
203 dprintf_midi(stddeb, "MIDI_ReadMThd(%04X, %08lX);\n", wDevID, dwOffset);
204 if (mmioSeek(MCIMidiDev[index].hFile, dwOffset, SEEK_SET) != dwOffset) {
205 dprintf_midi(stddeb, "MIDI_ReadMThd // can't seek at %08lX begin of 'MThd' \n", dwOffset);
206 return MCIERR_INTERNAL;
208 if (mmioRead(MCIMidiDev[index].hFile, (HPSTR)&fourcc,
209 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
210 return MCIERR_INTERNAL;
212 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
213 return MCIERR_INTERNAL;
215 if (MIDI_ReadWord(wDevID, &MCIMidiDev[index].wFormat) != 0) {
216 return MCIERR_INTERNAL;
218 if (MIDI_ReadWord(wDevID, &MCIMidiDev[index].nTracks) != 0) {
219 return MCIERR_INTERNAL;
221 if (MIDI_ReadWord(wDevID, &MCIMidiDev[index].nTempo) != 0) {
222 return MCIERR_INTERNAL;
224 dprintf_midi(stddeb, "MIDI_ReadMThd // toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
225 toberead, MCIMidiDev[index].wFormat,
226 MCIMidiDev[index].nTracks,
227 MCIMidiDev[index].nTempo);
228 toberead -= 3 * sizeof(WORD);
230 ntrks = read16bit ();
231 Mf_division = division = read16bit ();
233 return 0;
235 #else
236 return MMSYSERR_NOTENABLED;
237 #endif
241 static DWORD MIDI_ReadMTrk(UINT16 wDevID, DWORD dwOffset)
243 #if defined(linux) || defined(__FreeBSD__)
244 int index = MMSYSTEM_DevIDToIndex(wDevID);
245 DWORD toberead;
246 FOURCC fourcc;
247 if (mmioSeek(MCIMidiDev[index].hFile, dwOffset, SEEK_SET) != dwOffset) {
248 dprintf_midi(stddeb, "MIDI_ReadMTrk // can't seek at %08lX begin of 'MThd' \n", dwOffset);
250 if (mmioRead(MCIMidiDev[index].hFile, (HPSTR)&fourcc,
251 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
252 return MCIERR_INTERNAL;
254 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
255 return MCIERR_INTERNAL;
257 dprintf_midi(stddeb, "MIDI_ReadMTrk // toberead=%08lX\n", toberead);
258 toberead -= 3 * sizeof(WORD);
259 MCIMidiDev[index].dwTotalLen = toberead;
260 return 0;
261 #else
262 return MMSYSERR_NOTENABLED;
263 #endif
267 /**************************************************************************
268 * MIDI_mciOpen [internal]
270 static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
272 #if defined(linux) || defined(__FreeBSD__)
273 int index;
274 MIDIOPENDESC MidiDesc;
275 DWORD dwRet;
276 DWORD dwOffset;
277 LPSTR lpstrElementName;
278 char str[128];
280 dprintf_midi(stddeb, "MIDI_mciOpen(%08lX, %p)\n", dwFlags, lpParms);
281 if (lpParms == NULL) return MCIERR_INTERNAL;
283 wDevID = lpParms->wDeviceID;
284 index = MMSYSTEM_DevIDToIndex(wDevID);
286 if (MCIMidiDev[index].nUseCount > 0) {
287 /* The driver already open on this channel */
288 /* If the driver was opened shareable before and this open specifies */
289 /* shareable then increment the use count */
290 if (MCIMidiDev[index].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
291 ++MCIMidiDev[index].nUseCount;
292 else
293 return MCIERR_MUST_USE_SHAREABLE;
295 else {
296 MCIMidiDev[index].nUseCount = 1;
297 MCIMidiDev[index].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
299 dprintf_midi(stddeb, "MIDI_mciOpen // wDevID=%04X\n", wDevID);
300 lpParms->wDeviceID = wDevID;
301 dprintf_midi(stddeb, "MIDI_mciOpen // lpParms->wDevID=%04X\n", lpParms->wDeviceID);
302 dprintf_midi(stddeb, "MIDI_mciOpen // before OPEN_ELEMENT\n");
303 if (dwFlags & MCI_OPEN_ELEMENT) {
304 lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
305 dprintf_midi(stddeb, "MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
306 if (strlen(lpstrElementName) > 0) {
307 strcpy(str, lpstrElementName);
308 CharUpper32A(str);
309 MCIMidiDev[index].hFile = mmioOpen(str, NULL,
310 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
311 if (MCIMidiDev[index].hFile == 0) {
312 dprintf_midi(stddeb, "MIDI_mciOpen // can't find file='%s' !\n", str);
313 return MCIERR_FILE_NOT_FOUND;
316 else
317 MCIMidiDev[index].hFile = 0;
319 dprintf_midi(stddeb, "MIDI_mciOpen // hFile=%u\n", MCIMidiDev[index].hFile);
320 memcpy(&MCIMidiDev[index].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
321 MCIMidiDev[index].wNotifyDeviceID = lpParms->wDeviceID;
322 MCIMidiDev[index].dwStatus = MCI_MODE_STOP;
323 MCIMidiDev[index].dwBeginData = 0;
324 MCIMidiDev[index].dwTotalLen = 0;
325 MidiDesc.hMidi = 0;
326 if (MCIMidiDev[index].hFile != 0) {
327 MMCKINFO ckMainRIFF;
328 if (mmioDescend(MCIMidiDev[index].hFile, &ckMainRIFF, NULL, 0) != 0) {
329 return MCIERR_INTERNAL;
331 dprintf_midi(stddeb,"MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
332 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
333 ckMainRIFF.cksize);
334 dwOffset = 0;
335 if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
336 dprintf_midi(stddeb, "MIDI_mciOpen // is a 'RMID' file \n");
337 dwOffset = ckMainRIFF.dwDataOffset;
339 if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
340 dprintf_midi(stddeb, "MIDI_mciOpen // unknown format !\n");
341 return MCIERR_INTERNAL;
343 if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
344 dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MThd' header \n");
345 return MCIERR_INTERNAL;
347 dwOffset = mmioSeek(MCIMidiDev[index].hFile, 0, SEEK_CUR);
348 if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
349 dprintf_midi(stddeb, "MIDI_mciOpen // can't read 'MTrk' header \n");
350 return MCIERR_INTERNAL;
352 dwOffset = mmioSeek(MCIMidiDev[index].hFile, 0, SEEK_CUR);
353 MCIMidiDev[index].dwBeginData = dwOffset;
354 dprintf_midi(stddeb, "MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
355 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
356 ckMainRIFF.cksize);
358 dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
359 dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
360 return 0;
361 #else
362 return MMSYSERR_NOTENABLED;
363 #endif
367 /**************************************************************************
368 * MIDI_mciStop [internal]
370 static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
372 #if defined(linux) || defined(__FreeBSD__)
373 int index = MMSYSTEM_DevIDToIndex(wDevID);
374 dprintf_midi(stddeb, "MIDI_mciStop(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
375 if (lpParms == NULL) return MCIERR_INTERNAL;
376 MCIMidiDev[index].dwStatus = MCI_MODE_STOP;
377 dprintf_midi(stddeb, "MIDI_mciStop // MCIMidiDev[index].dwStatus=%p %d\n",
378 &MCIMidiDev[index].dwStatus, MCIMidiDev[index].dwStatus);
379 return 0;
380 #else
381 return MCIERR_INTERNAL;
382 #endif
386 /**************************************************************************
387 * MIDI_mciClose [internal]
389 static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
391 #if defined(linux) || defined(__FreeBSD__)
392 int index = MMSYSTEM_DevIDToIndex(wDevID);
393 DWORD dwRet;
394 dprintf_midi(stddeb, "MIDI_mciClose(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
395 if (MCIMidiDev[index].dwStatus != MCI_MODE_STOP) {
396 MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
398 MCIMidiDev[index].dwStatus = MCI_MODE_STOP;
399 MCIMidiDev[index].nUseCount--;
400 if (MCIMidiDev[index].nUseCount == 0) {
401 if (MCIMidiDev[index].hFile != 0) {
402 mmioClose(MCIMidiDev[index].hFile, 0);
403 MCIMidiDev[index].hFile = 0;
404 dprintf_midi(stddeb, "MIDI_mciClose // hFile closed !\n");
406 dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
407 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
408 dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
409 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
411 return 0;
412 #else
413 return 0;
414 #endif
418 /**************************************************************************
419 * MIDI_mciPlay [internal]
421 static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
423 #if defined(linux) || defined(__FreeBSD__)
424 int index = MMSYSTEM_DevIDToIndex(wDevID);
425 int count;
426 int start, end;
427 LPMIDIHDR lpMidiHdr;
428 DWORD dwData;
429 LPWORD ptr;
430 DWORD dwRet;
431 dprintf_midi(stddeb, "MIDI_mciPlay(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
432 if (MCIMidiDev[index].hFile == 0) {
433 dprintf_midi(stddeb, "MIDI_mciPlay // can't find file='%08lx' !\n",
434 MCIMidiDev[index].openParms.lpstrElementName);
435 return MCIERR_FILE_NOT_FOUND;
437 start = 1; end = 99999;
438 if (dwFlags & MCI_FROM) {
439 start = lpParms->dwFrom;
440 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_FROM=%d \n", start);
442 if (dwFlags & MCI_TO) {
443 end = lpParms->dwTo;
444 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_TO=%d \n", end);
446 #if 0
447 if (dwFlags & MCI_NOTIFY) {
448 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
449 switch(fork()) {
450 case -1:
451 dprintf_midi(stddeb, "MIDI_mciPlay // Can't 'fork' process !\n");
452 break;
453 case 0:
454 dprintf_midi(stddeb, "MIDI_mciPlay // process started ! play in background ...\n");
455 break;
456 default:
457 dprintf_midi(stddeb, "MIDI_mciPlay // process started ! return to caller...\n");
458 return 0;
461 #endif
462 lpMidiHdr = &MCIMidiDev[index].MidiHdr;
463 lpMidiHdr->lpData = (LPSTR) malloc(1200);
464 if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
465 lpMidiHdr->dwBufferLength = 1024;
466 lpMidiHdr->dwUser = 0L;
467 lpMidiHdr->dwFlags = 0L;
468 dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
469 /* dprintf_midi(stddeb, "MIDI_mciPlay // after MODM_PREPARE \n"); */
470 MCIMidiDev[index].dwStatus = MCI_MODE_PLAY;
471 while(MCIMidiDev[index].dwStatus != MCI_MODE_STOP) {
472 dprintf_midi(stddeb, "MIDI_mciPlay // MCIMidiDev[index].dwStatus=%p %d\n",
473 &MCIMidiDev[index].dwStatus, MCIMidiDev[index].dwStatus);
474 ptr = (LPWORD)lpMidiHdr->lpData;
475 for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
476 if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
477 *ptr = LOWORD(dwData);
480 count = mmioRead(MCIMidiDev[index].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
482 if (count < 1) break;
483 lpMidiHdr->dwBytesRecorded = count;
484 dprintf_midi(stddeb, "MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
485 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
486 dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
488 dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
489 if (lpMidiHdr->lpData != NULL) {
490 free(lpMidiHdr->lpData);
491 lpMidiHdr->lpData = NULL;
493 MCIMidiDev[index].dwStatus = MCI_MODE_STOP;
494 if (dwFlags & MCI_NOTIFY) {
495 dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
496 mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
497 MCIMidiDev[index].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
498 #if 0
499 exit(1);
500 #endif
502 return 0;
503 #else
504 return MMSYSERR_NOTENABLED;
505 #endif
509 /**************************************************************************
510 * MIDI_mciRecord [internal]
512 static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
514 #if defined(linux) || defined(__FreeBSD__)
515 int index = MMSYSTEM_DevIDToIndex(wDevID);
516 int start, end;
517 LPMIDIHDR lpMidiHdr;
518 DWORD dwRet;
520 dprintf_midi(stddeb, "MIDI_mciRecord(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
521 if (MCIMidiDev[index].hFile == 0) {
522 dprintf_midi(stddeb, "MIDI_mciRecord // can't find file='%08lx' !\n",
523 MCIMidiDev[index].openParms.lpstrElementName);
524 return MCIERR_FILE_NOT_FOUND;
526 start = 1; end = 99999;
527 if (dwFlags & MCI_FROM) {
528 start = lpParms->dwFrom;
529 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_FROM=%d \n", start);
531 if (dwFlags & MCI_TO) {
532 end = lpParms->dwTo;
533 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_TO=%d \n", end);
535 lpMidiHdr = &MCIMidiDev[index].MidiHdr;
536 lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
537 lpMidiHdr->dwBufferLength = 1024;
538 lpMidiHdr->dwUser = 0L;
539 lpMidiHdr->dwFlags = 0L;
540 dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
541 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_PREPARE \n");
542 MCIMidiDev[index].dwStatus = MCI_MODE_RECORD;
543 while(MCIMidiDev[index].dwStatus != MCI_MODE_STOP) {
544 dprintf_midi(stddeb, "MIDI_mciRecord // MCIMidiDev[index].dwStatus=%p %d\n",
545 &MCIMidiDev[index].dwStatus, MCIMidiDev[index].dwStatus);
546 lpMidiHdr->dwBytesRecorded = 0;
547 dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
548 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
549 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
550 if (lpMidiHdr->dwBytesRecorded == 0) break;
552 dprintf_midi(stddeb, "MIDI_mciRecord // before MIDM_UNPREPARE \n");
553 dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
554 dprintf_midi(stddeb, "MIDI_mciRecord // after MIDM_UNPREPARE \n");
555 if (lpMidiHdr->lpData != NULL) {
556 free(lpMidiHdr->lpData);
557 lpMidiHdr->lpData = NULL;
559 MCIMidiDev[index].dwStatus = MCI_MODE_STOP;
560 if (dwFlags & MCI_NOTIFY) {
561 dprintf_midi(stddeb, "MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
562 mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
563 MCIMidiDev[index].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
565 return 0;
566 #else
567 return MMSYSERR_NOTENABLED;
568 #endif
572 /**************************************************************************
573 * MIDI_mciPause [internal]
575 static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
577 #if defined(linux) || defined(__FreeBSD__)
578 dprintf_midi(stddeb, "MIDI_mciPause(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
579 if (lpParms == NULL) return MCIERR_INTERNAL;
580 return 0;
581 #else
582 return MCIERR_INTERNAL;
583 #endif
587 /**************************************************************************
588 * MIDI_mciResume [internal]
590 static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
592 #if defined(linux) || defined(__FreeBSD__)
593 dprintf_midi(stddeb, "MIDI_mciResume(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
594 if (lpParms == NULL) return MCIERR_INTERNAL;
595 return 0;
596 #else
597 return MCIERR_INTERNAL;
598 #endif
602 /**************************************************************************
603 * MIDI_mciSet [internal]
605 static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
607 #if defined(linux) || defined(__FreeBSD__)
608 dprintf_midi(stddeb, "MIDI_mciSet(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
609 if (lpParms == NULL) return MCIERR_INTERNAL;
610 dprintf_midi(stddeb, "MIDI_mciSet // dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
611 dprintf_midi(stddeb, "MIDI_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
612 if (dwFlags & MCI_SET_TIME_FORMAT) {
613 switch (lpParms->dwTimeFormat) {
614 case MCI_FORMAT_MILLISECONDS:
615 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
616 break;
617 case MCI_FORMAT_BYTES:
618 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_BYTES !\n");
619 break;
620 case MCI_FORMAT_SAMPLES:
621 dprintf_midi(stddeb, "MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
622 break;
623 default:
624 dprintf_midi(stddeb, "MIDI_mciSet // bad time format !\n");
625 return MCIERR_BAD_TIME_FORMAT;
628 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
629 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
630 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
631 if (dwFlags & MCI_SET_AUDIO) {
632 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO !\n");
634 if (dwFlags && MCI_SET_ON) {
635 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_ON !\n");
636 if (dwFlags && MCI_SET_AUDIO_LEFT) {
637 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
639 if (dwFlags && MCI_SET_AUDIO_RIGHT) {
640 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
643 if (dwFlags & MCI_SET_OFF) {
644 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SET_OFF !\n");
646 if (dwFlags & MCI_SEQ_SET_MASTER) {
647 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
649 if (dwFlags & MCI_SEQ_SET_SLAVE) {
650 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
652 if (dwFlags & MCI_SEQ_SET_OFFSET) {
653 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
655 if (dwFlags & MCI_SEQ_SET_PORT) {
656 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
658 if (dwFlags & MCI_SEQ_SET_TEMPO) {
659 dprintf_midi(stddeb, "MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
661 return 0;
662 #else
663 return MCIERR_INTERNAL;
664 #endif
668 /**************************************************************************
669 * MIDI_mciStatus [internal]
671 static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
673 #if defined(linux) || defined(__FreeBSD__)
674 int index = MMSYSTEM_DevIDToIndex(wDevID);
675 dprintf_midi(stddeb, "MIDI_mciStatus(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
676 if (lpParms == NULL) return MCIERR_INTERNAL;
677 if (dwFlags & MCI_STATUS_ITEM) {
678 switch(lpParms->dwItem) {
679 case MCI_STATUS_CURRENT_TRACK:
680 lpParms->dwReturn = 1;
681 break;
682 case MCI_STATUS_LENGTH:
683 lpParms->dwReturn = 5555;
684 if (dwFlags & MCI_TRACK) {
685 lpParms->dwTrack = 1;
686 lpParms->dwReturn = 2222;
688 break;
689 case MCI_STATUS_MODE:
690 lpParms->dwReturn = MCI_MODE_STOP;
691 break;
692 case MCI_STATUS_MEDIA_PRESENT:
693 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
694 lpParms->dwReturn = TRUE;
695 break;
696 case MCI_STATUS_NUMBER_OF_TRACKS:
697 lpParms->dwReturn = 1;
698 break;
699 case MCI_STATUS_POSITION:
700 lpParms->dwReturn = 3333;
701 if (dwFlags & MCI_STATUS_START) {
702 lpParms->dwItem = 1;
704 if (dwFlags & MCI_TRACK) {
705 lpParms->dwTrack = 1;
706 lpParms->dwReturn = 777;
708 break;
709 case MCI_STATUS_READY:
710 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_READY !\n");
711 lpParms->dwReturn = TRUE;
712 break;
713 case MCI_STATUS_TIME_FORMAT:
714 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
715 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
716 break;
717 case MCI_SEQ_STATUS_DIVTYPE:
718 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
719 lpParms->dwReturn = 0;
720 break;
721 case MCI_SEQ_STATUS_MASTER:
722 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
723 lpParms->dwReturn = 0;
724 break;
725 case MCI_SEQ_STATUS_SLAVE:
726 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
727 lpParms->dwReturn = 0;
728 break;
729 case MCI_SEQ_STATUS_OFFSET:
730 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
731 lpParms->dwReturn = 0;
732 break;
733 case MCI_SEQ_STATUS_PORT:
734 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
735 lpParms->dwReturn = 0;
736 break;
737 case MCI_SEQ_STATUS_TEMPO:
738 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
739 lpParms->dwReturn = 0;
740 break;
741 default:
742 dprintf_midi(stddeb, "MIDI_mciStatus // unknowm command %08lX !\n", lpParms->dwItem);
743 return MCIERR_UNRECOGNIZED_COMMAND;
746 if (dwFlags & MCI_NOTIFY) {
747 dprintf_midi(stddeb, "MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
748 mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
749 MCIMidiDev[index].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
751 return 0;
752 #else
753 return MCIERR_INTERNAL;
754 #endif
757 /**************************************************************************
758 * MIDI_mciGetDevCaps [internal]
760 static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,
761 LPMCI_GETDEVCAPS_PARMS lpParms)
763 #if defined(linux) || defined(__FreeBSD__)
764 dprintf_midi(stddeb, "MIDI_mciGetDevCaps(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
765 if (lpParms == NULL) return MCIERR_INTERNAL;
766 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
767 switch(lpParms->dwItem) {
768 case MCI_GETDEVCAPS_CAN_RECORD:
769 lpParms->dwReturn = TRUE;
770 break;
771 case MCI_GETDEVCAPS_HAS_AUDIO:
772 lpParms->dwReturn = TRUE;
773 break;
774 case MCI_GETDEVCAPS_HAS_VIDEO:
775 lpParms->dwReturn = FALSE;
776 break;
777 case MCI_GETDEVCAPS_DEVICE_TYPE:
778 lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
779 break;
780 case MCI_GETDEVCAPS_USES_FILES:
781 lpParms->dwReturn = TRUE;
782 break;
783 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
784 lpParms->dwReturn = TRUE;
785 break;
786 case MCI_GETDEVCAPS_CAN_EJECT:
787 lpParms->dwReturn = FALSE;
788 break;
789 case MCI_GETDEVCAPS_CAN_PLAY:
790 lpParms->dwReturn = TRUE;
791 break;
792 case MCI_GETDEVCAPS_CAN_SAVE:
793 lpParms->dwReturn = FALSE;
794 break;
795 default:
796 return MCIERR_UNRECOGNIZED_COMMAND;
799 return 0;
800 #else
801 return MCIERR_INTERNAL;
802 #endif
805 /**************************************************************************
806 * MIDI_mciInfo [internal]
808 static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
810 #if defined(linux) || defined(__FreeBSD__)
811 dprintf_midi(stddeb, "MIDI_mciInfo(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
812 if (lpParms == NULL) return MCIERR_INTERNAL;
813 lpParms->lpstrReturn = NULL;
814 switch(dwFlags) {
815 case MCI_INFO_PRODUCT:
816 lpParms->lpstrReturn = "Linux Sound System 0.5";
817 break;
818 case MCI_INFO_FILE:
819 lpParms->lpstrReturn = "FileName";
820 break;
821 default:
822 return MCIERR_UNRECOGNIZED_COMMAND;
824 if (lpParms->lpstrReturn != NULL)
825 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
826 else
827 lpParms->dwRetSize = 0;
828 return 0;
829 #else
830 return MCIERR_INTERNAL;
831 #endif
835 /*-----------------------------------------------------------------------*/
838 /**************************************************************************
839 * midGetDevCaps [internal]
841 static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize)
843 dprintf_midi(stddeb, "midGetDevCaps(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
844 return MMSYSERR_NOTENABLED;
847 /**************************************************************************
848 * midOpen [internal]
850 static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
852 #if defined(linux) || defined(__FreeBSD__)
853 int index = MMSYSTEM_DevIDToIndex(wDevID);
854 int midi;
855 dprintf_midi(stddeb,
856 "midOpen(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
857 if (lpDesc == NULL) {
858 dprintf_midi(stddeb,"Linux 'midOpen' // Invalid Parameter !\n");
859 return MMSYSERR_INVALPARAM;
861 if (index >= MAX_MIDIINDRV) {
862 dprintf_midi(stddeb,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
863 return MMSYSERR_ALLOCATED;
865 MidiInDev[index].unixdev = 0;
866 midi = open (MIDI_DEV, O_RDONLY, 0);
867 if (midi == -1) {
868 dprintf_midi(stddeb,"Linux 'midOpen' // can't open !\n");
869 return MMSYSERR_NOTENABLED;
871 MidiInDev[index].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
872 switch(MidiInDev[index].wFlags) {
873 case DCB_NULL:
874 dprintf_midi(stddeb,"Linux 'midOpen' // CALLBACK_NULL !\n");
875 break;
876 case DCB_WINDOW:
877 dprintf_midi(stddeb,
878 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
879 break;
880 case DCB_TASK:
881 dprintf_midi(stddeb,
882 "Linux 'midOpen' // CALLBACK_TASK !\n");
883 break;
884 case DCB_FUNCTION:
885 dprintf_midi(stddeb,
886 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
887 break;
889 MidiInDev[index].lpQueueHdr = NULL;
890 MidiInDev[index].unixdev = midi;
891 MidiInDev[index].dwTotalPlayed = 0;
892 MidiInDev[index].bufsize = 0x3FFF;
893 if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
894 dprintf_midi(stddeb,"Linux 'midOpen' // can't notify client !\n");
895 return MMSYSERR_INVALPARAM;
897 return MMSYSERR_NOERROR;
898 #else
899 return MMSYSERR_NOTENABLED;
900 #endif
903 /**************************************************************************
904 * midClose [internal]
906 static DWORD midClose(WORD wDevID)
908 #if defined(linux) || defined(__FreeBSD__)
909 int index = MMSYSTEM_DevIDToIndex(wDevID);
910 dprintf_midi(stddeb, "midClose(%04X);\n", wDevID);
911 if (MidiInDev[index].unixdev == 0) {
912 dprintf_midi(stddeb,"Linux 'midClose' // can't close !\n");
913 return MMSYSERR_NOTENABLED;
915 close(MidiInDev[index].unixdev);
916 MidiInDev[index].unixdev = 0;
917 MidiInDev[index].bufsize = 0;
918 if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
919 dprintf_midi(stddeb,"Linux 'midClose' // can't notify client !\n");
920 return MMSYSERR_INVALPARAM;
922 return MMSYSERR_NOERROR;
923 #else
924 return MMSYSERR_NOTENABLED;
925 #endif
928 /**************************************************************************
929 * midAddBuffer [internal]
931 static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
933 dprintf_midi(stddeb, "midAddBuffer(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
934 return MMSYSERR_NOTENABLED;
937 /**************************************************************************
938 * midPrepare [internal]
940 static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
942 dprintf_midi(stddeb, "midPrepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
943 return MMSYSERR_NOTENABLED;
946 /**************************************************************************
947 * midUnprepare [internal]
949 static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
951 dprintf_midi(stddeb, "midUnprepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
952 return MMSYSERR_NOTENABLED;
955 /**************************************************************************
956 * midReset [internal]
958 static DWORD midReset(WORD wDevID)
960 dprintf_midi(stddeb, "midReset(%04X);\n", wDevID);
961 return MMSYSERR_NOTENABLED;
965 /**************************************************************************
966 * midStart [internal]
968 static DWORD midStart(WORD wDevID)
970 dprintf_midi(stddeb, "midStart(%04X);\n", wDevID);
971 return MMSYSERR_NOTENABLED;
975 /**************************************************************************
976 * midStop [internal]
978 static DWORD midStop(WORD wDevID)
980 dprintf_midi(stddeb, "midStop(%04X);\n", wDevID);
981 return MMSYSERR_NOTENABLED;
985 /**************************************************************************
986 * midMessage [sample driver]
988 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
989 DWORD dwParam1, DWORD dwParam2)
991 dprintf_midi(stddeb, "midMessage(%04X, %04X, %08lX, %08lX, %08lX);\n",
992 wDevID, wMsg, dwUser, dwParam1, dwParam2);
993 switch(wMsg) {
994 case MIDM_OPEN:
995 return midOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
996 case MIDM_CLOSE:
997 return midClose(wDevID);
998 case MIDM_ADDBUFFER:
999 return midAddBuffer(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1000 case MIDM_PREPARE:
1001 return midPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1002 case MIDM_UNPREPARE:
1003 return midUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1004 case MIDM_GETDEVCAPS:
1005 return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1006 case MIDM_GETNUMDEVS:
1007 return 0;
1008 case MIDM_RESET:
1009 return midReset(wDevID);
1010 case MIDM_START:
1011 return midStart(wDevID);
1012 case MIDM_STOP:
1013 return midStop(wDevID);
1015 return MMSYSERR_NOTSUPPORTED;
1020 /*-----------------------------------------------------------------------*/
1023 /**************************************************************************
1024 * modGetDevCaps [internal]
1026 static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize)
1028 dprintf_midi(stddeb, "modGetDevCaps(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
1029 return MMSYSERR_NOTENABLED;
1033 /**************************************************************************
1034 * modOpen [internal]
1036 static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
1038 #if defined(linux) || defined(__FreeBSD__)
1039 int index = MMSYSTEM_DevIDToIndex(wDevID);
1040 int midi;
1041 dprintf_midi(stddeb,
1042 "modOpen(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1043 if (lpDesc == NULL) {
1044 dprintf_midi(stddeb,"Linux 'modOpen' // Invalid Parameter !\n");
1045 return MMSYSERR_INVALPARAM;
1047 if (index >= MAX_MIDIOUTDRV) {
1048 dprintf_midi(stddeb,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1049 return MMSYSERR_ALLOCATED;
1051 MidiOutDev[index].unixdev = 0;
1052 midi = open (MIDI_DEV, O_WRONLY, 0);
1053 if (midi == -1) {
1054 dprintf_midi(stddeb,"Linux 'modOpen' // can't open !\n");
1055 return MMSYSERR_NOTENABLED;
1057 MidiOutDev[index].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1058 switch(MidiOutDev[index].wFlags) {
1059 case DCB_NULL:
1060 dprintf_midi(stddeb,"Linux 'modOpen' // CALLBACK_NULL !\n");
1061 break;
1062 case DCB_WINDOW:
1063 dprintf_midi(stddeb,
1064 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1065 break;
1066 case DCB_TASK:
1067 dprintf_midi(stddeb,
1068 "Linux 'modOpen' // CALLBACK_TASK !\n");
1069 break;
1070 case DCB_FUNCTION:
1071 dprintf_midi(stddeb,
1072 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1073 break;
1075 MidiOutDev[index].lpQueueHdr = NULL;
1076 MidiOutDev[index].unixdev = midi;
1077 MidiOutDev[index].dwTotalPlayed = 0;
1078 MidiOutDev[index].bufsize = 0x3FFF;
1079 if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1080 dprintf_midi(stddeb,"Linux 'modOpen' // can't notify client !\n");
1081 return MMSYSERR_INVALPARAM;
1083 dprintf_midi(stddeb,
1084 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi);
1085 return MMSYSERR_NOERROR;
1086 #else
1087 return MMSYSERR_NOTENABLED;
1088 #endif
1092 /**************************************************************************
1093 * modClose [internal]
1095 static DWORD modClose(WORD wDevID)
1097 #if defined(linux) || defined(__FreeBSD__)
1098 int index = MMSYSTEM_DevIDToIndex(wDevID);
1099 dprintf_midi(stddeb, "modClose(%04X);\n", wDevID);
1100 if (MidiOutDev[index].unixdev == 0) {
1101 dprintf_midi(stddeb,"Linux 'modClose' // can't close !\n");
1102 return MMSYSERR_NOTENABLED;
1104 close(MidiOutDev[index].unixdev);
1105 MidiOutDev[index].unixdev = 0;
1106 MidiOutDev[index].bufsize = 0;
1107 if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1108 dprintf_midi(stddeb,"Linux 'modClose' // can't notify client !\n");
1109 return MMSYSERR_INVALPARAM;
1111 return MMSYSERR_NOERROR;
1112 #else
1113 return MMSYSERR_NOTENABLED;
1114 #endif
1117 /**************************************************************************
1118 * modData [internal]
1120 static DWORD modData(WORD wDevID, DWORD dwParam)
1122 #if defined(linux) || defined(__FreeBSD__)
1123 int index = MMSYSTEM_DevIDToIndex(wDevID);
1124 WORD event;
1125 dprintf_midi(stddeb,
1126 "modData(%04X, %08lX);\n", wDevID, dwParam);
1127 if (MidiOutDev[index].unixdev == 0) {
1128 dprintf_midi(stddeb,"Linux 'modData' // can't play !\n");
1129 return MIDIERR_NODEVICE;
1131 event = LOWORD(dwParam);
1132 if (write (MidiOutDev[index].unixdev,
1133 &event, sizeof(WORD)) != sizeof(WORD)) {
1134 dprintf_midi(stddeb,
1135 "modData() // error writting unixdev !\n");
1137 return MMSYSERR_NOTENABLED;
1138 #else
1139 return MMSYSERR_NOTENABLED;
1140 #endif
1143 /**************************************************************************
1144 * modLongData [internal]
1146 static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1148 #if defined(linux) || defined(__FreeBSD__)
1149 int index = MMSYSTEM_DevIDToIndex(wDevID);
1150 int count;
1151 LPWORD ptr;
1152 dprintf_midi(stddeb,
1153 "modLongData(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1154 if (MidiOutDev[index].unixdev == 0) {
1155 dprintf_midi(stddeb,"Linux 'modLongData' // can't play !\n");
1156 return MIDIERR_NODEVICE;
1158 if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
1159 if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
1160 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1161 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1162 lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1163 dprintf_midi(stddeb,
1164 "modLongData() // dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
1166 count = write (MidiOutDev[index].unixdev,
1167 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1169 ptr = (LPWORD)lpMidiHdr->lpData;
1170 for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
1171 if (write (MidiOutDev[index].unixdev, ptr,
1172 sizeof(WORD)) != sizeof(WORD)) break;
1173 ptr++;
1175 if (count != lpMidiHdr->dwBytesRecorded) {
1176 dprintf_midi(stddeb,
1177 "modLongData() // error writting unixdev #%d ! (%d != %ld)\n",
1178 MidiOutDev[index].unixdev, count, lpMidiHdr->dwBytesRecorded);
1179 return MMSYSERR_NOTENABLED;
1181 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1182 lpMidiHdr->dwFlags |= MHDR_DONE;
1183 if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
1184 dprintf_midi(stddeb,"Linux 'modLongData' // can't notify client !\n");
1185 return MMSYSERR_INVALPARAM;
1187 return MMSYSERR_NOERROR;
1188 #else
1189 return MMSYSERR_NOTENABLED;
1190 #endif
1193 /**************************************************************************
1194 * modPrepare [internal]
1196 static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1198 #if defined(linux) || defined(__FreeBSD__)
1199 int index = MMSYSTEM_DevIDToIndex(wDevID);
1200 dprintf_midi(stddeb,
1201 "modPrepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1202 if (MidiOutDev[index].unixdev == 0) {
1203 dprintf_midi(stddeb,"Linux 'modPrepare' // can't prepare !\n");
1204 return MMSYSERR_NOTENABLED;
1206 if (MidiOutDev[index].lpQueueHdr != NULL) {
1207 dprintf_midi(stddeb,"Linux 'modPrepare' // already prepare !\n");
1208 return MMSYSERR_NOTENABLED;
1210 MidiOutDev[index].dwTotalPlayed = 0;
1211 MidiOutDev[index].lpQueueHdr = lpMidiHdr;
1212 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1213 lpMidiHdr->dwFlags |= MHDR_PREPARED;
1214 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1215 return MMSYSERR_NOERROR;
1216 #else
1217 return MMSYSERR_NOTENABLED;
1218 #endif
1221 /**************************************************************************
1222 * modUnprepare [internal]
1224 static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1226 #if defined(linux) || defined(__FreeBSD__)
1227 int index = MMSYSTEM_DevIDToIndex(wDevID);
1228 dprintf_midi(stddeb,
1229 "modUnprepare(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
1230 if (MidiOutDev[index].unixdev == 0) {
1231 dprintf_midi(stddeb,"Linux 'modUnprepare' // can't unprepare !\n");
1232 return MMSYSERR_NOTENABLED;
1234 return MMSYSERR_NOERROR;
1235 #else
1236 return MMSYSERR_NOTENABLED;
1237 #endif
1240 /**************************************************************************
1241 * modReset [internal]
1243 static DWORD modReset(WORD wDevID)
1245 dprintf_midi(stddeb, "modReset(%04X);\n", wDevID);
1246 return MMSYSERR_NOTENABLED;
1250 /**************************************************************************
1251 * modMessage [sample driver]
1253 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1254 DWORD dwParam1, DWORD dwParam2)
1256 dprintf_midi(stddeb, "modMessage(%04X, %04X, %08lX, %08lX, %08lX);\n",
1257 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1258 switch(wMsg) {
1259 case MODM_OPEN:
1260 return modOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1261 case MODM_CLOSE:
1262 return modClose(wDevID);
1263 case MODM_DATA:
1264 return modData(wDevID, dwParam1);
1265 case MODM_LONGDATA:
1266 return modLongData(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1267 case MODM_PREPARE:
1268 return modPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1269 case MODM_UNPREPARE:
1270 return modUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1271 case MODM_GETDEVCAPS:
1272 return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1273 case MODM_GETNUMDEVS:
1274 return 1;
1275 case MODM_GETVOLUME:
1276 return 0;
1277 case MODM_SETVOLUME:
1278 return 0;
1279 case MODM_RESET:
1280 return modReset(wDevID);
1282 return MMSYSERR_NOTSUPPORTED;
1286 /**************************************************************************
1287 * MIDI_DriverProc [sample driver]
1289 LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
1290 DWORD dwParam1, DWORD dwParam2)
1292 #if defined(linux) || defined(__FreeBSD__)
1293 switch(wMsg) {
1294 case DRV_LOAD:
1295 return 1;
1296 case DRV_FREE:
1297 return 1;
1298 case DRV_OPEN:
1299 return 1;
1300 case DRV_CLOSE:
1301 return 1;
1302 case DRV_ENABLE:
1303 return 1;
1304 case DRV_DISABLE:
1305 return 1;
1306 case DRV_QUERYCONFIGURE:
1307 return 1;
1308 case DRV_CONFIGURE:
1309 MessageBox16(0, "Sample Midi Linux Driver !",
1310 "MMLinux Driver", MB_OK);
1311 return 1;
1312 case DRV_INSTALL:
1313 return DRVCNF_RESTART;
1314 case DRV_REMOVE:
1315 return DRVCNF_RESTART;
1316 case MCI_OPEN_DRIVER:
1317 case MCI_OPEN:
1318 return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
1319 case MCI_CLOSE_DRIVER:
1320 case MCI_CLOSE:
1321 return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1322 case MCI_PLAY:
1323 return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
1324 case MCI_RECORD:
1325 return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
1326 case MCI_STOP:
1327 return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1328 case MCI_SET:
1329 return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
1330 case MCI_PAUSE:
1331 return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1332 case MCI_RESUME:
1333 return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1334 case MCI_STATUS:
1335 return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1336 case MCI_GETDEVCAPS:
1337 return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1338 case MCI_INFO:
1339 return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
1340 default:
1341 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1343 #else
1344 return MMSYSERR_NOTENABLED;
1345 #endif
1349 /*-----------------------------------------------------------------------*/