Release 941210
[wine/multimedia.git] / multimedia / midi.c
blobdf240455a9ee51e236a2e08719db9f04552cc600
1 /*
2 * Sample MIDI Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
6 static char Copyright[] = "Copyright Martin Ayotte, 1994";
7 */
8 #ifndef WINELIB
9 #define BUILTIN_MMSYSTEM
10 #endif
12 #ifdef BUILTIN_MMSYSTEM
14 #include <stdio.h>
15 #include "win.h"
16 #include "user.h"
17 #include "driver.h"
18 #include "mmsystem.h"
19 #include <fcntl.h>
20 #include <sys/ioctl.h>
22 #include "stddebug.h"
23 /* #define DEBUG_MIDI */
25 #define DEBUG_MIDI
26 #include "debug.h"
29 #ifdef linux
30 #include <linux/soundcard.h>
31 #endif
33 #ifdef linux
34 #define MIDI_DEV "/dev/sequencer"
36 #ifdef SOUND_VERSION
37 #define IOCTL(a,b,c) ioctl(a,b,&c)
38 #else
39 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
40 #endif
42 #define MAX_MIDIINDRV 2
43 #define MAX_MIDIOUTDRV 2
44 #define MAX_MCIMIDIDRV 2
46 typedef struct {
47 int unixdev;
48 int state;
49 DWORD bufsize;
50 MIDIOPENDESC midiDesc;
51 WORD wFlags;
52 LPMIDIHDR lpQueueHdr;
53 DWORD dwTotalPlayed;
54 } LINUX_MIDIIN;
56 typedef struct {
57 int unixdev;
58 int state;
59 DWORD bufsize;
60 MIDIOPENDESC midiDesc;
61 WORD wFlags;
62 LPMIDIHDR lpQueueHdr;
63 DWORD dwTotalPlayed;
64 } LINUX_MIDIOUT;
66 typedef struct {
67 int nUseCount; /* Incremented for each shared open */
68 BOOL fShareable; /* TRUE if first open was shareable */
69 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
70 HANDLE hCallback; /* Callback handle for pending notification */
71 HMMIO hFile; /* mmio file handle open as Element */
72 DWORD dwBeginData;
73 DWORD dwTotalLen;
74 WORD wFormat;
75 WORD nTracks;
76 WORD nTempo;
77 MCI_OPEN_PARMS openParms;
78 MIDIHDR MidiHdr;
79 WORD dwStatus;
80 } LINUX_MCIMIDI;
82 static LINUX_MIDIIN MidiInDev[MAX_MIDIINDRV];
83 static LINUX_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
84 static LINUX_MCIMIDI MCIMidiDev[MAX_MCIMIDIDRV];
85 #endif
87 DWORD MIDI_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms);
88 DWORD MIDI_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
89 DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
90 DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
91 DWORD MIDI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
92 DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
93 DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
94 DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms);
95 DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms);
96 DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
97 DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms);
99 DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags);
100 DWORD modClose(WORD wDevID);
101 DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize);
102 DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize);
103 DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize);
104 DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize);
105 DWORD modData(WORD wDevID, DWORD dwParam);
107 DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags);
108 DWORD midClose(WORD wDevID);
109 DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize);
111 /**************************************************************************
112 * MIDI_NotifyClient [internal]
114 DWORD MIDI_NotifyClient(UINT wDevID, WORD wMsg,
115 DWORD dwParam1, DWORD dwParam2)
117 #ifdef linux
118 if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
119 MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags,
120 MidiInDev[wDevID].midiDesc.hMidi, wMsg,
121 MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
122 printf("MIDI_NotifyClient // can't notify client !\n");
123 return MMSYSERR_NOERROR;
125 #else
126 return MMSYSERR_NOTENABLED;
127 #endif
131 /**************************************************************************
132 * AUDIO_DriverProc [sample driver]
134 LRESULT MIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
135 DWORD dwParam1, DWORD dwParam2)
137 #ifdef linux
138 switch(wMsg) {
139 case DRV_LOAD:
140 return (LRESULT)1L;
141 case DRV_FREE:
142 return (LRESULT)1L;
143 case DRV_OPEN:
144 return (LRESULT)1L;
145 case DRV_CLOSE:
146 return (LRESULT)1L;
147 case DRV_ENABLE:
148 return (LRESULT)1L;
149 case DRV_DISABLE:
150 return (LRESULT)1L;
151 case DRV_QUERYCONFIGURE:
152 return (LRESULT)1L;
153 case DRV_CONFIGURE:
154 MessageBox((HWND)NULL, "Sample Midi Linux Driver !",
155 "MMLinux Driver", MB_OK);
156 return (LRESULT)1L;
157 case DRV_INSTALL:
158 return (LRESULT)DRVCNF_RESTART;
159 case DRV_REMOVE:
160 return (LRESULT)DRVCNF_RESTART;
161 case MCI_OPEN_DRIVER:
162 case MCI_OPEN:
163 return MIDI_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
164 case MCI_CLOSE_DRIVER:
165 case MCI_CLOSE:
166 return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
167 case MCI_PLAY:
168 return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
169 case MCI_RECORD:
170 return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
171 case MCI_STOP:
172 return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
173 case MCI_SET:
174 return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
175 case MCI_PAUSE:
176 return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
177 case MCI_RESUME:
178 return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
179 case MCI_STATUS:
180 return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
181 case MCI_GETDEVCAPS:
182 return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
183 case MCI_INFO:
184 return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
185 default:
186 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
188 #else
189 return MMSYSERR_NOTENABLED;
190 #endif
194 /**************************************************************************
195 * MIDI_ReadByte [internal]
197 DWORD MIDI_ReadByte(UINT wDevID, BYTE FAR *lpbyt)
199 if (lpbyt != NULL) {
200 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
201 (long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
202 return 0;
205 printf("MIDI_ReadByte // error reading wDevID=%d \n", wDevID);
206 return MCIERR_INTERNAL;
210 /**************************************************************************
211 * MIDI_ReadWord [internal]
213 DWORD MIDI_ReadWord(UINT wDevID, LPWORD lpw)
215 BYTE hibyte, lobyte;
216 if (lpw != NULL) {
217 if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
218 if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
219 *lpw = ((WORD)hibyte << 8) + lobyte;
220 return 0;
224 printf("MIDI_ReadWord // error reading wDevID=%d \n", wDevID);
225 return MCIERR_INTERNAL;
229 /**************************************************************************
230 * MIDI_ReadLong [internal]
232 DWORD MIDI_ReadLong(UINT wDevID, LPDWORD lpdw)
234 WORD hiword, loword;
235 BYTE hibyte, lobyte;
236 if (lpdw != NULL) {
237 if (MIDI_ReadWord(wDevID, &hiword) == 0) {
238 if (MIDI_ReadWord(wDevID, &loword) == 0) {
239 *lpdw = MAKELONG(loword, hiword);
240 return 0;
244 printf("MIDI_ReadLong // error reading wDevID=%d \n", wDevID);
245 return MCIERR_INTERNAL;
249 /**************************************************************************
250 * MIDI_ReadVaryLen [internal]
252 DWORD MIDI_ReadVaryLen(UINT wDevID, LPDWORD lpdw)
254 BYTE byte;
255 DWORD value;
256 if (lpdw == NULL) return MCIERR_INTERNAL;
257 if (MIDI_ReadByte(wDevID, &byte) != 0) {
258 printf("MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
259 return MCIERR_INTERNAL;
261 value = (DWORD)(byte & 0x7F);
262 while (byte & 0x80) {
263 if (MIDI_ReadByte(wDevID, &byte) != 0) {
264 printf("MIDI_ReadVaryLen // error reading wDevID=%d \n", wDevID);
265 return MCIERR_INTERNAL;
267 value = (value << 7) + (byte & 0x7F);
269 *lpdw = value;
271 printf("MIDI_ReadVaryLen // val=%08lX \n", value);
273 return 0;
277 /**************************************************************************
278 * MIDI_ReadMThd [internal]
280 DWORD MIDI_ReadMThd(UINT wDevID, DWORD dwOffset)
282 DWORD toberead;
283 FOURCC fourcc;
284 dprintf_midi(stddeb, "MIDI_ReadMThd(%04X, %08X);\n", wDevID, dwOffset);
285 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
286 printf("MIDI_ReadMThd // can't seek at %08X begin of 'MThd' \n", dwOffset);
287 return MCIERR_INTERNAL;
289 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
290 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
291 return MCIERR_INTERNAL;
293 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
294 return MCIERR_INTERNAL;
296 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0) {
297 return MCIERR_INTERNAL;
299 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0) {
300 return MCIERR_INTERNAL;
302 if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0) {
303 return MCIERR_INTERNAL;
305 printf("MIDI_ReadMThd // toberead=%08X, wFormat=%04X nTracks=%04X nTempo=%04X\n",
306 toberead, MCIMidiDev[wDevID].wFormat,
307 MCIMidiDev[wDevID].nTracks,
308 MCIMidiDev[wDevID].nTempo);
309 toberead -= 3 * sizeof(WORD);
311 ntrks = read16bit ();
312 Mf_division = division = read16bit ();
314 return 0;
318 DWORD MIDI_ReadMTrk(UINT wDevID, DWORD dwOffset)
320 DWORD toberead;
321 FOURCC fourcc;
322 if (mmioSeek(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
323 printf("MIDI_ReadMTrk // can't seek at %08X begin of 'MThd' \n", dwOffset);
325 if (mmioRead(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
326 (long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
327 return MCIERR_INTERNAL;
329 if (MIDI_ReadLong(wDevID, &toberead) != 0) {
330 return MCIERR_INTERNAL;
332 printf("MIDI_ReadMTrk // toberead=%08X\n", toberead);
333 toberead -= 3 * sizeof(WORD);
334 MCIMidiDev[wDevID].dwTotalLen = toberead;
335 return 0;
339 /**************************************************************************
340 * MIDI_mciOpen [internal]
342 DWORD MIDI_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
344 #ifdef linux
345 int hFile;
346 UINT wDevID;
347 OFSTRUCT OFstruct;
348 MIDIOPENDESC MidiDesc;
349 DWORD dwRet;
350 DWORD dwOffset;
351 char str[128];
352 LPSTR ptr;
353 DWORD toberead;
354 #ifdef DEBUG_MIDI
355 printf("MIDI_mciOpen(%08X, %08X)\n", dwFlags, lpParms);
356 #endif
357 if (lpParms == NULL) return MCIERR_INTERNAL;
358 wDevID = lpParms->wDeviceID;
359 if (MCIMidiDev[wDevID].nUseCount > 0) {
360 /* The driver already open on this channel */
361 /* If the driver was opened shareable before and this open specifies */
362 /* shareable then increment the use count */
363 if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
364 ++MCIMidiDev[wDevID].nUseCount;
365 else
366 return MCIERR_MUST_USE_SHAREABLE;
368 else {
369 MCIMidiDev[wDevID].nUseCount = 1;
370 MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
372 if (dwFlags & MCI_OPEN_ELEMENT) {
373 printf("MIDI_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
374 lpParms->lpstrElementName);
375 /* printf("MIDI_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
376 if (strlen(lpParms->lpstrElementName) > 0) {
377 strcpy(str, lpParms->lpstrElementName);
378 AnsiUpper(str);
379 MCIMidiDev[wDevID].hFile = mmioOpen(str, NULL,
380 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
381 if (MCIMidiDev[wDevID].hFile == 0) {
382 printf("MIDI_mciOpen // can't find file='%s' !\n", str);
383 return MCIERR_FILE_NOT_FOUND;
386 else
387 MCIMidiDev[wDevID].hFile = 0;
389 printf("MIDI_mciOpen // hFile=%u\n", MCIMidiDev[wDevID].hFile);
390 memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS));
391 MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
392 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
393 MCIMidiDev[wDevID].dwBeginData = 0;
394 MCIMidiDev[wDevID].dwTotalLen = 0;
395 MidiDesc.hMidi = 0;
396 if (MCIMidiDev[wDevID].hFile != 0) {
397 MMCKINFO mmckInfo;
398 MMCKINFO ckMainRIFF;
399 if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
400 return MCIERR_INTERNAL;
402 #ifdef DEBUG_MIDI
403 printf("MIDI_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
404 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
405 ckMainRIFF.cksize);
406 #endif
407 dwOffset = 0;
408 if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
409 printf("MIDI_mciOpen // is a 'RMID' file \n");
410 dwOffset = ckMainRIFF.dwDataOffset;
412 if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
413 printf("MIDI_mciOpen // unknown format !\n");
414 return MCIERR_INTERNAL;
416 if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
417 printf("MIDI_mciOpen // can't read 'MThd' header \n");
418 return MCIERR_INTERNAL;
420 dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
421 if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
422 printf("MIDI_mciOpen // can't read 'MTrk' header \n");
423 return MCIERR_INTERNAL;
425 dwOffset = mmioSeek(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
426 MCIMidiDev[wDevID].dwBeginData = dwOffset;
427 #ifdef DEBUG_MIDI
428 printf("MIDI_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
429 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
430 mmckInfo.cksize);
431 #endif
433 dwRet = modMessage(0, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
434 dwRet = midMessage(0, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
435 return 0;
436 #else
437 return MMSYSERR_NOTENABLED;
438 #endif
442 /**************************************************************************
443 * MIDI_mciClose [internal]
445 DWORD MIDI_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
447 #ifdef linux
448 DWORD dwRet;
449 #ifdef DEBUG_MIDI
450 printf("MIDI_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
451 #endif
452 if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
453 MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
455 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
456 MCIMidiDev[wDevID].nUseCount--;
457 if (MCIMidiDev[wDevID].nUseCount == 0) {
458 if (MCIMidiDev[wDevID].hFile != 0) {
459 mmioClose(MCIMidiDev[wDevID].hFile, 0);
460 MCIMidiDev[wDevID].hFile = 0;
461 printf("MIDI_mciClose // hFile closed !\n");
463 dwRet = modMessage(0, MODM_CLOSE, 0, 0L, 0L);
464 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
465 dwRet = midMessage(0, MIDM_CLOSE, 0, 0L, 0L);
466 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
468 return 0;
469 #else
470 return 0;
471 #endif
475 /**************************************************************************
476 * MIDI_mciPlay [internal]
478 DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
480 #ifdef linux
481 int count;
482 int start, end;
483 LPMIDIHDR lpMidiHdr;
484 DWORD dwData;
485 LPWORD ptr;
486 DWORD dwRet;
487 #ifdef DEBUG_MIDI
488 printf("MIDI_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
489 #endif
490 if (MCIMidiDev[wDevID].hFile == 0) {
491 printf("MIDI_mciPlay // can't find file='%s' !\n",
492 MCIMidiDev[wDevID].openParms.lpstrElementName);
493 return MCIERR_FILE_NOT_FOUND;
495 start = 1; end = 99999;
496 if (dwFlags & MCI_FROM) {
497 start = lpParms->dwFrom;
498 printf("MIDI_mciPlay // MCI_FROM=%d \n", start);
500 if (dwFlags & MCI_TO) {
501 end = lpParms->dwTo;
502 printf("MIDI_mciPlay // MCI_TO=%d \n", end);
504 /**/
505 if (dwFlags & MCI_NOTIFY) {
506 printf("MIDI_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
507 switch(fork()) {
508 case -1:
509 printf("MIDI_mciPlay // Can't 'fork' process !\n");
510 break;
511 case 0:
512 printf("MIDI_mciPlay // process started ! play in background ...\n");
513 break;
514 default:
515 printf("MIDI_mciPlay // process started ! return to caller...\n");
516 return 0;
519 /**/
520 lpMidiHdr = &MCIMidiDev[wDevID].MidiHdr;
521 lpMidiHdr->lpData = (LPSTR) malloc(1200);
522 if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
523 lpMidiHdr->dwBufferLength = 1024;
524 lpMidiHdr->dwUser = 0L;
525 lpMidiHdr->dwFlags = 0L;
526 dwRet = modMessage(0, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
527 /* printf("MIDI_mciPlay // after MODM_PREPARE \n"); */
528 MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
529 while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
530 printf("MIDI_mciPlay // MCIMidiDev[wDevID].dwStatus=%p %d\n",
531 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
532 ptr = (LPWORD)lpMidiHdr->lpData;
533 for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
534 if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
535 *ptr = LOWORD(dwData);
538 count = mmioRead(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
540 if (count < 1) break;
541 lpMidiHdr->dwBytesRecorded = count;
542 #ifdef DEBUG_MIDI
543 printf("MIDI_mciPlay // before MODM_LONGDATA lpMidiHdr=%08X dwBytesRecorded=%u\n",
544 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
545 #endif
546 dwRet = modMessage(0, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
548 dwRet = modMessage(0, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
549 if (lpMidiHdr->lpData != NULL) {
550 free(lpMidiHdr->lpData);
551 lpMidiHdr->lpData = NULL;
553 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
554 if (dwFlags & MCI_NOTIFY) {
555 #ifdef DEBUG_MIDI
556 printf("MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
557 #endif
558 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
559 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
560 exit(1);
562 return 0;
563 #else
564 return MMSYSERR_NOTENABLED;
565 #endif
569 /**************************************************************************
570 * MIDI_mciRecord [internal]
572 DWORD MIDI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
574 #ifdef linux
575 int count;
576 int start, end;
577 LPMIDIHDR lpMidiHdr;
578 DWORD dwRet;
579 #ifdef DEBUG_MIDI
580 printf("MIDI_mciRecord(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
581 #endif
582 if (MCIMidiDev[wDevID].hFile == 0) {
583 printf("MIDI_mciRecord // can't find file='%s' !\n",
584 MCIMidiDev[wDevID].openParms.lpstrElementName);
585 return MCIERR_FILE_NOT_FOUND;
587 start = 1; end = 99999;
588 if (dwFlags & MCI_FROM) {
589 start = lpParms->dwFrom;
590 printf("MIDI_mciRecord // MCI_FROM=%d \n", start);
592 if (dwFlags & MCI_TO) {
593 end = lpParms->dwTo;
594 printf("MIDI_mciRecord // MCI_TO=%d \n", end);
596 lpMidiHdr = &MCIMidiDev[wDevID].MidiHdr;
597 lpMidiHdr->lpData = (LPSTR) malloc(1200);
598 lpMidiHdr->dwBufferLength = 1024;
599 lpMidiHdr->dwUser = 0L;
600 lpMidiHdr->dwFlags = 0L;
601 dwRet = midMessage(0, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
602 printf("MIDI_mciRecord // after MIDM_PREPARE \n");
603 MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
604 while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
605 printf("MIDI_mciRecord // MCIMidiDev[wDevID].dwStatus=%p %d\n",
606 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
607 lpMidiHdr->dwBytesRecorded = 0;
608 dwRet = midMessage(0, MIDM_START, 0, 0L, 0L);
609 printf("MIDI_mciRecord // after MIDM_START lpMidiHdr=%08X dwBytesRecorded=%u\n",
610 lpMidiHdr, lpMidiHdr->dwBytesRecorded);
611 if (lpMidiHdr->dwBytesRecorded == 0) break;
613 printf("MIDI_mciRecord // before MIDM_UNPREPARE \n");
614 dwRet = midMessage(0, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
615 printf("MIDI_mciRecord // after MIDM_UNPREPARE \n");
616 if (lpMidiHdr->lpData != NULL) {
617 free(lpMidiHdr->lpData);
618 lpMidiHdr->lpData = NULL;
620 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
621 if (dwFlags & MCI_NOTIFY) {
622 #ifdef DEBUG_MIDI
623 printf("MIDI_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
624 #endif
625 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
626 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
628 return 0;
629 #else
630 return MMSYSERR_NOTENABLED;
631 #endif
635 /**************************************************************************
636 * MIDI_mciStop [internal]
638 DWORD MIDI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
640 #ifdef linux
641 #ifdef DEBUG_MIDI
642 printf("MIDI_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
643 #endif
644 if (lpParms == NULL) return MCIERR_INTERNAL;
645 MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
646 printf("MIDI_mciStop // MCIMidiDev[wDevID].dwStatus=%p %d\n",
647 &MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
648 return 0;
649 #else
650 return MCIERR_INTERNAL;
651 #endif
655 /**************************************************************************
656 * MIDI_mciPause [internal]
658 DWORD MIDI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
660 #ifdef linux
661 #ifdef DEBUG_MIDI
662 printf("MIDI_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
663 #endif
664 if (lpParms == NULL) return MCIERR_INTERNAL;
665 return 0;
666 #else
667 return MCIERR_INTERNAL;
668 #endif
672 /**************************************************************************
673 * MIDI_mciResume [internal]
675 DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
677 #ifdef linux
678 #ifdef DEBUG_MIDI
679 printf("MIDI_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
680 #endif
681 if (lpParms == NULL) return MCIERR_INTERNAL;
682 return 0;
683 #else
684 return MCIERR_INTERNAL;
685 #endif
689 /**************************************************************************
690 * MIDI_mciSet [internal]
692 DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
694 #ifdef linux
695 #ifdef DEBUG_MIDI
696 printf("MIDI_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
697 #endif
698 if (lpParms == NULL) return MCIERR_INTERNAL;
699 #ifdef DEBUG_MIDI
700 printf("MIDI_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
701 printf("MIDI_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
702 #endif
703 if (dwFlags & MCI_SET_TIME_FORMAT) {
704 switch (lpParms->dwTimeFormat) {
705 case MCI_FORMAT_MILLISECONDS:
706 printf("MIDI_mciSet // MCI_FORMAT_MILLISECONDS !\n");
707 break;
708 case MCI_FORMAT_BYTES:
709 printf("MIDI_mciSet // MCI_FORMAT_BYTES !\n");
710 break;
711 case MCI_FORMAT_SAMPLES:
712 printf("MIDI_mciSet // MCI_FORMAT_SAMPLES !\n");
713 break;
714 default:
715 printf("MIDI_mciSet // bad time format !\n");
716 return MCIERR_BAD_TIME_FORMAT;
719 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
720 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
721 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
722 if (dwFlags & MCI_SET_AUDIO) {
723 printf("MIDI_mciSet // MCI_SET_AUDIO !\n");
725 if (dwFlags && MCI_SET_ON) {
726 printf("MIDI_mciSet // MCI_SET_ON !\n");
727 if (dwFlags && MCI_SET_AUDIO_LEFT) {
728 printf("MIDI_mciSet // MCI_SET_AUDIO_LEFT !\n");
730 if (dwFlags && MCI_SET_AUDIO_RIGHT) {
731 printf("MIDI_mciSet // MCI_SET_AUDIO_RIGHT !\n");
734 if (dwFlags & MCI_SET_OFF) {
735 printf("MIDI_mciSet // MCI_SET_OFF !\n");
737 if (dwFlags & MCI_SEQ_SET_MASTER) {
738 printf("MIDI_mciSet // MCI_SEQ_SET_MASTER !\n");
740 if (dwFlags & MCI_SEQ_SET_SLAVE) {
741 printf("MIDI_mciSet // MCI_SEQ_SET_SLAVE !\n");
743 if (dwFlags & MCI_SEQ_SET_OFFSET) {
744 printf("MIDI_mciSet // MCI_SEQ_SET_OFFSET !\n");
746 if (dwFlags & MCI_SEQ_SET_PORT) {
747 printf("MIDI_mciSet // MCI_SEQ_SET_PORT !\n");
749 if (dwFlags & MCI_SEQ_SET_TEMPO) {
750 printf("MIDI_mciSet // MCI_SEQ_SET_TEMPO !\n");
752 return 0;
753 #else
754 return MCIERR_INTERNAL;
755 #endif
759 /**************************************************************************
760 * MIDI_mciStatus [internal]
762 DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
764 #ifdef linux
765 #ifdef DEBUG_MIDI
766 printf("MIDI_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
767 #endif
768 if (lpParms == NULL) return MCIERR_INTERNAL;
769 if (dwFlags & MCI_STATUS_ITEM) {
770 switch(lpParms->dwItem) {
771 case MCI_STATUS_CURRENT_TRACK:
772 lpParms->dwReturn = 1;
773 break;
774 case MCI_STATUS_LENGTH:
775 lpParms->dwReturn = 5555;
776 if (dwFlags & MCI_TRACK) {
777 lpParms->dwTrack = 1;
778 lpParms->dwReturn = 2222;
780 break;
781 case MCI_STATUS_MODE:
782 lpParms->dwReturn = MCI_MODE_STOP;
783 break;
784 case MCI_STATUS_MEDIA_PRESENT:
785 printf("MIDI_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
786 lpParms->dwReturn = TRUE;
787 break;
788 case MCI_STATUS_NUMBER_OF_TRACKS:
789 lpParms->dwReturn = 1;
790 break;
791 case MCI_STATUS_POSITION:
792 lpParms->dwReturn = 3333;
793 if (dwFlags & MCI_STATUS_START) {
794 lpParms->dwItem = 1;
796 if (dwFlags & MCI_TRACK) {
797 lpParms->dwTrack = 1;
798 lpParms->dwReturn = 777;
800 break;
801 case MCI_STATUS_READY:
802 printf("MIDI_mciStatus // MCI_STATUS_READY !\n");
803 lpParms->dwReturn = TRUE;
804 break;
805 case MCI_STATUS_TIME_FORMAT:
806 printf("MIDI_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
807 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
808 break;
809 case MCI_SEQ_STATUS_DIVTYPE:
810 printf("MIDI_mciStatus // MCI_SEQ_STATUS_DIVTYPE !\n");
811 lpParms->dwReturn = 0;
812 break;
813 case MCI_SEQ_STATUS_MASTER:
814 printf("MIDI_mciStatus // MCI_SEQ_STATUS_MASTER !\n");
815 lpParms->dwReturn = 0;
816 break;
817 case MCI_SEQ_STATUS_SLAVE:
818 printf("MIDI_mciStatus // MCI_SEQ_STATUS_SLAVE !\n");
819 lpParms->dwReturn = 0;
820 break;
821 case MCI_SEQ_STATUS_OFFSET:
822 printf("MIDI_mciStatus // MCI_SEQ_STATUS_OFFSET !\n");
823 lpParms->dwReturn = 0;
824 break;
825 case MCI_SEQ_STATUS_PORT:
826 printf("MIDI_mciStatus // MCI_SEQ_STATUS_PORT !\n");
827 lpParms->dwReturn = 0;
828 break;
829 case MCI_SEQ_STATUS_TEMPO:
830 printf("MIDI_mciStatus // MCI_SEQ_STATUS_TEMPO !\n");
831 lpParms->dwReturn = 0;
832 break;
833 default:
834 printf("MIDI_mciStatus // unknowm command %04X !\n", lpParms->dwItem);
835 return MCIERR_UNRECOGNIZED_COMMAND;
838 if (dwFlags & MCI_NOTIFY) {
839 printf("MIDI_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
840 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
841 MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
843 return 0;
844 #else
845 return MCIERR_INTERNAL;
846 #endif
849 /**************************************************************************
850 * MIDI_mciGetDevCaps [internal]
852 DWORD MIDI_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
853 LPMCI_GETDEVCAPS_PARMS lpParms)
855 #ifdef linux
856 printf("MIDI_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
857 if (lpParms == NULL) return MCIERR_INTERNAL;
858 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
859 switch(lpParms->dwItem) {
860 case MCI_GETDEVCAPS_CAN_RECORD:
861 lpParms->dwReturn = TRUE;
862 break;
863 case MCI_GETDEVCAPS_HAS_AUDIO:
864 lpParms->dwReturn = TRUE;
865 break;
866 case MCI_GETDEVCAPS_HAS_VIDEO:
867 lpParms->dwReturn = FALSE;
868 break;
869 case MCI_GETDEVCAPS_DEVICE_TYPE:
870 lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
871 break;
872 case MCI_GETDEVCAPS_USES_FILES:
873 lpParms->dwReturn = TRUE;
874 break;
875 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
876 lpParms->dwReturn = TRUE;
877 break;
878 case MCI_GETDEVCAPS_CAN_EJECT:
879 lpParms->dwReturn = FALSE;
880 break;
881 case MCI_GETDEVCAPS_CAN_PLAY:
882 lpParms->dwReturn = TRUE;
883 break;
884 case MCI_GETDEVCAPS_CAN_SAVE:
885 lpParms->dwReturn = FALSE;
886 break;
887 default:
888 return MCIERR_UNRECOGNIZED_COMMAND;
891 return 0;
892 #else
893 return MCIERR_INTERNAL;
894 #endif
897 /**************************************************************************
898 * MIDI_mciInfo [internal]
900 DWORD MIDI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
902 #ifdef linux
903 printf("MIDI_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
904 if (lpParms == NULL) return MCIERR_INTERNAL;
905 lpParms->lpstrReturn = NULL;
906 switch(dwFlags) {
907 case MCI_INFO_PRODUCT:
908 lpParms->lpstrReturn = "Linux Sound System 0.5";
909 break;
910 case MCI_INFO_FILE:
911 lpParms->lpstrReturn = "FileName";
912 break;
913 default:
914 return MCIERR_UNRECOGNIZED_COMMAND;
916 if (lpParms->lpstrReturn != NULL)
917 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
918 else
919 lpParms->dwRetSize = 0;
920 return 0;
921 #else
922 return MCIERR_INTERNAL;
923 #endif
927 /*-----------------------------------------------------------------------*/
930 /**************************************************************************
931 * midGetDevCaps [internal]
933 DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS lpCaps, DWORD dwSize)
935 printf("midGetDevCaps(%u, %08X, %08X);\n", wDevID, lpCaps, dwSize);
936 return MMSYSERR_NOTENABLED;
939 /**************************************************************************
940 * midOpen [internal]
942 DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
944 #ifdef linux
945 int midi;
946 dprintf_midi(stddeb,
947 "midOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
948 if (lpDesc == NULL) {
949 fprintf(stderr,"Linux 'midOpen' // Invalid Parameter !\n");
950 return MMSYSERR_INVALPARAM;
952 if (wDevID >= MAX_MIDIINDRV) {
953 fprintf(stderr,"Linux 'midOpen' // MAX_MIDIINDRV reached !\n");
954 return MMSYSERR_ALLOCATED;
956 MidiInDev[wDevID].unixdev = 0;
957 midi = open (MIDI_DEV, O_RDONLY, 0);
958 if (midi == -1) {
959 fprintf(stderr,"Linux 'midOpen' // can't open !\n");
960 return MMSYSERR_NOTENABLED;
962 MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
963 switch(MidiInDev[wDevID].wFlags) {
964 case DCB_NULL:
965 fprintf(stderr,"Linux 'midOpen' // CALLBACK_NULL !\n");
966 break;
967 case DCB_WINDOW:
968 dprintf_midi(stddeb,
969 "Linux 'midOpen' // CALLBACK_WINDOW !\n");
970 break;
971 case DCB_TASK:
972 dprintf_midi(stddeb,
973 "Linux 'midOpen' // CALLBACK_TASK !\n");
974 break;
975 case DCB_FUNCTION:
976 dprintf_midi(stddeb,
977 "Linux 'midOpen' // CALLBACK_FUNCTION !\n");
978 break;
980 MidiInDev[wDevID].lpQueueHdr = NULL;
981 MidiInDev[wDevID].unixdev = midi;
982 MidiInDev[wDevID].dwTotalPlayed = 0;
983 MidiInDev[wDevID].bufsize = 0x3FFF;
984 if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
985 fprintf(stderr,"Linux 'midOpen' // can't notify client !\n");
986 return MMSYSERR_INVALPARAM;
988 return MMSYSERR_NOERROR;
989 #else
990 return MMSYSERR_NOTENABLED;
991 #endif
994 /**************************************************************************
995 * midClose [internal]
997 DWORD midClose(WORD wDevID)
999 #ifdef linux
1000 dprintf_midi(stddeb,"midClose(%u);\n", wDevID);
1001 if (MidiInDev[wDevID].unixdev == 0) {
1002 fprintf(stderr,"Linux 'midClose' // can't close !\n");
1003 return MMSYSERR_NOTENABLED;
1005 close(MidiInDev[wDevID].unixdev);
1006 MidiInDev[wDevID].unixdev = 0;
1007 MidiInDev[wDevID].bufsize = 0;
1008 if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1009 fprintf(stderr,"Linux 'midClose' // can't notify client !\n");
1010 return MMSYSERR_INVALPARAM;
1012 return MMSYSERR_NOERROR;
1013 #else
1014 return MMSYSERR_NOTENABLED;
1015 #endif
1018 /**************************************************************************
1019 * midAddBuffer [internal]
1021 DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1023 printf("midAddBuffer(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1024 return MMSYSERR_NOTENABLED;
1027 /**************************************************************************
1028 * midPrepare [internal]
1030 DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1032 printf("midPrepare(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1033 return MMSYSERR_NOTENABLED;
1036 /**************************************************************************
1037 * midUnprepare [internal]
1039 DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1041 printf("midUnprepare(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1042 return MMSYSERR_NOTENABLED;
1045 /**************************************************************************
1046 * midReset [internal]
1048 DWORD midReset(WORD wDevID)
1050 printf("midReset(%u);\n", wDevID);
1051 return MMSYSERR_NOTENABLED;
1055 /**************************************************************************
1056 * midStart [internal]
1058 DWORD midStart(WORD wDevID)
1060 printf("midStart(%u);\n", wDevID);
1061 return MMSYSERR_NOTENABLED;
1065 /**************************************************************************
1066 * midStop [internal]
1068 DWORD midStop(WORD wDevID)
1070 printf("midStop(%u);\n", wDevID);
1071 return MMSYSERR_NOTENABLED;
1075 /**************************************************************************
1076 * midMessage [sample driver]
1078 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1079 DWORD dwParam1, DWORD dwParam2)
1081 printf("midMessage(%u, %04X, %08X, %08X, %08X);\n",
1082 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1083 switch(wMsg) {
1084 case MIDM_OPEN:
1085 return midOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
1086 case MIDM_CLOSE:
1087 return midClose(wDevID);
1088 case MIDM_ADDBUFFER:
1089 return midAddBuffer(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1090 case MIDM_PREPARE:
1091 return midPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1092 case MIDM_UNPREPARE:
1093 return midUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1094 case MIDM_GETDEVCAPS:
1095 return midGetDevCaps(wDevID, (LPMIDIINCAPS)dwParam1, dwParam2);
1096 case MIDM_GETNUMDEVS:
1097 return 1L;
1098 case MIDM_RESET:
1099 return midReset(wDevID);
1100 case MIDM_START:
1101 return midStart(wDevID);
1102 case MIDM_STOP:
1103 return midStop(wDevID);
1105 return MMSYSERR_NOTSUPPORTED;
1110 /*-----------------------------------------------------------------------*/
1113 /**************************************************************************
1114 * modGetDevCaps [internal]
1116 DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS lpCaps, DWORD dwSize)
1118 printf("modGetDevCaps(%u, %08X, %08X);\n", wDevID, lpCaps, dwSize);
1119 return MMSYSERR_NOTENABLED;
1123 /**************************************************************************
1124 * modOpen [internal]
1126 DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
1128 #ifdef linux
1129 int midi;
1130 dprintf_midi(stddeb,
1131 "modOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
1132 if (lpDesc == NULL) {
1133 fprintf(stderr,"Linux 'modOpen' // Invalid Parameter !\n");
1134 return MMSYSERR_INVALPARAM;
1136 if (wDevID >= MAX_MIDIOUTDRV) {
1137 fprintf(stderr,"Linux 'modOpen' // MAX_MIDIOUTDRV reached !\n");
1138 return MMSYSERR_ALLOCATED;
1140 MidiOutDev[wDevID].unixdev = 0;
1141 midi = open (MIDI_DEV, O_WRONLY, 0);
1142 if (midi == -1) {
1143 fprintf(stderr,"Linux 'modOpen' // can't open !\n");
1144 return MMSYSERR_NOTENABLED;
1146 MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1147 switch(MidiOutDev[wDevID].wFlags) {
1148 case DCB_NULL:
1149 fprintf(stderr,"Linux 'modOpen' // CALLBACK_NULL !\n");
1150 break;
1151 case DCB_WINDOW:
1152 dprintf_midi(stddeb,
1153 "Linux 'modOpen' // CALLBACK_WINDOW !\n");
1154 break;
1155 case DCB_TASK:
1156 dprintf_midi(stddeb,
1157 "Linux 'modOpen' // CALLBACK_TASK !\n");
1158 break;
1159 case DCB_FUNCTION:
1160 dprintf_midi(stddeb,
1161 "Linux 'modOpen' // CALLBACK_FUNCTION !\n");
1162 break;
1164 MidiOutDev[wDevID].lpQueueHdr = NULL;
1165 MidiOutDev[wDevID].unixdev = midi;
1166 MidiOutDev[wDevID].dwTotalPlayed = 0;
1167 MidiOutDev[wDevID].bufsize = 0x3FFF;
1168 if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1169 fprintf(stderr,"Linux 'modOpen' // can't notify client !\n");
1170 return MMSYSERR_INVALPARAM;
1172 dprintf_midi(stddeb,
1173 "Linux 'modOpen' // Succesful unixdev=%d !\n", midi);
1174 return MMSYSERR_NOERROR;
1175 #else
1176 return MMSYSERR_NOTENABLED;
1177 #endif
1181 /**************************************************************************
1182 * modClose [internal]
1184 DWORD modClose(WORD wDevID)
1186 #ifdef linux
1187 dprintf_midi(stddeb,"modClose(%u);\n", wDevID);
1188 if (MidiOutDev[wDevID].unixdev == 0) {
1189 fprintf(stderr,"Linux 'modClose' // can't close !\n");
1190 return MMSYSERR_NOTENABLED;
1192 close(MidiOutDev[wDevID].unixdev);
1193 MidiOutDev[wDevID].unixdev = 0;
1194 MidiOutDev[wDevID].bufsize = 0;
1195 if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1196 fprintf(stderr,"Linux 'modClose' // can't notify client !\n");
1197 return MMSYSERR_INVALPARAM;
1199 return MMSYSERR_NOERROR;
1200 #else
1201 return MMSYSERR_NOTENABLED;
1202 #endif
1205 /**************************************************************************
1206 * modData [internal]
1208 DWORD modData(WORD wDevID, DWORD dwParam)
1210 WORD event;
1211 dprintf_midi(stddeb,
1212 "modData(%u, %08X);\n", wDevID, dwParam);
1213 if (MidiOutDev[wDevID].unixdev == 0) {
1214 fprintf(stderr,"Linux 'modData' // can't play !\n");
1215 return MIDIERR_NODEVICE;
1217 event = LOWORD(dwParam);
1218 if (write (MidiOutDev[wDevID].unixdev,
1219 &event, sizeof(WORD)) != sizeof(WORD)) {
1220 dprintf_midi(stddeb,
1221 "modData() // error writting unixdev !\n");
1223 return MMSYSERR_NOTENABLED;
1226 /**************************************************************************
1227 * modLongData [internal]
1229 DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1231 #ifdef linux
1232 int count;
1233 LPWORD ptr;
1234 dprintf_midi(stddeb,
1235 "modLongData(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1236 printf("modLongData(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1237 if (MidiOutDev[wDevID].unixdev == 0) {
1238 fprintf(stderr,"Linux 'modLongData' // can't play !\n");
1239 return MIDIERR_NODEVICE;
1241 if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
1242 if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
1243 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1244 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1245 lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1246 dprintf_midi(stddeb,
1247 "modLongData() // dwBytesRecorded %u !\n", lpMidiHdr->dwBytesRecorded);
1249 count = write (MidiOutDev[wDevID].unixdev,
1250 lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
1252 ptr = (LPWORD)lpMidiHdr->lpData;
1253 for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
1254 if (write (MidiOutDev[wDevID].unixdev, ptr,
1255 sizeof(WORD)) != sizeof(WORD)) break;
1256 ptr++;
1258 if (count != lpMidiHdr->dwBytesRecorded) {
1259 dprintf_midi(stddeb,
1260 "modLongData() // error writting unixdev #%d ! (%d != %d)\n",
1261 MidiOutDev[wDevID].unixdev, count, lpMidiHdr->dwBytesRecorded);
1262 return MMSYSERR_NOTENABLED;
1264 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1265 lpMidiHdr->dwFlags |= MHDR_DONE;
1266 if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
1267 fprintf(stderr,"Linux 'modLongData' // can't notify client !\n");
1268 return MMSYSERR_INVALPARAM;
1270 return MMSYSERR_NOERROR;
1271 #else
1272 return MMSYSERR_NOTENABLED;
1273 #endif
1276 /**************************************************************************
1277 * modPrepare [internal]
1279 DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1281 #ifdef linux
1282 dprintf_midi(stddeb,
1283 "modPrepare(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1284 if (MidiOutDev[wDevID].unixdev == 0) {
1285 fprintf(stderr,"Linux 'modPrepare' // can't prepare !\n");
1286 return MMSYSERR_NOTENABLED;
1288 if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
1289 fprintf(stderr,"Linux 'modPrepare' // already prepare !\n");
1290 return MMSYSERR_NOTENABLED;
1292 MidiOutDev[wDevID].dwTotalPlayed = 0;
1293 MidiOutDev[wDevID].lpQueueHdr = lpMidiHdr;
1294 if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
1295 lpMidiHdr->dwFlags |= MHDR_PREPARED;
1296 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1297 return MMSYSERR_NOERROR;
1298 #else
1299 return MMSYSERR_NOTENABLED;
1300 #endif
1303 /**************************************************************************
1304 * modUnprepare [internal]
1306 DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
1308 #ifdef linux
1309 dprintf_midi(stddeb,
1310 "modUnprepare(%u, %08X, %08X);\n", wDevID, lpMidiHdr, dwSize);
1311 if (MidiOutDev[wDevID].unixdev == 0) {
1312 fprintf(stderr,"Linux 'modUnprepare' // can't unprepare !\n");
1313 return MMSYSERR_NOTENABLED;
1315 return MMSYSERR_NOERROR;
1316 #else
1317 return MMSYSERR_NOTENABLED;
1318 #endif
1321 /**************************************************************************
1322 * modReset [internal]
1324 DWORD modReset(WORD wDevID)
1326 printf("modReset(%u);\n", wDevID);
1327 return MMSYSERR_NOTENABLED;
1331 /**************************************************************************
1332 * modGetPosition [internal]
1334 DWORD modGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1336 printf("modGetposition(%u, %08X, %08X);\n", wDevID, lpTime, uSize);
1337 return MMSYSERR_NOTENABLED;
1341 /**************************************************************************
1342 * modMessage [sample driver]
1344 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1345 DWORD dwParam1, DWORD dwParam2)
1347 printf("modMessage(%u, %04X, %08X, %08X, %08X);\n",
1348 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1349 switch(wMsg) {
1350 case MODM_OPEN:
1351 return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
1352 case MODM_CLOSE:
1353 return modClose(wDevID);
1354 case MODM_DATA:
1355 return modData(wDevID, dwParam1);
1356 case MODM_LONGDATA:
1357 return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1358 case MODM_PREPARE:
1359 return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1360 case MODM_UNPREPARE:
1361 return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
1362 case MODM_GETDEVCAPS:
1363 return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)dwParam1, dwParam2);
1364 case MODM_GETNUMDEVS:
1365 return 1L;
1366 case MODM_GETVOLUME:
1367 return 0L;
1368 case MODM_SETVOLUME:
1369 return 0L;
1370 case MODM_RESET:
1371 return modReset(wDevID);
1373 return MMSYSERR_NOTSUPPORTED;
1377 /*-----------------------------------------------------------------------*/
1380 #endif /* #ifdef BUILTIN_MMSYSTEM */