2 * Sample Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
6 static char Copyright
[] = "Copyright Martin Ayotte, 1994";
9 #define BUILTIN_MMSYSTEM
12 #ifdef BUILTIN_MMSYSTEM
23 #include <sys/ioctl.h>
25 #include <linux/soundcard.h>
29 #define SOUND_DEV "/dev/dsp"
32 #define IOCTL(a,b,c) ioctl(a,b,&c)
34 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
37 #define MAX_WAVOUTDRV 2
38 #define MAX_WAVINDRV 2
39 #define MAX_MCIWAVDRV 2
45 WAVEOPENDESC waveDesc
;
55 DWORD bufsize
; /* Linux '/dev/dsp' give us that size */
56 WAVEOPENDESC waveDesc
;
60 DWORD dwTotalRecorded
;
64 int nUseCount
; /* Incremented for each shared open */
65 BOOL fShareable
; /* TRUE if first open was shareable */
66 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
67 HANDLE hCallback
; /* Callback handle for pending notification */
68 HMMIO hFile
; /* mmio file handle open as Element */
69 MCI_WAVE_OPEN_PARMS openParms
;
70 PCMWAVEFORMAT WaveFormat
;
74 static LINUX_WAVEOUT WOutDev
[MAX_WAVOUTDRV
];
75 static LINUX_WAVEIN WInDev
[MAX_WAVOUTDRV
];
76 static LINUX_MCIWAVE MCIWavDev
[MAX_MCIWAVDRV
];
79 DWORD
WAVE_mciOpen(DWORD dwFlags
, LPMCI_WAVE_OPEN_PARMS lpParms
);
80 DWORD
WAVE_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
);
81 DWORD
WAVE_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
);
82 DWORD
WAVE_mciRecord(UINT wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
);
83 DWORD
WAVE_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
84 DWORD
WAVE_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
85 DWORD
WAVE_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
86 DWORD
WAVE_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
);
87 DWORD
WAVE_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
);
88 DWORD
WAVE_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
, LPMCI_GETDEVCAPS_PARMS lpParms
);
89 DWORD
WAVE_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
);
91 DWORD
wodGetDevCaps(WORD wDevID
, LPWAVEOUTCAPS lpCaps
, DWORD dwSize
);
92 DWORD
wodOpen(WORD wDevID
, LPWAVEOPENDESC lpDesc
, DWORD dwFlags
);
93 DWORD
wodClose(WORD wDevID
);
94 DWORD
wodWrite(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
);
95 DWORD
wodPrepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
);
96 DWORD
wodUnprepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
);
99 /**************************************************************************
100 * WAVE_NotifyClient [internal]
102 DWORD
WAVE_NotifyClient(UINT wDevID
, WORD wMsg
,
103 DWORD dwParam1
, DWORD dwParam2
)
106 if (WInDev
[wDevID
].wFlags
!= DCB_NULL
&& !DriverCallback(
107 WInDev
[wDevID
].waveDesc
.dwCallBack
, WInDev
[wDevID
].wFlags
,
108 WInDev
[wDevID
].waveDesc
.hWave
, wMsg
,
109 WInDev
[wDevID
].waveDesc
.dwInstance
, dwParam1
, dwParam2
)) {
110 printf("WAVE_NotifyClient // can't notify client !\n");
111 return MMSYSERR_NOERROR
;
114 return MMSYSERR_NOTENABLED
;
119 /**************************************************************************
120 * AUDIO_DriverProc [sample driver]
122 LRESULT
WAVE_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
123 DWORD dwParam1
, DWORD dwParam2
)
139 case DRV_QUERYCONFIGURE
:
142 MessageBox((HWND
)NULL
, "Sample MultiMedia Linux Driver !",
143 "MMLinux Driver", MB_OK
);
146 return (LRESULT
)DRVCNF_RESTART
;
148 return (LRESULT
)DRVCNF_RESTART
;
149 case MCI_OPEN_DRIVER
:
151 return WAVE_mciOpen(dwParam1
, (LPMCI_WAVE_OPEN_PARMS
)dwParam2
);
152 case MCI_CLOSE_DRIVER
:
154 return WAVE_mciClose(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
156 return WAVE_mciPlay(dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
)dwParam2
);
158 return WAVE_mciRecord(dwDevID
, dwParam1
, (LPMCI_RECORD_PARMS
)dwParam2
);
160 return WAVE_mciStop(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
162 return WAVE_mciSet(dwDevID
, dwParam1
, (LPMCI_SET_PARMS
)dwParam2
);
164 return WAVE_mciPause(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
166 return WAVE_mciResume(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
168 return WAVE_mciStatus(dwDevID
, dwParam1
, (LPMCI_STATUS_PARMS
)dwParam2
);
170 return WAVE_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
)dwParam2
);
172 return WAVE_mciInfo(dwDevID
, dwParam1
, (LPMCI_INFO_PARMS
)dwParam2
);
174 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
177 return MMSYSERR_NOTENABLED
;
181 /**************************************************************************
183 DWORD
WAVE_mciOpen(DWORD dwFlags
, LPMCI_WAVE_OPEN_PARMS lpParms
)
189 LPPCMWAVEFORMAT lpWaveFormat
;
190 WAVEOPENDESC WaveDesc
;
195 printf("WAVE_mciOpen(%08X, %08X)\n", dwFlags
, lpParms
);
197 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
198 wDevID
= lpParms
->wDeviceID
;
199 if (MCIWavDev
[wDevID
].nUseCount
> 0) {
200 /* The driver already open on this channel */
201 /* If the driver was opened shareable before and this open specifies */
202 /* shareable then increment the use count */
203 if (MCIWavDev
[wDevID
].fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
204 ++MCIWavDev
[wDevID
].nUseCount
;
206 return MCIERR_MUST_USE_SHAREABLE
;
209 MCIWavDev
[wDevID
].nUseCount
= 1;
210 MCIWavDev
[wDevID
].fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
212 if (dwFlags
& MCI_OPEN_ELEMENT
) {
213 printf("WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
214 lpParms
->lpstrElementName
);
215 /* printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
216 if (strlen(lpParms
->lpstrElementName
) > 0) {
217 strcpy(str
, lpParms
->lpstrElementName
);
219 MCIWavDev
[wDevID
].hFile
= mmioOpen(str
, NULL
,
220 MMIO_ALLOCBUF
| MMIO_READWRITE
| MMIO_EXCLUSIVE
);
221 if (MCIWavDev
[wDevID
].hFile
== 0) {
222 printf("WAVE_mciOpen // can't find file='%s' !\n", str
);
223 return MCIERR_FILE_NOT_FOUND
;
227 MCIWavDev
[wDevID
].hFile
= 0;
229 printf("WAVE_mciOpen // hFile=%u\n", MCIWavDev
[wDevID
].hFile
);
230 memcpy(&MCIWavDev
[wDevID
].openParms
, lpParms
, sizeof(MCI_WAVE_OPEN_PARMS
));
231 MCIWavDev
[wDevID
].wNotifyDeviceID
= lpParms
->wDeviceID
;
232 lpWaveFormat
= &MCIWavDev
[wDevID
].WaveFormat
;
234 WaveDesc
.lpFormat
= (LPWAVEFORMAT
)lpWaveFormat
;
235 lpWaveFormat
->wf
.wFormatTag
= WAVE_FORMAT_PCM
;
236 lpWaveFormat
->wBitsPerSample
= 8;
237 lpWaveFormat
->wf
.nChannels
= 1;
238 lpWaveFormat
->wf
.nSamplesPerSec
= 11025;
239 lpWaveFormat
->wf
.nAvgBytesPerSec
= 11025;
240 lpWaveFormat
->wf
.nBlockAlign
= 1;
241 if (MCIWavDev
[wDevID
].hFile
!= 0) {
244 if (mmioDescend(MCIWavDev
[wDevID
].hFile
, &ckMainRIFF
, NULL
, 0) != 0) {
245 return MCIERR_INTERNAL
;
248 printf("WAVE_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
249 (LPSTR
)&ckMainRIFF
.ckid
, (LPSTR
)&ckMainRIFF
.fccType
,
252 if ((ckMainRIFF
.ckid
!= FOURCC_RIFF
) ||
253 (ckMainRIFF
.fccType
!= mmioFOURCC('W', 'A', 'V', 'E'))) {
254 return MCIERR_INTERNAL
;
256 mmckInfo
.ckid
= mmioFOURCC('f', 'm', 't', ' ');
257 if (mmioDescend(MCIWavDev
[wDevID
].hFile
, &mmckInfo
, &ckMainRIFF
, MMIO_FINDCHUNK
) != 0) {
258 return MCIERR_INTERNAL
;
261 printf("WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
262 (LPSTR
)&mmckInfo
.ckid
, (LPSTR
)&mmckInfo
.fccType
,
265 if (mmioRead(MCIWavDev
[wDevID
].hFile
, (HPSTR
) lpWaveFormat
,
266 (long) sizeof(PCMWAVEFORMAT
)) != (long) sizeof(PCMWAVEFORMAT
)) {
267 return MCIERR_INTERNAL
;
269 mmckInfo
.ckid
= mmioFOURCC('d', 'a', 't', 'a');
270 if (mmioDescend(MCIWavDev
[wDevID
].hFile
, &mmckInfo
, &ckMainRIFF
, MMIO_FINDCHUNK
) != 0) {
271 return MCIERR_INTERNAL
;
274 printf("WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
275 (LPSTR
)&mmckInfo
.ckid
, (LPSTR
)&mmckInfo
.fccType
,
277 printf("WAVE_mciOpen // nChannels=%d nSamplesPerSec=%d\n",
278 lpWaveFormat
->wf
.nChannels
, lpWaveFormat
->wf
.nSamplesPerSec
);
280 lpWaveFormat
->wBitsPerSample
= 0;
282 lpWaveFormat
->wf
.nAvgBytesPerSec
=
283 lpWaveFormat
->wf
.nSamplesPerSec
* lpWaveFormat
->wf
.nBlockAlign
;
284 dwRet
= wodMessage(0, WODM_OPEN
, 0, (DWORD
)&WaveDesc
, CALLBACK_NULL
);
285 dwRet
= widMessage(0, WIDM_OPEN
, 0, (DWORD
)&WaveDesc
, CALLBACK_NULL
);
288 return MMSYSERR_NOTENABLED
;
292 /**************************************************************************
293 * WAVE_mciClose [internal]
295 DWORD
WAVE_mciClose(UINT wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
300 printf("WAVE_mciClose(%u, %08X, %08X);\n", wDevID
, dwParam
, lpParms
);
302 MCIWavDev
[wDevID
].nUseCount
--;
303 if (MCIWavDev
[wDevID
].nUseCount
== 0) {
304 if (MCIWavDev
[wDevID
].hFile
!= 0) {
305 close(MCIWavDev
[wDevID
].hFile
);
306 MCIWavDev
[wDevID
].hFile
= 0;
308 dwRet
= wodMessage(0, WODM_CLOSE
, 0, 0L, 0L);
309 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
310 dwRet
= widMessage(0, WIDM_CLOSE
, 0, 0L, 0L);
311 if (dwRet
!= MMSYSERR_NOERROR
) return MCIERR_INTERNAL
;
320 /**************************************************************************
321 * WAVE_mciPlay [internal]
323 DWORD
WAVE_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
331 printf("WAVE_mciPlay(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
333 if (MCIWavDev
[wDevID
].hFile
== 0) {
334 printf("WAVE_mciPlay // can't find file='%s' !\n",
335 MCIWavDev
[wDevID
].openParms
.lpstrElementName
);
336 return MCIERR_FILE_NOT_FOUND
;
338 start
= 1; end
= 99999;
339 if (dwFlags
& MCI_FROM
) {
340 start
= lpParms
->dwFrom
;
341 printf("WAVE_mciPlay // MCI_FROM=%d \n", start
);
343 if (dwFlags
& MCI_TO
) {
345 printf("WAVE_mciPlay // MCI_TO=%d \n", end
);
348 if (dwFlags & MCI_NOTIFY) {
349 printf("WAVE_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
352 printf("WAVE_mciPlay // Can't 'fork' process !\n");
357 printf("WAVE_mciPlay // process started ! return to caller...\n");
362 lpWaveHdr
= &MCIWavDev
[wDevID
].WaveHdr
;
363 lpWaveHdr
->lpData
= (LPSTR
) malloc(64000);
364 lpWaveHdr
->dwBufferLength
= 32000;
365 lpWaveHdr
->dwUser
= 0L;
366 lpWaveHdr
->dwFlags
= 0L;
367 lpWaveHdr
->dwLoops
= 0L;
368 dwRet
= wodMessage(0, WODM_PREPARE
, 0, (DWORD
)lpWaveHdr
, sizeof(WAVEHDR
));
369 /* printf("WAVE_mciPlay // after WODM_PREPARE \n"); */
371 count
= mmioRead(MCIWavDev
[wDevID
].hFile
, lpWaveHdr
->lpData
, lpWaveHdr
->dwBufferLength
);
372 if (count
< 1) break;
373 lpWaveHdr
->dwBytesRecorded
= count
;
375 printf("WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%08X dwBytesRecorded=%u\n",
376 lpWaveHdr
, lpWaveHdr
->dwBytesRecorded
);
378 dwRet
= wodMessage(0, WODM_WRITE
, 0, (DWORD
)lpWaveHdr
, sizeof(WAVEHDR
));
380 dwRet
= wodMessage(0, WODM_UNPREPARE
, 0, (DWORD
)lpWaveHdr
, sizeof(WAVEHDR
));
381 if (lpWaveHdr
->lpData
!= NULL
) {
382 free(lpWaveHdr
->lpData
);
383 lpWaveHdr
->lpData
= NULL
;
385 if (dwFlags
& MCI_NOTIFY
) {
387 printf("WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
389 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
390 MCIWavDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
394 return MMSYSERR_NOTENABLED
;
399 /**************************************************************************
400 * WAVE_mciRecord [internal]
402 DWORD
WAVE_mciRecord(UINT wDevID
, DWORD dwFlags
, LPMCI_RECORD_PARMS lpParms
)
410 printf("WAVE_mciRecord(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
412 if (MCIWavDev
[wDevID
].hFile
== 0) {
413 printf("WAVE_mciRecord // can't find file='%s' !\n",
414 MCIWavDev
[wDevID
].openParms
.lpstrElementName
);
415 return MCIERR_FILE_NOT_FOUND
;
417 start
= 1; end
= 99999;
418 if (dwFlags
& MCI_FROM
) {
419 start
= lpParms
->dwFrom
;
420 printf("WAVE_mciRecord // MCI_FROM=%d \n", start
);
422 if (dwFlags
& MCI_TO
) {
424 printf("WAVE_mciRecord // MCI_TO=%d \n", end
);
426 lpWaveHdr
= &MCIWavDev
[wDevID
].WaveHdr
;
427 lpWaveHdr
->lpData
= (LPSTR
) malloc(64000);
428 lpWaveHdr
->dwBufferLength
= 32000;
429 lpWaveHdr
->dwUser
= 0L;
430 lpWaveHdr
->dwFlags
= 0L;
431 lpWaveHdr
->dwLoops
= 0L;
432 dwRet
= widMessage(0, WIDM_PREPARE
, 0, (DWORD
)lpWaveHdr
, sizeof(WAVEHDR
));
433 printf("WAVE_mciRecord // after WIDM_PREPARE \n");
435 lpWaveHdr
->dwBytesRecorded
= 0;
436 dwRet
= widMessage(0, WIDM_START
, 0, 0L, 0L);
437 printf("WAVE_mciRecord // after WIDM_START lpWaveHdr=%08X dwBytesRecorded=%u\n",
438 lpWaveHdr
, lpWaveHdr
->dwBytesRecorded
);
439 if (lpWaveHdr
->dwBytesRecorded
== 0) break;
441 printf("WAVE_mciRecord // before WIDM_UNPREPARE \n");
442 dwRet
= widMessage(0, WIDM_UNPREPARE
, 0, (DWORD
)lpWaveHdr
, sizeof(WAVEHDR
));
443 printf("WAVE_mciRecord // after WIDM_UNPREPARE \n");
444 if (lpWaveHdr
->lpData
!= NULL
) {
445 free(lpWaveHdr
->lpData
);
446 lpWaveHdr
->lpData
= NULL
;
448 if (dwFlags
& MCI_NOTIFY
) {
450 printf("WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
452 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
453 MCIWavDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
457 return MMSYSERR_NOTENABLED
;
462 /**************************************************************************
463 * WAVE_mciStop [internal]
465 DWORD
WAVE_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
469 printf("WAVE_mciStop(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
471 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
474 return MCIERR_INTERNAL
;
479 /**************************************************************************
480 * WAVE_mciPause [internal]
482 DWORD
WAVE_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
486 printf("WAVE_mciPause(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
488 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
491 return MCIERR_INTERNAL
;
496 /**************************************************************************
497 * WAVE_mciResume [internal]
499 DWORD
WAVE_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
503 printf("WAVE_mciResume(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
505 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
508 return MCIERR_INTERNAL
;
513 /**************************************************************************
514 * WAVE_mciSet [internal]
516 DWORD
WAVE_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
520 printf("WAVE_mciSet(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
522 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
524 printf("WAVE_mciSet // dwTimeFormat=%08X\n", lpParms
->dwTimeFormat
);
525 printf("WAVE_mciSet // dwAudio=%08X\n", lpParms
->dwAudio
);
527 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
528 switch (lpParms
->dwTimeFormat
) {
529 case MCI_FORMAT_MILLISECONDS
:
530 printf("WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
532 case MCI_FORMAT_BYTES
:
533 printf("WAVE_mciSet // MCI_FORMAT_BYTES !\n");
535 case MCI_FORMAT_SAMPLES
:
536 printf("WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
539 printf("WAVE_mciSet // bad time format !\n");
540 return MCIERR_BAD_TIME_FORMAT
;
543 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
544 if (dwFlags
& MCI_SET_DOOR_OPEN
) return MCIERR_UNSUPPORTED_FUNCTION
;
545 if (dwFlags
& MCI_SET_DOOR_CLOSED
) return MCIERR_UNSUPPORTED_FUNCTION
;
546 if (dwFlags
& MCI_SET_AUDIO
) {
547 printf("WAVE_mciSet // MCI_SET_AUDIO !\n");
549 if (dwFlags
&& MCI_SET_ON
) {
550 printf("WAVE_mciSet // MCI_SET_ON !\n");
551 if (dwFlags
&& MCI_SET_AUDIO_LEFT
) {
552 printf("WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
554 if (dwFlags
&& MCI_SET_AUDIO_RIGHT
) {
555 printf("WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
558 if (dwFlags
& MCI_SET_OFF
) {
559 printf("WAVE_mciSet // MCI_SET_OFF !\n");
561 if (dwFlags
& MCI_WAVE_INPUT
) {
562 printf("WAVE_mciSet // MCI_WAVE_INPUT !\n");
564 if (dwFlags
& MCI_WAVE_OUTPUT
) {
565 printf("WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
567 if (dwFlags
& MCI_WAVE_SET_ANYINPUT
) {
568 printf("WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
570 if (dwFlags
& MCI_WAVE_SET_ANYOUTPUT
) {
571 printf("WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
573 if (dwFlags
& MCI_WAVE_SET_AVGBYTESPERSEC
) {
574 printf("WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
576 if (dwFlags
& MCI_WAVE_SET_BITSPERSAMPLE
) {
577 printf("WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
579 if (dwFlags
& MCI_WAVE_SET_BLOCKALIGN
) {
580 printf("WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
582 if (dwFlags
& MCI_WAVE_SET_CHANNELS
) {
583 printf("WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
585 if (dwFlags
& MCI_WAVE_SET_FORMATTAG
) {
586 printf("WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
588 if (dwFlags
& MCI_WAVE_SET_SAMPLESPERSEC
) {
589 printf("WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
593 return MCIERR_INTERNAL
;
598 /**************************************************************************
599 * WAVE_mciStatus [internal]
601 DWORD
WAVE_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
605 printf("WAVE_mciStatus(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
607 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
608 if (dwFlags
& MCI_STATUS_ITEM
) {
609 switch(lpParms
->dwItem
) {
610 case MCI_STATUS_CURRENT_TRACK
:
611 lpParms
->dwReturn
= 1;
613 case MCI_STATUS_LENGTH
:
614 lpParms
->dwReturn
= 5555;
615 if (dwFlags
& MCI_TRACK
) {
616 lpParms
->dwTrack
= 1;
617 lpParms
->dwReturn
= 2222;
620 case MCI_STATUS_MODE
:
621 lpParms
->dwReturn
= MCI_MODE_STOP
;
623 case MCI_STATUS_MEDIA_PRESENT
:
624 printf("WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
625 lpParms
->dwReturn
= TRUE
;
627 case MCI_STATUS_NUMBER_OF_TRACKS
:
628 lpParms
->dwReturn
= 1;
630 case MCI_STATUS_POSITION
:
631 lpParms
->dwReturn
= 3333;
632 if (dwFlags
& MCI_STATUS_START
) {
635 if (dwFlags
& MCI_TRACK
) {
636 lpParms
->dwTrack
= 1;
637 lpParms
->dwReturn
= 777;
640 case MCI_STATUS_READY
:
641 printf("WAVE_mciStatus // MCI_STATUS_READY !\n");
642 lpParms
->dwReturn
= TRUE
;
644 case MCI_STATUS_TIME_FORMAT
:
645 printf("WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
646 lpParms
->dwReturn
= MCI_FORMAT_MILLISECONDS
;
649 printf("WAVE_mciStatus // MCI_WAVE_INPUT !\n");
650 lpParms
->dwReturn
= 0;
652 case MCI_WAVE_OUTPUT
:
653 printf("WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
654 lpParms
->dwReturn
= 0;
656 case MCI_WAVE_STATUS_AVGBYTESPERSEC
:
657 printf("WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
658 lpParms
->dwReturn
= 22050;
660 case MCI_WAVE_STATUS_BITSPERSAMPLE
:
661 printf("WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
662 lpParms
->dwReturn
= 8;
664 case MCI_WAVE_STATUS_BLOCKALIGN
:
665 printf("WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
666 lpParms
->dwReturn
= 1;
668 case MCI_WAVE_STATUS_CHANNELS
:
669 printf("WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
670 lpParms
->dwReturn
= 1;
672 case MCI_WAVE_STATUS_FORMATTAG
:
673 printf("WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
674 lpParms
->dwReturn
= WAVE_FORMAT_PCM
;
676 case MCI_WAVE_STATUS_LEVEL
:
677 printf("WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
678 lpParms
->dwReturn
= 0xAAAA5555;
680 case MCI_WAVE_STATUS_SAMPLESPERSEC
:
681 printf("WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
682 lpParms
->dwReturn
= 22050;
685 printf("WAVE_mciStatus // unknowm command %04X !\n", lpParms
->dwItem
);
686 return MCIERR_UNRECOGNIZED_COMMAND
;
689 if (dwFlags
& MCI_NOTIFY
) {
690 printf("WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms
->dwCallback
);
691 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
692 MCIWavDev
[wDevID
].wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
696 return MCIERR_INTERNAL
;
700 /**************************************************************************
701 * WAVE_mciGetDevCaps [internal]
703 DWORD
WAVE_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
,
704 LPMCI_GETDEVCAPS_PARMS lpParms
)
707 printf("WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
708 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
709 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
710 switch(lpParms
->dwItem
) {
711 case MCI_GETDEVCAPS_CAN_RECORD
:
712 lpParms
->dwReturn
= TRUE
;
714 case MCI_GETDEVCAPS_HAS_AUDIO
:
715 lpParms
->dwReturn
= TRUE
;
717 case MCI_GETDEVCAPS_HAS_VIDEO
:
718 lpParms
->dwReturn
= FALSE
;
720 case MCI_GETDEVCAPS_DEVICE_TYPE
:
721 lpParms
->dwReturn
= MCI_DEVTYPE_WAVEFORM_AUDIO
;
723 case MCI_GETDEVCAPS_USES_FILES
:
724 lpParms
->dwReturn
= TRUE
;
726 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
727 lpParms
->dwReturn
= TRUE
;
729 case MCI_GETDEVCAPS_CAN_EJECT
:
730 lpParms
->dwReturn
= FALSE
;
732 case MCI_GETDEVCAPS_CAN_PLAY
:
733 lpParms
->dwReturn
= TRUE
;
735 case MCI_GETDEVCAPS_CAN_SAVE
:
736 lpParms
->dwReturn
= FALSE
;
738 case MCI_WAVE_GETDEVCAPS_INPUTS
:
739 lpParms
->dwReturn
= 1;
741 case MCI_WAVE_GETDEVCAPS_OUTPUTS
:
742 lpParms
->dwReturn
= 1;
745 return MCIERR_UNRECOGNIZED_COMMAND
;
750 return MCIERR_INTERNAL
;
754 /**************************************************************************
755 * WAVE_mciInfo [internal]
757 DWORD
WAVE_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS lpParms
)
760 printf("WAVE_mciInfo(%u, %08X, %08X);\n", wDevID
, dwFlags
, lpParms
);
761 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
762 lpParms
->lpstrReturn
= NULL
;
764 case MCI_INFO_PRODUCT
:
765 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
768 lpParms
->lpstrReturn
= "FileName";
771 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
773 case MCI_WAVE_OUTPUT
:
774 lpParms
->lpstrReturn
= "Linux Sound System 0.5";
777 return MCIERR_UNRECOGNIZED_COMMAND
;
779 if (lpParms
->lpstrReturn
!= NULL
)
780 lpParms
->dwRetSize
= strlen(lpParms
->lpstrReturn
);
782 lpParms
->dwRetSize
= 0;
785 return MCIERR_INTERNAL
;
790 /*-----------------------------------------------------------------------*/
793 /**************************************************************************
794 * wodGetDevCaps [internal]
796 DWORD
wodGetDevCaps(WORD wDevID
, LPWAVEOUTCAPS lpCaps
, DWORD dwSize
)
804 printf("wodGetDevCaps(%u, %08X, %u);\n", wDevID
, lpCaps
, dwSize
);
805 if (lpCaps
== NULL
) return MMSYSERR_NOTENABLED
;
806 audio
= open (SOUND_DEV
, O_WRONLY
, 0);
807 if (audio
== -1) return MMSYSERR_NOTENABLED
;
808 lpCaps
->wMid
= 0xFF; /* Manufac ID */
809 lpCaps
->wPid
= 0x01; /* Product ID */
810 strcpy(lpCaps
->szPname
, "Linux WAV Driver");
811 lpCaps
->dwFormats
= 0;
812 lpCaps
->dwSupport
= 0;
813 lpCaps
->wChannels
= (IOCTL(audio
, SNDCTL_DSP_STEREO
, dsp_stereo
) != 0) ? 1 : 2;
814 bytespersmpl
= (IOCTL(audio
, SNDCTL_DSP_SAMPLESIZE
, samplesize
) != 0) ? 1 : 2;
816 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
817 lpCaps
->dwFormats
|= WAVE_FORMAT_4M08
;
818 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_4S08
;
819 if (bytespersmpl
> 1) {
820 lpCaps
->dwFormats
|= WAVE_FORMAT_4M16
;
821 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_4S16
;
825 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
826 lpCaps
->dwFormats
|= WAVE_FORMAT_2M08
;
827 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_2S08
;
828 if (bytespersmpl
> 1) {
829 lpCaps
->dwFormats
|= WAVE_FORMAT_2M16
;
830 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_2S16
;
834 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
835 lpCaps
->dwFormats
|= WAVE_FORMAT_1M08
;
836 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_1S08
;
837 if (bytespersmpl
> 1) {
838 lpCaps
->dwFormats
|= WAVE_FORMAT_1M16
;
839 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_1S16
;
843 printf("wodGetDevCaps // dwFormats = %08X\n", lpCaps
->dwFormats
);
844 return MMSYSERR_NOERROR
;
846 return MMSYSERR_NOTENABLED
;
851 /**************************************************************************
854 DWORD
wodOpen(WORD wDevID
, LPWAVEOPENDESC lpDesc
, DWORD dwFlags
)
862 printf("wodOpen(%u, %08X, %08X);\n", wDevID
, lpDesc
, dwFlags
);
863 if (lpDesc
== NULL
) {
864 printf("Linux 'wodOpen' // Invalid Parameter !\n");
865 return MMSYSERR_INVALPARAM
;
867 if (wDevID
>= MAX_WAVOUTDRV
) {
868 printf("Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
869 return MMSYSERR_ALLOCATED
;
871 WOutDev
[wDevID
].unixdev
= 0;
872 audio
= open (SOUND_DEV
, O_WRONLY
, 0);
874 printf("Linux 'wodOpen' // can't open !\n");
875 return MMSYSERR_NOTENABLED
;
877 IOCTL(audio
, SNDCTL_DSP_GETBLKSIZE
, abuf_size
);
878 if (abuf_size
< 4096 || abuf_size
> 65536) {
880 printf("Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
882 printf("Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
883 return MMSYSERR_NOTENABLED
;
885 WOutDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
886 switch(WOutDev
[wDevID
].wFlags
) {
888 printf("Linux 'wodOpen' // CALLBACK_NULL !\n");
891 printf("Linux 'wodOpen' // CALLBACK_WINDOW !\n");
894 printf("Linux 'wodOpen' // CALLBACK_TASK !\n");
897 printf("Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
900 WOutDev
[wDevID
].lpQueueHdr
= NULL
;
901 WOutDev
[wDevID
].unixdev
= audio
;
902 WOutDev
[wDevID
].dwTotalPlayed
= 0;
903 WOutDev
[wDevID
].bufsize
= abuf_size
;
904 memcpy(&WOutDev
[wDevID
].waveDesc
, lpDesc
, sizeof(WAVEOPENDESC
));
905 if (lpDesc
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
906 printf("Linux 'wodOpen' // Bad format %04X !\n",
907 lpDesc
->lpFormat
->wFormatTag
);
908 return WAVERR_BADFORMAT
;
910 memcpy(&WOutDev
[wDevID
].Format
, lpDesc
->lpFormat
, sizeof(PCMWAVEFORMAT
));
911 if (WOutDev
[wDevID
].Format
.wf
.nChannels
== 0) return WAVERR_BADFORMAT
;
912 if (WOutDev
[wDevID
].Format
.wf
.nSamplesPerSec
== 0) return WAVERR_BADFORMAT
;
913 if (WOutDev
[wDevID
].Format
.wBitsPerSample
== 0) {
914 WOutDev
[wDevID
].Format
.wBitsPerSample
= 8 *
915 (WOutDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/
916 WOutDev
[wDevID
].Format
.wf
.nSamplesPerSec
) /
917 WOutDev
[wDevID
].Format
.wf
.nChannels
;
919 samplesize
= WOutDev
[wDevID
].Format
.wBitsPerSample
;
920 smplrate
= WOutDev
[wDevID
].Format
.wf
.nSamplesPerSec
;
921 dsp_stereo
= (WOutDev
[wDevID
].Format
.wf
.nChannels
> 1) ? TRUE
: FALSE
;
922 IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
);
923 IOCTL(audio
, SNDCTL_DSP_SAMPLESIZE
, samplesize
);
924 IOCTL(audio
, SNDCTL_DSP_STEREO
, dsp_stereo
);
925 printf("Linux 'wodOpen' // wBitsPerSample=%u !\n",
926 WOutDev
[wDevID
].Format
.wBitsPerSample
);
927 printf("Linux 'wodOpen' // nSamplesPerSec=%u !\n",
928 WOutDev
[wDevID
].Format
.wf
.nSamplesPerSec
);
929 printf("Linux 'wodOpen' // nChannels=%u !\n",
930 WOutDev
[wDevID
].Format
.wf
.nChannels
);
931 if (WAVE_NotifyClient(wDevID
, WOM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
932 printf("Linux 'wodOpen' // can't notify client !\n");
933 return MMSYSERR_INVALPARAM
;
935 return MMSYSERR_NOERROR
;
937 return MMSYSERR_NOTENABLED
;
941 /**************************************************************************
942 * wodClose [internal]
944 DWORD
wodClose(WORD wDevID
)
947 printf("wodClose(%u);\n", wDevID
);
948 if (WOutDev
[wDevID
].unixdev
== 0) {
949 printf("Linux 'wodClose' // can't close !\n");
950 return MMSYSERR_NOTENABLED
;
952 close(WOutDev
[wDevID
].unixdev
);
953 WOutDev
[wDevID
].unixdev
= 0;
954 WOutDev
[wDevID
].bufsize
= 0;
955 if (WAVE_NotifyClient(wDevID
, WOM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
956 printf("Linux 'wodClose' // can't notify client !\n");
957 return MMSYSERR_INVALPARAM
;
959 return MMSYSERR_NOERROR
;
961 return MMSYSERR_NOTENABLED
;
965 /**************************************************************************
966 * wodWrite [internal]
968 DWORD
wodWrite(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
971 printf("wodWrite(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
972 if (WOutDev
[wDevID
].unixdev
== 0) {
973 printf("Linux 'wodWrite' // can't play !\n");
974 return MMSYSERR_NOTENABLED
;
976 if (lpWaveHdr
->lpData
== NULL
) return WAVERR_UNPREPARED
;
977 if (!(lpWaveHdr
->dwFlags
& WHDR_PREPARED
)) return WAVERR_UNPREPARED
;
978 if (lpWaveHdr
->dwFlags
& WHDR_INQUEUE
) return WAVERR_STILLPLAYING
;
979 lpWaveHdr
->dwFlags
&= ~WHDR_DONE
;
980 lpWaveHdr
->dwFlags
|= WHDR_INQUEUE
;
981 printf("wodWrite() // dwBytesRecorded %u !\n", lpWaveHdr
->dwBytesRecorded
);
982 if (write (WOutDev
[wDevID
].unixdev
, lpWaveHdr
->lpData
,
983 lpWaveHdr
->dwBytesRecorded
) != lpWaveHdr
->dwBytesRecorded
) {
984 return MMSYSERR_NOTENABLED
;
986 lpWaveHdr
->dwFlags
&= ~WHDR_INQUEUE
;
987 lpWaveHdr
->dwFlags
|= WHDR_DONE
;
988 if (WAVE_NotifyClient(wDevID
, WOM_DONE
, 0L, 0L) != MMSYSERR_NOERROR
) {
989 printf("Linux 'wodWrite' // can't notify client !\n");
990 return MMSYSERR_INVALPARAM
;
992 return MMSYSERR_NOERROR
;
994 return MMSYSERR_NOTENABLED
;
998 /**************************************************************************
999 * wodPrepare [internal]
1001 DWORD
wodPrepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
1004 printf("wodPrepare(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
1005 if (WOutDev
[wDevID
].unixdev
== 0) {
1006 printf("Linux 'wodPrepare' // can't prepare !\n");
1007 return MMSYSERR_NOTENABLED
;
1009 if (WOutDev
[wDevID
].lpQueueHdr
!= NULL
) {
1010 printf("Linux 'wodPrepare' // already prepare !\n");
1011 return MMSYSERR_NOTENABLED
;
1013 WOutDev
[wDevID
].dwTotalPlayed
= 0;
1014 WOutDev
[wDevID
].lpQueueHdr
= lpWaveHdr
;
1015 if (lpWaveHdr
->dwFlags
& WHDR_INQUEUE
) return WAVERR_STILLPLAYING
;
1016 lpWaveHdr
->dwFlags
|= WHDR_PREPARED
;
1017 lpWaveHdr
->dwFlags
&= ~WHDR_DONE
;
1018 return MMSYSERR_NOERROR
;
1020 return MMSYSERR_NOTENABLED
;
1024 /**************************************************************************
1025 * wodUnprepare [internal]
1027 DWORD
wodUnprepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
1030 printf("wodUnprepare(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
1031 if (WOutDev
[wDevID
].unixdev
== 0) {
1032 printf("Linux 'wodUnprepare' // can't unprepare !\n");
1033 return MMSYSERR_NOTENABLED
;
1035 return MMSYSERR_NOERROR
;
1037 return MMSYSERR_NOTENABLED
;
1041 /**************************************************************************
1042 * wodRestart [internal]
1044 DWORD
wodRestart(WORD wDevID
)
1047 printf("wodRestart(%u);\n", wDevID
);
1048 if (WOutDev
[wDevID
].unixdev
== 0) {
1049 printf("Linux 'wodRestart' // can't restart !\n");
1050 return MMSYSERR_NOTENABLED
;
1052 return MMSYSERR_NOERROR
;
1054 return MMSYSERR_NOTENABLED
;
1058 /**************************************************************************
1059 * wodReset [internal]
1061 DWORD
wodReset(WORD wDevID
)
1064 printf("wodReset(%u);\n", wDevID
);
1065 if (WOutDev
[wDevID
].unixdev
== 0) {
1066 printf("Linux 'wodReset' // can't reset !\n");
1067 return MMSYSERR_NOTENABLED
;
1069 return MMSYSERR_NOERROR
;
1071 return MMSYSERR_NOTENABLED
;
1076 /**************************************************************************
1077 * wodGetPosition [internal]
1079 DWORD
wodGetPosition(WORD wDevID
, LPMMTIME lpTime
, DWORD uSize
)
1083 printf("wodGetPosition(%u, %08X, %u);\n", wDevID
, lpTime
, uSize
);
1084 if (WOutDev
[wDevID
].unixdev
== 0) {
1085 printf("Linux 'wodGetPosition' // can't get pos !\n");
1086 return MMSYSERR_NOTENABLED
;
1088 if (lpTime
== NULL
) return MMSYSERR_INVALPARAM
;
1090 switch(lpTime
->wType
) {
1092 lpTime
->u
.cb
= WOutDev
[wDevID
].dwTotalPlayed
;
1093 printf("wodGetPosition // TIME_BYTES=%u\n", lpTime
->u
.cb
);
1096 lpTime
->u
.sample
= WOutDev
[wDevID
].dwTotalPlayed
* 8 /
1097 WOutDev
[wDevID
].Format
.wBitsPerSample
;
1098 printf("wodGetPosition // TIME_SAMPLES=%u\n", lpTime
->u
.sample
);
1101 lpTime
->u
.ms
= WOutDev
[wDevID
].dwTotalPlayed
/
1102 (WOutDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/ 1000);
1103 printf("wodGetPosition // TIME_MS=%u\n", lpTime
->u
.ms
);
1106 time
= WOutDev
[wDevID
].dwTotalPlayed
/
1107 (WOutDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/ 1000);
1108 lpTime
->u
.smpte
.hour
= time
/ 108000;
1109 time
-= lpTime
->u
.smpte
.hour
* 108000;
1110 lpTime
->u
.smpte
.min
= time
/ 1800;
1111 time
-= lpTime
->u
.smpte
.min
* 1800;
1112 lpTime
->u
.smpte
.sec
= time
/ 30;
1113 time
-= lpTime
->u
.smpte
.sec
* 30;
1114 lpTime
->u
.smpte
.frame
= time
;
1115 lpTime
->u
.smpte
.fps
= 30;
1116 printf("wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1117 lpTime
->u
.smpte
.hour
, lpTime
->u
.smpte
.min
,
1118 lpTime
->u
.smpte
.sec
, lpTime
->u
.smpte
.frame
);
1121 printf("wodGetPosition() format not supported ! use TIME_MS !\n");
1122 lpTime
->wType
= TIME_MS
;
1125 return MMSYSERR_NOERROR
;
1127 return MMSYSERR_NOTENABLED
;
1131 /**************************************************************************
1132 * wodSetVolume [internal]
1134 DWORD
wodSetVolume(WORD wDevID
, DWORD dwParam
)
1139 printf("wodSetVolume(%u, %08X);\n", wDevID
, dwParam
);
1140 if (WOutDev
[wDevID
].unixdev
== 0) {
1141 printf("Linux 'wodSetVolume' // can't set volume !\n");
1142 return MMSYSERR_NOTENABLED
;
1144 if ((mixer
= open("/dev/mixer", O_RDWR
)) < 0) {
1145 printf("Linux 'wodSetVolume' // mixer device not available !\n");
1146 return MMSYSERR_NOTENABLED
;
1148 if (ioctl(mixer
, SOUND_MIXER_WRITE_PCM
, &volume
) == -1) {
1149 printf("Linux 'wodSetVolume' // unable set mixer !\n");
1150 return MMSYSERR_NOTENABLED
;
1153 return MMSYSERR_NOERROR
;
1155 return MMSYSERR_NOTENABLED
;
1160 /**************************************************************************
1161 * wodMessage [sample driver]
1163 DWORD
wodMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1164 DWORD dwParam1
, DWORD dwParam2
)
1166 printf("wodMessage(%u, %04X, %08X, %08X, %08X);\n",
1167 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1170 return wodOpen(wDevID
, (LPWAVEOPENDESC
)dwParam1
, dwParam2
);
1172 return wodClose(wDevID
);
1174 return wodWrite(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1178 return wodGetPosition(wDevID
, (LPMMTIME
)dwParam1
, dwParam2
);
1179 case WODM_BREAKLOOP
:
1182 return wodPrepare(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1183 case WODM_UNPREPARE
:
1184 return wodUnprepare(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1185 case WODM_GETDEVCAPS
:
1186 return wodGetDevCaps(wDevID
, (LPWAVEOUTCAPS
)dwParam1
, dwParam2
);
1187 case WODM_GETNUMDEVS
:
1193 case WODM_GETPLAYBACKRATE
:
1195 case WODM_SETPLAYBACKRATE
:
1197 case WODM_GETVOLUME
:
1199 case WODM_SETVOLUME
:
1200 return wodSetVolume(wDevID
, dwParam1
);
1202 return wodRestart(wDevID
);
1204 return wodReset(wDevID
);
1206 return MMSYSERR_NOTSUPPORTED
;
1210 /*-----------------------------------------------------------------------*/
1212 /**************************************************************************
1213 * widGetDevCaps [internal]
1215 DWORD
widGetDevCaps(WORD wDevID
, LPWAVEINCAPS lpCaps
, DWORD dwSize
)
1220 int samplesize
= 16;
1223 printf("widGetDevCaps(%u, %08X, %u);\n", wDevID
, lpCaps
, dwSize
);
1224 if (lpCaps
== NULL
) return MMSYSERR_NOTENABLED
;
1225 audio
= open (SOUND_DEV
, O_RDONLY
, 0);
1226 if (audio
== -1) return MMSYSERR_NOTENABLED
;
1227 lpCaps
->wMid
= 0xFF; /* Manufac ID */
1228 lpCaps
->wPid
= 0x01; /* Product ID */
1229 strcpy(lpCaps
->szPname
, "Linux WAV Driver");
1230 lpCaps
->dwFormats
= 0;
1231 lpCaps
->wChannels
= (IOCTL(audio
, SNDCTL_DSP_STEREO
, dsp_stereo
) != 0) ? 1 : 2;
1232 bytespersmpl
= (IOCTL(audio
, SNDCTL_DSP_SAMPLESIZE
, samplesize
) != 0) ? 1 : 2;
1234 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
1235 lpCaps
->dwFormats
|= WAVE_FORMAT_4M08
;
1236 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_4S08
;
1237 if (bytespersmpl
> 1) {
1238 lpCaps
->dwFormats
|= WAVE_FORMAT_4M16
;
1239 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_4S16
;
1243 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
1244 lpCaps
->dwFormats
|= WAVE_FORMAT_2M08
;
1245 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_2S08
;
1246 if (bytespersmpl
> 1) {
1247 lpCaps
->dwFormats
|= WAVE_FORMAT_2M16
;
1248 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_2S16
;
1252 if (IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
) == 0) {
1253 lpCaps
->dwFormats
|= WAVE_FORMAT_1M08
;
1254 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_1S08
;
1255 if (bytespersmpl
> 1) {
1256 lpCaps
->dwFormats
|= WAVE_FORMAT_1M16
;
1257 if (lpCaps
->wChannels
> 1) lpCaps
->dwFormats
|= WAVE_FORMAT_1S16
;
1261 printf("widGetDevCaps // dwFormats = %08X\n", lpCaps
->dwFormats
);
1262 return MMSYSERR_NOERROR
;
1264 return MMSYSERR_NOTENABLED
;
1269 /**************************************************************************
1270 * widOpen [internal]
1272 DWORD
widOpen(WORD wDevID
, LPWAVEOPENDESC lpDesc
, DWORD dwFlags
)
1280 printf("widOpen(%u, %08X, %08X);\n", wDevID
, lpDesc
, dwFlags
);
1281 if (lpDesc
== NULL
) {
1282 printf("Linux 'widOpen' // Invalid Parameter !\n");
1283 return MMSYSERR_INVALPARAM
;
1285 if (wDevID
>= MAX_WAVINDRV
) {
1286 printf("Linux 'widOpen' // MAX_WAVINDRV reached !\n");
1287 return MMSYSERR_ALLOCATED
;
1289 WInDev
[wDevID
].unixdev
= 0;
1290 audio
= open (SOUND_DEV
, O_RDONLY
, 0);
1292 printf("Linux 'widOpen' // can't open !\n");
1293 return MMSYSERR_NOTENABLED
;
1295 IOCTL(audio
, SNDCTL_DSP_GETBLKSIZE
, abuf_size
);
1296 if (abuf_size
< 4096 || abuf_size
> 65536) {
1297 if (abuf_size
== -1)
1298 printf("Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
1300 printf("Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
1301 return MMSYSERR_NOTENABLED
;
1303 WInDev
[wDevID
].wFlags
= HIWORD(dwFlags
& CALLBACK_TYPEMASK
);
1304 switch(WInDev
[wDevID
].wFlags
) {
1306 printf("Linux 'widOpen' // CALLBACK_NULL !\n");
1309 printf("Linux 'widOpen' // CALLBACK_WINDOW !\n");
1312 printf("Linux 'widOpen' // CALLBACK_TASK !\n");
1315 printf("Linux 'widOpen' // CALLBACK_FUNCTION !\n");
1318 WInDev
[wDevID
].lpQueueHdr
= NULL
;
1319 WInDev
[wDevID
].unixdev
= audio
;
1320 WInDev
[wDevID
].bufsize
= abuf_size
;
1321 WInDev
[wDevID
].dwTotalRecorded
= 0;
1322 memcpy(&WInDev
[wDevID
].waveDesc
, lpDesc
, sizeof(WAVEOPENDESC
));
1323 if (lpDesc
->lpFormat
->wFormatTag
!= WAVE_FORMAT_PCM
) {
1324 printf("Linux 'widOpen' // Bad format %04X !\n",
1325 lpDesc
->lpFormat
->wFormatTag
);
1326 return WAVERR_BADFORMAT
;
1328 memcpy(&WInDev
[wDevID
].Format
, lpDesc
->lpFormat
, sizeof(PCMWAVEFORMAT
));
1329 WInDev
[wDevID
].Format
.wBitsPerSample
= 8; /* <-------------- */
1330 if (WInDev
[wDevID
].Format
.wf
.nChannels
== 0) return WAVERR_BADFORMAT
;
1331 if (WInDev
[wDevID
].Format
.wf
.nSamplesPerSec
== 0) return WAVERR_BADFORMAT
;
1332 if (WInDev
[wDevID
].Format
.wBitsPerSample
== 0) {
1333 WInDev
[wDevID
].Format
.wBitsPerSample
= 8 *
1334 (WInDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/
1335 WInDev
[wDevID
].Format
.wf
.nSamplesPerSec
) /
1336 WInDev
[wDevID
].Format
.wf
.nChannels
;
1338 samplesize
= WInDev
[wDevID
].Format
.wBitsPerSample
;
1339 smplrate
= WInDev
[wDevID
].Format
.wf
.nSamplesPerSec
;
1340 dsp_stereo
= (WInDev
[wDevID
].Format
.wf
.nChannels
> 1) ? TRUE
: FALSE
;
1341 IOCTL(audio
, SNDCTL_DSP_SPEED
, smplrate
);
1342 IOCTL(audio
, SNDCTL_DSP_SAMPLESIZE
, samplesize
);
1343 IOCTL(audio
, SNDCTL_DSP_STEREO
, dsp_stereo
);
1344 #ifdef DEBUG_MCIWAVE
1345 printf("Linux 'widOpen' // wBitsPerSample=%u !\n",
1346 WInDev
[wDevID
].Format
.wBitsPerSample
);
1347 printf("Linux 'widOpen' // nSamplesPerSec=%u !\n",
1348 WInDev
[wDevID
].Format
.wf
.nSamplesPerSec
);
1349 printf("Linux 'widOpen' // nChannels=%u !\n",
1350 WInDev
[wDevID
].Format
.wf
.nChannels
);
1351 printf("Linux 'widOpen' // nAvgBytesPerSec=%u\n",
1352 WInDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
);
1354 if (WAVE_NotifyClient(wDevID
, WIM_OPEN
, 0L, 0L) != MMSYSERR_NOERROR
) {
1355 printf("Linux 'widOpen' // can't notify client !\n");
1356 return MMSYSERR_INVALPARAM
;
1358 return MMSYSERR_NOERROR
;
1360 return MMSYSERR_NOTENABLED
;
1364 /**************************************************************************
1365 * widClose [internal]
1367 DWORD
widClose(WORD wDevID
)
1370 printf("widClose(%u);\n", wDevID
);
1371 if (WInDev
[wDevID
].unixdev
== 0) {
1372 printf("Linux 'widClose' // can't close !\n");
1373 return MMSYSERR_NOTENABLED
;
1375 close(WInDev
[wDevID
].unixdev
);
1376 WInDev
[wDevID
].unixdev
= 0;
1377 WInDev
[wDevID
].bufsize
= 0;
1378 if (WAVE_NotifyClient(wDevID
, WIM_CLOSE
, 0L, 0L) != MMSYSERR_NOERROR
) {
1379 printf("Linux 'widClose' // can't notify client !\n");
1380 return MMSYSERR_INVALPARAM
;
1382 return MMSYSERR_NOERROR
;
1384 return MMSYSERR_NOTENABLED
;
1388 /**************************************************************************
1389 * widAddBuffer [internal]
1391 DWORD
widAddBuffer(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
1396 printf("widAddBuffer(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
1397 if (WInDev
[wDevID
].unixdev
== 0) {
1398 printf("Linux 'widAddBuffer' // can't do it !\n");
1399 return MMSYSERR_NOTENABLED
;
1401 if (WInDev
[wDevID
].lpQueueHdr
== NULL
||
1402 !(lpWaveHdr
->dwFlags
& WHDR_PREPARED
)) {
1403 printf("Linux 'widAddBuffer' // never been prepared !\n");
1404 return WAVERR_UNPREPARED
;
1406 if ((lpWaveHdr
->dwFlags
& WHDR_INQUEUE
) &&
1407 (WInDev
[wDevID
].lpQueueHdr
!= lpWaveHdr
)) {
1408 /* except if it's the one just prepared ... */
1409 printf("Linux 'widAddBuffer' // header already in use !\n");
1410 return WAVERR_STILLPLAYING
;
1412 lpWaveHdr
->dwFlags
|= WHDR_PREPARED
;
1413 lpWaveHdr
->dwFlags
|= WHDR_INQUEUE
;
1414 lpWaveHdr
->dwFlags
&= ~WHDR_DONE
;
1415 lpWaveHdr
->dwBytesRecorded
= 0;
1416 /* added to the queue, except if it's the one just prepared ... */
1417 if (WInDev
[wDevID
].lpQueueHdr
!= lpWaveHdr
) {
1418 lpWIHdr
= WInDev
[wDevID
].lpQueueHdr
;
1419 while (lpWIHdr
->lpNext
!= NULL
) {
1420 lpWIHdr
= lpWIHdr
->lpNext
;
1423 lpWIHdr
->lpNext
= lpWaveHdr
;
1426 printf("widAddBuffer // buffer added ! (now %u in queue)\n", count
);
1427 return MMSYSERR_NOERROR
;
1429 return MMSYSERR_NOTENABLED
;
1433 /**************************************************************************
1434 * widPrepare [internal]
1436 DWORD
widPrepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
1439 printf("widPrepare(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
1440 if (WInDev
[wDevID
].unixdev
== 0) {
1441 printf("Linux 'widPrepare' // can't prepare !\n");
1442 return MMSYSERR_NOTENABLED
;
1444 if (WInDev
[wDevID
].lpQueueHdr
!= NULL
) {
1445 printf("Linux 'widPrepare' // already prepare !\n");
1446 return WAVERR_BADFORMAT
;
1448 WInDev
[wDevID
].dwTotalRecorded
= 0;
1449 WInDev
[wDevID
].lpQueueHdr
= lpWaveHdr
;
1450 if (lpWaveHdr
->dwFlags
& WHDR_INQUEUE
) return WAVERR_STILLPLAYING
;
1451 lpWaveHdr
->dwFlags
|= WHDR_PREPARED
;
1452 lpWaveHdr
->dwFlags
|= WHDR_INQUEUE
;
1453 lpWaveHdr
->dwFlags
&= ~WHDR_DONE
;
1454 lpWaveHdr
->dwBytesRecorded
= 0;
1455 printf("Linux 'widPrepare' // header prepared !\n");
1456 return MMSYSERR_NOERROR
;
1458 return MMSYSERR_NOTENABLED
;
1462 /**************************************************************************
1463 * widUnprepare [internal]
1465 DWORD
widUnprepare(WORD wDevID
, LPWAVEHDR lpWaveHdr
, DWORD dwSize
)
1468 printf("widUnprepare(%u, %08X, %08X);\n", wDevID
, lpWaveHdr
, dwSize
);
1469 if (WInDev
[wDevID
].unixdev
== 0) {
1470 printf("Linux 'widUnprepare' // can't unprepare !\n");
1471 return MMSYSERR_NOTENABLED
;
1473 lpWaveHdr
->dwFlags
&= ~WHDR_PREPARED
;
1474 lpWaveHdr
->dwFlags
&= ~WHDR_INQUEUE
;
1475 lpWaveHdr
->dwFlags
|= WHDR_DONE
;
1476 WInDev
[wDevID
].lpQueueHdr
= NULL
;
1477 printf("Linux 'widUnprepare' // all headers unprepared !\n");
1478 return MMSYSERR_NOERROR
;
1480 return MMSYSERR_NOTENABLED
;
1484 /**************************************************************************
1485 * widStart [internal]
1487 DWORD
widStart(WORD wDevID
)
1492 printf("widStart(%u);\n", wDevID
);
1493 if (WInDev
[wDevID
].unixdev
== 0) {
1494 printf("Linux 'widStart' // can't start recording !\n");
1495 return MMSYSERR_NOTENABLED
;
1497 if (WInDev
[wDevID
].lpQueueHdr
== NULL
||
1498 WInDev
[wDevID
].lpQueueHdr
->lpData
== NULL
) {
1499 printf("Linux 'widStart' // never been prepared !\n");
1500 return WAVERR_UNPREPARED
;
1502 lpWIHdr
= WInDev
[wDevID
].lpQueueHdr
;
1503 while(lpWIHdr
!= NULL
) {
1504 lpWIHdr
->dwBufferLength
&= 0xFFFF;
1505 printf("widStart // recording buf#%u=%08X size=%u \n",
1506 count
, lpWIHdr
->lpData
, lpWIHdr
->dwBufferLength
);
1508 read (WInDev
[wDevID
].unixdev
, lpWIHdr
->lpData
,
1509 lpWIHdr
->dwBufferLength
);
1510 lpWIHdr
->dwBytesRecorded
= lpWIHdr
->dwBufferLength
;
1511 WInDev
[wDevID
].dwTotalRecorded
+= lpWIHdr
->dwBytesRecorded
;
1512 lpWIHdr
->dwFlags
&= ~WHDR_INQUEUE
;
1513 lpWIHdr
->dwFlags
|= WHDR_DONE
;
1514 if (WAVE_NotifyClient(wDevID
, WIM_DATA
, (DWORD
)lpWIHdr
, 0L) !=
1516 printf("Linux 'widStart' // can't notify client !\n");
1517 return MMSYSERR_INVALPARAM
;
1519 lpWIHdr
= lpWIHdr
->lpNext
;
1522 printf("widStart // end of recording !\n");
1524 return MMSYSERR_NOERROR
;
1526 return MMSYSERR_NOTENABLED
;
1530 /**************************************************************************
1531 * widStop [internal]
1533 DWORD
widStop(WORD wDevID
)
1536 printf("widStop(%u);\n", wDevID
);
1537 if (WInDev
[wDevID
].unixdev
== 0) {
1538 printf("Linux 'widStop' // can't stop !\n");
1539 return MMSYSERR_NOTENABLED
;
1541 return MMSYSERR_NOERROR
;
1543 return MMSYSERR_NOTENABLED
;
1547 /**************************************************************************
1548 * widReset [internal]
1550 DWORD
widReset(WORD wDevID
)
1553 printf("widReset(%u);\n", wDevID
);
1554 if (WInDev
[wDevID
].unixdev
== 0) {
1555 printf("Linux 'widReset' // can't reset !\n");
1556 return MMSYSERR_NOTENABLED
;
1558 return MMSYSERR_NOERROR
;
1560 return MMSYSERR_NOTENABLED
;
1564 /**************************************************************************
1565 * widGetPosition [internal]
1567 DWORD
widGetPosition(WORD wDevID
, LPMMTIME lpTime
, DWORD uSize
)
1571 #ifdef DEBUG_MCIWAVE
1572 printf("widGetPosition(%u, %08X, %u);\n", wDevID
, lpTime
, uSize
);
1574 if (WInDev
[wDevID
].unixdev
== 0) {
1575 printf("Linux 'widGetPosition' // can't get pos !\n");
1576 return MMSYSERR_NOTENABLED
;
1578 if (lpTime
== NULL
) return MMSYSERR_INVALPARAM
;
1580 #ifdef DEBUG_MCIWAVE
1581 printf("widGetPosition // wType=%04X !\n", lpTime
->wType
);
1582 printf("widGetPosition // wBitsPerSample=%u\n",
1583 WInDev
[wDevID
].Format
.wBitsPerSample
);
1584 printf("widGetPosition // nSamplesPerSec=%u\n",
1585 WInDev
[wDevID
].Format
.wf
.nSamplesPerSec
);
1586 printf("widGetPosition // nChannels=%u\n",
1587 WInDev
[wDevID
].Format
.wf
.nChannels
);
1588 printf("widGetPosition // nAvgBytesPerSec=%u\n",
1589 WInDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
);
1592 switch(lpTime
->wType
) {
1594 lpTime
->u
.cb
= WInDev
[wDevID
].dwTotalRecorded
;
1595 printf("widGetPosition // TIME_BYTES=%u\n", lpTime
->u
.cb
);
1598 lpTime
->u
.sample
= WInDev
[wDevID
].dwTotalRecorded
* 8 /
1599 WInDev
[wDevID
].Format
.wBitsPerSample
;
1600 printf("widGetPosition // TIME_SAMPLES=%u\n", lpTime
->u
.sample
);
1603 lpTime
->u
.ms
= WInDev
[wDevID
].dwTotalRecorded
/
1604 (WInDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/ 1000);
1605 printf("widGetPosition // TIME_MS=%u\n", lpTime
->u
.ms
);
1608 time
= WInDev
[wDevID
].dwTotalRecorded
/
1609 (WInDev
[wDevID
].Format
.wf
.nAvgBytesPerSec
/ 1000);
1610 lpTime
->u
.smpte
.hour
= time
/ 108000;
1611 time
-= lpTime
->u
.smpte
.hour
* 108000;
1612 lpTime
->u
.smpte
.min
= time
/ 1800;
1613 time
-= lpTime
->u
.smpte
.min
* 1800;
1614 lpTime
->u
.smpte
.sec
= time
/ 30;
1615 time
-= lpTime
->u
.smpte
.sec
* 30;
1616 lpTime
->u
.smpte
.frame
= time
;
1617 lpTime
->u
.smpte
.fps
= 30;
1618 printf("widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1619 lpTime
->u
.smpte
.hour
, lpTime
->u
.smpte
.min
,
1620 lpTime
->u
.smpte
.sec
, lpTime
->u
.smpte
.frame
);
1623 printf("widGetPosition() format not supported ! use TIME_MS !\n");
1624 lpTime
->wType
= TIME_MS
;
1627 return MMSYSERR_NOERROR
;
1629 return MMSYSERR_NOTENABLED
;
1633 /**************************************************************************
1634 * widMessage [sample driver]
1636 DWORD
widMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1637 DWORD dwParam1
, DWORD dwParam2
)
1639 printf("widMessage(%u, %04X, %08X, %08X, %08X);\n",
1640 wDevID
, wMsg
, dwUser
, dwParam1
, dwParam2
);
1643 return widOpen(wDevID
, (LPWAVEOPENDESC
)dwParam1
, dwParam2
);
1645 return widClose(wDevID
);
1646 case WIDM_ADDBUFFER
:
1647 return widAddBuffer(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1649 return widPrepare(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1650 case WIDM_UNPREPARE
:
1651 return widUnprepare(wDevID
, (LPWAVEHDR
)dwParam1
, dwParam2
);
1652 case WIDM_GETDEVCAPS
:
1653 return widGetDevCaps(wDevID
, (LPWAVEINCAPS
)dwParam1
, dwParam2
);
1654 case WIDM_GETNUMDEVS
:
1657 return widGetPosition(wDevID
, (LPMMTIME
)dwParam1
, dwParam2
);
1659 return widReset(wDevID
);
1661 return widStart(wDevID
);
1663 return widStop(wDevID
);
1665 return MMSYSERR_NOTSUPPORTED
;
1669 /*-----------------------------------------------------------------------*/
1673 /**************************************************************************
1674 * midMessage [sample driver]
1676 DWORD
midMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1677 DWORD dwParam1
, DWORD dwParam2
)
1679 return MMSYSERR_NOTENABLED
;
1682 /**************************************************************************
1683 * modMessage [sample driver]
1685 DWORD
modMessage(WORD wDevID
, WORD wMsg
, DWORD dwUser
,
1686 DWORD dwParam1
, DWORD dwParam2
)
1688 return MMSYSERR_NOTENABLED
;
1691 #endif /* #ifdef BUILTIN_MMSYSTEM */