2 * Sample Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
8 #define BUILTIN_MMSYSTEM
11 #ifdef BUILTIN_MMSYSTEM
19 #include <sys/ioctl.h>
25 #include "stackframe.h"
28 #include <linux/soundcard.h>
35 #define SOUND_DEV "/dev/dsp"
38 #define IOCTL(a,b,c) ((-1==ioctl(a,b,&c))&&(perror("ioctl:"#b":"#c),0))
40 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
43 #define MAX_WAVOUTDRV 2
44 #define MAX_WAVINDRV 2
45 #define MAX_MCIWAVDRV 2
51 WAVEOPENDESC waveDesc;
61 DWORD bufsize; /* Linux '/dev/dsp' give us that size */
62 WAVEOPENDESC waveDesc;
66 DWORD dwTotalRecorded;
70 int nUseCount; /* Incremented for each shared open */
71 BOOL fShareable; /* TRUE if first open was shareable */
72 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
73 HANDLE hCallback; /* Callback handle for pending notification */
74 HMMIO hFile; /* mmio file handle open as Element */
75 MCI_WAVE_OPEN_PARMS openParms;
76 PCMWAVEFORMAT WaveFormat;
80 static LINUX_WAVEOUT WOutDev[MAX_WAVOUTDRV];
81 static LINUX_WAVEIN WInDev[MAX_WAVOUTDRV];
82 static LINUX_MCIWAVE MCIWavDev[MAX_MCIWAVDRV];
85 /**************************************************************************
86 * WAVE_NotifyClient [internal]
88 static DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg,
89 DWORD dwParam1, DWORD dwParam2)
91 if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
92 WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags,
93 WInDev[wDevID].waveDesc.hWave, wMsg,
94 WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
95 dprintf_mciwave(stddeb,"WAVE_NotifyClient // can't notify client !\n");
96 return MMSYSERR_NOERROR;
102 /**************************************************************************
104 static DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
107 LPPCMWAVEFORMAT lpWaveFormat;
109 LPWAVEOPENDESC lpDesc;
110 LPSTR lpstrElementName;
114 dprintf_mciwave(stddeb,"WAVE_mciOpen(%04X, %08lX, %p)\n",
115 wDevID, dwFlags, lpParms);
116 if (lpParms == NULL) return MCIERR_INTERNAL;
117 dprintf_mciwave(stddeb,"WAVE_mciOpen // wDevID=%04X\n", wDevID);
118 if (MCIWavDev[wDevID].nUseCount > 0) {
119 /* The driver already open on this channel */
120 /* If the driver was opened shareable before and this open specifies */
121 /* shareable then increment the use count */
122 if (MCIWavDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
123 ++MCIWavDev[wDevID].nUseCount;
125 return MCIERR_MUST_USE_SHAREABLE;
128 MCIWavDev[wDevID].nUseCount = 1;
129 MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
131 dprintf_mciwave(stddeb,"WAVE_mciOpen // before setting lParams->wDeviceID // winstack=%p ds=%04X ss=%04X sp=%04X\n",
132 (BYTE *)CURRENT_STACK16->args,
133 CURRENT_STACK16->ds, IF1632_Saved16_ss, IF1632_Saved16_sp);
134 lpParms->wDeviceID = wDevID;
135 dprintf_mciwave(stddeb,"WAVE_mciOpen // wDevID=%04X\n", wDevID);
136 dprintf_mciwave(stddeb,"WAVE_mciOpen // before OPEN_ELEMENT\n");
137 if (dwFlags & MCI_OPEN_ELEMENT) {
138 lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
139 dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
141 /* printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
142 if (strlen(lpstrElementName) > 0) {
143 strcpy(str, lpstrElementName);
145 MCIWavDev[wDevID].hFile = mmioOpen(str, NULL,
146 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
147 if (MCIWavDev[wDevID].hFile == 0) {
148 dprintf_mciwave(stddeb,"WAVE_mciOpen // can't find file='%s' !\n", str);
149 return MCIERR_FILE_NOT_FOUND;
153 MCIWavDev[wDevID].hFile = 0;
155 dprintf_mciwave(stddeb,"WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
156 memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
157 MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
158 lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
159 hDesc = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
160 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hDesc);
163 lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
164 lpWaveFormat->wBitsPerSample = 8;
165 lpWaveFormat->wf.nChannels = 1;
166 lpWaveFormat->wf.nSamplesPerSec = 11025;
167 lpWaveFormat->wf.nAvgBytesPerSec = 11025;
168 lpWaveFormat->wf.nBlockAlign = 1;
170 if (MCIWavDev[wDevID].hFile != 0) {
173 if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
174 return MCIERR_INTERNAL;
176 dprintf_mciwave(stddeb,
177 "WAVE_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
178 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
180 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
181 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) {
182 return MCIERR_INTERNAL;
184 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
185 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
186 return MCIERR_INTERNAL;
188 dprintf_mciwave(stddeb,
189 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
190 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
192 if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
193 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) {
194 return MCIERR_INTERNAL;
196 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
197 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
198 return MCIERR_INTERNAL;
200 dprintf_mciwave(stddeb,
201 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
202 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
204 dprintf_mciwave(stddeb,
205 "WAVE_mciOpen // nChannels=%d nSamplesPerSec=%ld\n",
206 lpWaveFormat->wf.nChannels, lpWaveFormat->wf.nSamplesPerSec);
207 lpWaveFormat->wBitsPerSample = 0;
209 lpWaveFormat->wf.nAvgBytesPerSec =
210 lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
211 hFormat = USER_HEAP_ALLOC(sizeof(PCMWAVEFORMAT));
212 lpDesc->lpFormat = (LPWAVEFORMAT) USER_HEAP_LIN_ADDR(hFormat);
213 memcpy(lpDesc->lpFormat, lpWaveFormat, sizeof(PCMWAVEFORMAT));
214 lpDesc = (LPWAVEOPENDESC) USER_HEAP_SEG_ADDR(hDesc);
215 dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
216 dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)lpDesc, CALLBACK_NULL);
217 USER_HEAP_FREE(hFormat);
218 USER_HEAP_FREE(hDesc);
222 /**************************************************************************
223 * WAVE_mciClose [internal]
225 static DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
228 dprintf_mciwave(stddeb,
229 "WAVE_mciClose(%u, %08lX, %p);\n", wDevID, dwParam, lpParms);
230 MCIWavDev[wDevID].nUseCount--;
231 if (MCIWavDev[wDevID].nUseCount == 0) {
232 if (MCIWavDev[wDevID].hFile != 0) {
233 mmioClose(MCIWavDev[wDevID].hFile, 0);
234 MCIWavDev[wDevID].hFile = 0;
236 dwRet = wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
237 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
238 dwRet = widMessage(0, WIDM_CLOSE, 0, 0L, 0L);
239 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
245 /**************************************************************************
246 * WAVE_mciPlay [internal]
248 static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
255 LPWAVEHDR lp16WaveHdr;
257 dprintf_mciwave(stddeb,
258 "WAVE_mciPlay(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
259 if (MCIWavDev[wDevID].hFile == 0) {
260 dprintf_mciwave(stddeb,"WAVE_mciPlay // can't find file='%s' !\n",
261 MCIWavDev[wDevID].openParms.lpstrElementName);
262 return MCIERR_FILE_NOT_FOUND;
264 start = 1; end = 99999;
265 if (dwFlags & MCI_FROM) {
266 start = lpParms->dwFrom;
267 dprintf_mciwave(stddeb,
268 "WAVE_mciPlay // MCI_FROM=%d \n", start);
270 if (dwFlags & MCI_TO) {
272 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_TO=%d \n", end);
275 if (dwFlags & MCI_NOTIFY) {
276 dprintf_mciwave(stddeb,
277 "WAVE_mciPlay // MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
280 dprintf_mciwave(stddeb,
281 "WAVE_mciPlay // Can't 'fork' process !\n");
286 dprintf_mciwave(stddeb,"WAVE_mciPlay // process started ! return to caller...\n");
292 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
293 hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
294 lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
295 lpWaveHdr->dwUser = 0L;
296 lpWaveHdr->dwFlags = 0L;
297 lpWaveHdr->dwLoops = 0L;
298 hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
299 lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
300 memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
301 lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
302 dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
304 count = mmioRead(MCIWavDev[wDevID].hFile,
305 PTR_SEG_TO_LIN(lpWaveHdr->lpData), bufsize);
306 dprintf_mciwave(stddeb,"WAVE_mciPlay // mmioRead bufsize=%ld count=%ld\n", bufsize, count);
307 if (count < 1) break;
308 lpWaveHdr->dwBufferLength = count;
309 /* lpWaveHdr->dwBytesRecorded = count; */
310 dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%p dwBufferLength=%lu dwBytesRecorded=%lu\n",
311 lpWaveHdr, lpWaveHdr->dwBufferLength, lpWaveHdr->dwBytesRecorded);
312 dwRet = wodMessage(0, WODM_WRITE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
314 dwRet = wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
315 if (lpWaveHdr->lpData != NULL) {
318 lpWaveHdr->lpData = NULL;
320 USER_HEAP_FREE(hWaveHdr);
321 if (dwFlags & MCI_NOTIFY) {
322 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
323 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
324 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
331 /**************************************************************************
332 * WAVE_mciRecord [internal]
334 static DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
341 LPWAVEHDR lp16WaveHdr;
344 dprintf_mciwave(stddeb,
345 "WAVE_mciRecord(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
346 if (MCIWavDev[wDevID].hFile == 0) {
347 dprintf_mciwave(stddeb,"WAVE_mciRecord // can't find file='%s' !\n",
348 MCIWavDev[wDevID].openParms.lpstrElementName);
349 return MCIERR_FILE_NOT_FOUND;
351 start = 1; end = 99999;
352 if (dwFlags & MCI_FROM) {
353 start = lpParms->dwFrom;
354 dprintf_mciwave(stddeb,
355 "WAVE_mciRecord // MCI_FROM=%d \n", start);
357 if (dwFlags & MCI_TO) {
359 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_TO=%d \n", end);
362 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
363 hData = GlobalAlloc(GMEM_MOVEABLE, bufsize);
364 lpWaveHdr->lpData = (LPSTR) WIN16_GlobalLock(hData);
365 lpWaveHdr->dwBufferLength = bufsize;
366 lpWaveHdr->dwUser = 0L;
367 lpWaveHdr->dwFlags = 0L;
368 lpWaveHdr->dwLoops = 0L;
369 hWaveHdr = USER_HEAP_ALLOC(sizeof(WAVEHDR));
370 lp16WaveHdr = (LPWAVEHDR) USER_HEAP_SEG_ADDR(hWaveHdr);
371 memcpy(PTR_SEG_TO_LIN(lp16WaveHdr), lpWaveHdr, sizeof(WAVEHDR));
372 lpWaveHdr = PTR_SEG_TO_LIN(lp16WaveHdr);
373 dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
374 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
376 lpWaveHdr->dwBytesRecorded = 0;
377 dwRet = widMessage(0, WIDM_START, 0, 0L, 0L);
378 dprintf_mciwave(stddeb,
379 "WAVE_mciRecord // after WIDM_START lpWaveHdr=%p dwBytesRecorded=%lu\n",
380 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
381 if (lpWaveHdr->dwBytesRecorded == 0) break;
383 dprintf_mciwave(stddeb,"WAVE_mciRecord // before WIDM_UNPREPARE \n");
384 dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lp16WaveHdr, sizeof(WAVEHDR));
385 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
386 if (lpWaveHdr->lpData != NULL) {
389 lpWaveHdr->lpData = NULL;
391 USER_HEAP_FREE(hWaveHdr);
392 if (dwFlags & MCI_NOTIFY) {
393 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
394 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
395 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
401 /**************************************************************************
402 * WAVE_mciStop [internal]
404 static DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
406 dprintf_mciwave(stddeb,
407 "WAVE_mciStop(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
408 if (lpParms == NULL) return MCIERR_INTERNAL;
413 /**************************************************************************
414 * WAVE_mciPause [internal]
416 static DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
418 dprintf_mciwave(stddeb,
419 "WAVE_mciPause(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
420 if (lpParms == NULL) return MCIERR_INTERNAL;
425 /**************************************************************************
426 * WAVE_mciResume [internal]
428 static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
430 dprintf_mciwave(stddeb,
431 "WAVE_mciResume(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
432 if (lpParms == NULL) return MCIERR_INTERNAL;
437 /**************************************************************************
438 * WAVE_mciSet [internal]
440 static DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
442 dprintf_mciwave(stddeb,
443 "WAVE_mciSet(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
444 if (lpParms == NULL) return MCIERR_INTERNAL;
445 dprintf_mciwave(stddeb,
446 "WAVE_mciSet // dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
447 dprintf_mciwave(stddeb,
448 "WAVE_mciSet // dwAudio=%08lX\n", lpParms->dwAudio);
449 if (dwFlags & MCI_SET_TIME_FORMAT) {
450 switch (lpParms->dwTimeFormat) {
451 case MCI_FORMAT_MILLISECONDS:
452 dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
454 case MCI_FORMAT_BYTES:
455 dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
457 case MCI_FORMAT_SAMPLES:
458 dprintf_mciwave(stddeb, "WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
461 dprintf_mciwave(stddeb, "WAVE_mciSet // bad time format !\n");
462 return MCIERR_BAD_TIME_FORMAT;
465 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
466 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
467 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
468 if (dwFlags & MCI_SET_AUDIO)
469 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO !\n");
470 if (dwFlags && MCI_SET_ON) {
471 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_ON !\n");
472 if (dwFlags && MCI_SET_AUDIO_LEFT)
473 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
474 if (dwFlags && MCI_SET_AUDIO_RIGHT)
475 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
477 if (dwFlags & MCI_SET_OFF)
478 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_OFF !\n");
479 if (dwFlags & MCI_WAVE_INPUT)
480 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_INPUT !\n");
481 if (dwFlags & MCI_WAVE_OUTPUT)
482 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
483 if (dwFlags & MCI_WAVE_SET_ANYINPUT)
484 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
485 if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)
486 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
487 if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC)
488 dprintf_mciwave(stddeb,
489 "WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
490 if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE)
491 dprintf_mciwave(stddeb,
492 "WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
493 if (dwFlags & MCI_WAVE_SET_BLOCKALIGN)
494 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
495 if (dwFlags & MCI_WAVE_SET_CHANNELS)
496 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
497 if (dwFlags & MCI_WAVE_SET_FORMATTAG)
498 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
499 if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC)
500 dprintf_mciwave(stddeb,
501 "WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
506 /**************************************************************************
507 * WAVE_mciStatus [internal]
509 static DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
511 dprintf_mciwave(stddeb,
512 "WAVE_mciStatus(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
513 if (lpParms == NULL) return MCIERR_INTERNAL;
514 if (dwFlags & MCI_STATUS_ITEM) {
515 switch(lpParms->dwItem) {
516 case MCI_STATUS_CURRENT_TRACK:
517 lpParms->dwReturn = 1;
519 case MCI_STATUS_LENGTH:
520 lpParms->dwReturn = 5555;
521 if (dwFlags & MCI_TRACK) {
522 lpParms->dwTrack = 1;
523 lpParms->dwReturn = 2222;
526 case MCI_STATUS_MODE:
527 lpParms->dwReturn = MCI_MODE_STOP;
529 case MCI_STATUS_MEDIA_PRESENT:
530 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
531 lpParms->dwReturn = TRUE;
533 case MCI_STATUS_NUMBER_OF_TRACKS:
534 lpParms->dwReturn = 1;
536 case MCI_STATUS_POSITION:
537 lpParms->dwReturn = 3333;
538 if (dwFlags & MCI_STATUS_START) {
541 if (dwFlags & MCI_TRACK) {
542 lpParms->dwTrack = 1;
543 lpParms->dwReturn = 777;
546 case MCI_STATUS_READY:
547 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_READY !\n");
548 lpParms->dwReturn = TRUE;
550 case MCI_STATUS_TIME_FORMAT:
551 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
552 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
555 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_INPUT !\n");
556 lpParms->dwReturn = 0;
558 case MCI_WAVE_OUTPUT:
559 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
560 lpParms->dwReturn = 0;
562 case MCI_WAVE_STATUS_AVGBYTESPERSEC:
563 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
564 lpParms->dwReturn = 22050;
566 case MCI_WAVE_STATUS_BITSPERSAMPLE:
567 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
568 lpParms->dwReturn = 8;
570 case MCI_WAVE_STATUS_BLOCKALIGN:
571 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
572 lpParms->dwReturn = 1;
574 case MCI_WAVE_STATUS_CHANNELS:
575 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
576 lpParms->dwReturn = 1;
578 case MCI_WAVE_STATUS_FORMATTAG:
579 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
580 lpParms->dwReturn = WAVE_FORMAT_PCM;
582 case MCI_WAVE_STATUS_LEVEL:
583 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
584 lpParms->dwReturn = 0xAAAA5555;
586 case MCI_WAVE_STATUS_SAMPLESPERSEC:
587 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
588 lpParms->dwReturn = 22050;
591 dprintf_mciwave(stddeb,"WAVE_mciStatus // unknown command %08lX !\n", lpParms->dwItem);
592 return MCIERR_UNRECOGNIZED_COMMAND;
595 if (dwFlags & MCI_NOTIFY) {
596 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
597 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
598 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
603 /**************************************************************************
604 * WAVE_mciGetDevCaps [internal]
606 static DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
607 LPMCI_GETDEVCAPS_PARMS lpParms)
609 dprintf_mciwave(stddeb,
610 "WAVE_mciGetDevCaps(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
611 if (lpParms == NULL) return MCIERR_INTERNAL;
612 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
613 switch(lpParms->dwItem) {
614 case MCI_GETDEVCAPS_CAN_RECORD:
615 lpParms->dwReturn = TRUE;
617 case MCI_GETDEVCAPS_HAS_AUDIO:
618 lpParms->dwReturn = TRUE;
620 case MCI_GETDEVCAPS_HAS_VIDEO:
621 lpParms->dwReturn = FALSE;
623 case MCI_GETDEVCAPS_DEVICE_TYPE:
624 lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
626 case MCI_GETDEVCAPS_USES_FILES:
627 lpParms->dwReturn = TRUE;
629 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
630 lpParms->dwReturn = TRUE;
632 case MCI_GETDEVCAPS_CAN_EJECT:
633 lpParms->dwReturn = FALSE;
635 case MCI_GETDEVCAPS_CAN_PLAY:
636 lpParms->dwReturn = TRUE;
638 case MCI_GETDEVCAPS_CAN_SAVE:
639 lpParms->dwReturn = TRUE;
641 case MCI_WAVE_GETDEVCAPS_INPUTS:
642 lpParms->dwReturn = 1;
644 case MCI_WAVE_GETDEVCAPS_OUTPUTS:
645 lpParms->dwReturn = 1;
648 return MCIERR_UNRECOGNIZED_COMMAND;
654 /**************************************************************************
655 * WAVE_mciInfo [internal]
657 static DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
659 dprintf_mciwave(stddeb,
660 "WAVE_mciInfo(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
661 if (lpParms == NULL) return MCIERR_INTERNAL;
662 lpParms->lpstrReturn = NULL;
664 case MCI_INFO_PRODUCT:
665 lpParms->lpstrReturn = "Linux Sound System 0.5";
668 lpParms->lpstrReturn =
669 (LPSTR)MCIWavDev[wDevID].openParms.lpstrElementName;
672 lpParms->lpstrReturn = "Linux Sound System 0.5";
674 case MCI_WAVE_OUTPUT:
675 lpParms->lpstrReturn = "Linux Sound System 0.5";
678 return MCIERR_UNRECOGNIZED_COMMAND;
680 if (lpParms->lpstrReturn != NULL)
681 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
683 lpParms->dwRetSize = 0;
688 /*-----------------------------------------------------------------------*/
691 /**************************************************************************
692 * wodGetDevCaps [internal]
694 static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
701 dprintf_mciwave(stddeb,
702 "wodGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
703 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
704 audio = open (SOUND_DEV, O_WRONLY, 0);
705 if (audio == -1) return MMSYSERR_NOTENABLED;
707 lpCaps->wMid = 0x0002;
708 lpCaps->wPid = 0x0104;
709 strcpy(lpCaps->szPname, "SB16 Wave Out");
711 lpCaps->wMid = 0x00FF; /* Manufac ID */
712 lpCaps->wPid = 0x0001; /* Product ID */
713 strcpy(lpCaps->szPname, "Linux WAVOUT Driver");
715 lpCaps->dwFormats = 0x00000000;
716 lpCaps->dwSupport = WAVECAPS_VOLUME;
717 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
718 if (lpCaps->wChannels > 1) lpCaps->dwSupport |= WAVECAPS_LRVOLUME;
719 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
721 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
722 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
723 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
724 if (bytespersmpl > 1) {
725 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
726 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
730 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
731 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
732 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
733 if (bytespersmpl > 1) {
734 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
735 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
739 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
740 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
741 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
742 if (bytespersmpl > 1) {
743 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
744 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
748 dprintf_mciwave(stddeb,
749 "wodGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
750 return MMSYSERR_NOERROR;
754 /**************************************************************************
757 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
764 LPWAVEFORMAT lpFormat;
766 dprintf_mciwave(stddeb,
767 "wodOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
768 if (lpDesc == NULL) {
769 dprintf_mciwave(stddeb,"Linux 'wodOpen' // Invalid Parameter !\n");
770 return MMSYSERR_INVALPARAM;
772 if (wDevID >= MAX_WAVOUTDRV) {
773 dprintf_mciwave(stddeb,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
774 return MMSYSERR_ALLOCATED;
776 WOutDev[wDevID].unixdev = 0;
777 audio = open (SOUND_DEV, O_WRONLY, 0);
779 dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't open !\n");
780 return MMSYSERR_NOTENABLED;
782 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
783 if (abuf_size < 4096 || abuf_size > 65536) {
785 dprintf_mciwave(stddeb,"Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
787 dprintf_mciwave(stddeb,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
788 return MMSYSERR_NOTENABLED;
790 WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
791 switch(WOutDev[wDevID].wFlags) {
793 dprintf_mciwave(stddeb, "Linux 'wodOpen' // CALLBACK_NULL !\n");
796 dprintf_mciwave(stddeb, "Linux 'wodOpen' // CALLBACK_WINDOW !\n");
799 dprintf_mciwave(stddeb, "Linux 'wodOpen' // CALLBACK_TASK !\n");
802 dprintf_mciwave(stddeb, "Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
805 WOutDev[wDevID].lpQueueHdr = NULL;
806 WOutDev[wDevID].unixdev = audio;
807 WOutDev[wDevID].dwTotalPlayed = 0;
808 WOutDev[wDevID].bufsize = abuf_size;
809 memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
810 /* lpFormat = (LPWAVEFORMAT) PTR_SEG_TO_LIN(lpDesc->lpFormat); */
811 lpFormat = lpDesc->lpFormat;
812 if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
813 dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad format %04X !\n",
814 lpFormat->wFormatTag);
815 dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad nChannels %d !\n",
816 lpFormat->nChannels);
817 dprintf_mciwave(stddeb,"Linux 'wodOpen' // Bad nSamplesPerSec %ld !\n",
818 lpFormat->nSamplesPerSec);
819 return WAVERR_BADFORMAT;
821 memcpy(&WOutDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
822 if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
823 if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
824 dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
825 WOutDev[wDevID].Format.wBitsPerSample);
826 if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
827 WOutDev[wDevID].Format.wBitsPerSample = 8 *
828 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
829 WOutDev[wDevID].Format.wf.nSamplesPerSec) /
830 WOutDev[wDevID].Format.wf.nChannels;
832 samplesize = WOutDev[wDevID].Format.wBitsPerSample;
833 smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
834 dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
835 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
836 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
837 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
838 dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
839 WOutDev[wDevID].Format.wBitsPerSample);
840 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nAvgBytesPerSec=%lu !\n",
841 WOutDev[wDevID].Format.wf.nAvgBytesPerSec);
842 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nSamplesPerSec=%lu !\n",
843 WOutDev[wDevID].Format.wf.nSamplesPerSec);
844 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nChannels=%u !\n",
845 WOutDev[wDevID].Format.wf.nChannels);
846 if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
847 dprintf_mciwave(stddeb,"Linux 'wodOpen' // can't notify client !\n");
848 return MMSYSERR_INVALPARAM;
850 return MMSYSERR_NOERROR;
853 /**************************************************************************
854 * wodClose [internal]
856 static DWORD wodClose(WORD wDevID)
858 dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
859 if (WOutDev[wDevID].unixdev == 0) {
860 dprintf_mciwave(stddeb,"Linux 'wodClose' // can't close !\n");
861 return MMSYSERR_NOTENABLED;
863 close(WOutDev[wDevID].unixdev);
864 WOutDev[wDevID].unixdev = 0;
865 WOutDev[wDevID].bufsize = 0;
866 WOutDev[wDevID].lpQueueHdr = NULL;
867 if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
868 dprintf_mciwave(stddeb,"Linux 'wodClose' // can't notify client !\n");
869 return MMSYSERR_INVALPARAM;
871 return MMSYSERR_NOERROR;
874 /**************************************************************************
875 * wodWrite [internal]
877 static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
881 dprintf_mciwave(stddeb,"wodWrite(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
882 if (WOutDev[wDevID].unixdev == 0) {
883 dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't play !\n");
884 return MMSYSERR_NOTENABLED;
886 if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
887 if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
888 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
889 lpWaveHdr->dwFlags &= ~WHDR_DONE;
890 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
891 dprintf_mciwave(stddeb,
892 "wodWrite() // dwBufferLength %lu !\n", lpWaveHdr->dwBufferLength);
893 dprintf_mciwave(stddeb,
894 "wodWrite() // WOutDev[%u].unixdev %u !\n", wDevID, WOutDev[wDevID].unixdev);
895 lpData = PTR_SEG_TO_LIN(lpWaveHdr->lpData);
896 count = write (WOutDev[wDevID].unixdev, lpData, lpWaveHdr->dwBufferLength);
897 dprintf_mciwave(stddeb,
898 "wodWrite() // write returned count %u !\n", count);
899 if (count != lpWaveHdr->dwBufferLength) {
900 dprintf_mciwave(stddeb,"Linux 'wodWrite' // error writting !\n");
901 return MMSYSERR_NOTENABLED;
903 WOutDev[wDevID].dwTotalPlayed += count;
904 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
905 lpWaveHdr->dwFlags |= WHDR_DONE;
906 if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
907 dprintf_mciwave(stddeb,"Linux 'wodWrite' // can't notify client !\n");
908 return MMSYSERR_INVALPARAM;
910 return MMSYSERR_NOERROR;
913 /**************************************************************************
914 * wodPrepare [internal]
916 static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
918 dprintf_mciwave(stddeb,
919 "wodPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
920 if (WOutDev[wDevID].unixdev == 0) {
921 dprintf_mciwave(stddeb,"Linux 'wodPrepare' // can't prepare !\n");
922 return MMSYSERR_NOTENABLED;
924 /* the COOL waveeditor feels much better without this check...
925 * someone please have a look at available documentation
926 if (WOutDev[wDevID].lpQueueHdr != NULL) {
927 dprintf_mciwave(stddeb,"Linux 'wodPrepare' // already prepare !\n");
928 return MMSYSERR_NOTENABLED;
931 WOutDev[wDevID].dwTotalPlayed = 0;
932 WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
933 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
934 lpWaveHdr->dwFlags |= WHDR_PREPARED;
935 lpWaveHdr->dwFlags &= ~WHDR_DONE;
936 return MMSYSERR_NOERROR;
939 /**************************************************************************
940 * wodUnprepare [internal]
942 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
944 dprintf_mciwave(stddeb,
945 "wodUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
946 if (WOutDev[wDevID].unixdev == 0) {
947 dprintf_mciwave(stddeb,"Linux 'wodUnprepare' // can't unprepare !\n");
948 return MMSYSERR_NOTENABLED;
950 return MMSYSERR_NOERROR;
953 /**************************************************************************
954 * wodRestart [internal]
956 static DWORD wodRestart(WORD wDevID)
958 dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
959 if (WOutDev[wDevID].unixdev == 0) {
960 dprintf_mciwave(stddeb,"Linux 'wodRestart' // can't restart !\n");
961 return MMSYSERR_NOTENABLED;
963 return MMSYSERR_NOERROR;
966 /**************************************************************************
967 * wodReset [internal]
969 static DWORD wodReset(WORD wDevID)
971 dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
972 if (WOutDev[wDevID].unixdev == 0) {
973 dprintf_mciwave(stddeb,"Linux 'wodReset' // can't reset !\n");
974 return MMSYSERR_NOTENABLED;
976 return MMSYSERR_NOERROR;
980 /**************************************************************************
981 * wodGetPosition [internal]
983 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
986 dprintf_mciwave(stddeb,"wodGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
987 if (WOutDev[wDevID].unixdev == 0) {
988 dprintf_mciwave(stddeb,"Linux 'wodGetPosition' // can't get pos !\n");
989 return MMSYSERR_NOTENABLED;
991 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
992 switch(lpTime->wType) {
994 lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
995 dprintf_mciwave(stddeb,"wodGetPosition // TIME_BYTES=%lu\n", lpTime->u.cb);
998 dprintf_mciwave(stddeb,"wodGetPosition // dwTotalPlayed=%lu\n",
999 WOutDev[wDevID].dwTotalPlayed);
1000 dprintf_mciwave(stddeb,"wodGetPosition // wBitsPerSample=%u\n",
1001 WOutDev[wDevID].Format.wBitsPerSample);
1002 lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
1003 WOutDev[wDevID].Format.wBitsPerSample;
1004 dprintf_mciwave(stddeb,"wodGetPosition // TIME_SAMPLES=%lu\n", lpTime->u.sample);
1007 time = WOutDev[wDevID].dwTotalPlayed /
1008 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1009 lpTime->u.smpte.hour = time / 108000;
1010 time -= lpTime->u.smpte.hour * 108000;
1011 lpTime->u.smpte.min = time / 1800;
1012 time -= lpTime->u.smpte.min * 1800;
1013 lpTime->u.smpte.sec = time / 30;
1014 time -= lpTime->u.smpte.sec * 30;
1015 lpTime->u.smpte.frame = time;
1016 lpTime->u.smpte.fps = 30;
1017 dprintf_mciwave(stddeb,
1018 "wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1019 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1020 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1023 dprintf_mciwave(stddeb,"wodGetPosition() format not supported ! use TIME_MS !\n");
1024 lpTime->wType = TIME_MS;
1026 lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
1027 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1028 dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
1031 return MMSYSERR_NOERROR;
1034 /**************************************************************************
1035 * wodGetVolume [internal]
1037 static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
1040 int volume, left, right;
1041 dprintf_mciwave(stddeb,"wodGetVolume(%u, %p);\n", wDevID, lpdwVol);
1042 if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
1043 if ((mixer = open("/dev/mixer", O_RDONLY)) < 0) {
1044 dprintf_mciwave(stddeb, "Linux 'wodGetVolume' // mixer device not available !\n");
1045 return MMSYSERR_NOTENABLED;
1047 if (ioctl(mixer, SOUND_MIXER_READ_PCM, &volume) == -1) {
1048 dprintf_mciwave(stddeb,"Linux 'wodGetVolume' // unable read mixer !\n");
1049 return MMSYSERR_NOTENABLED;
1052 left = volume & 0x7F;
1053 right = (volume >> 8) & 0x7F;
1054 printf("Linux 'AUX_GetVolume' // left=%d right=%d !\n", left, right);
1055 *lpdwVol = MAKELONG(left << 9, right << 9);
1056 return MMSYSERR_NOERROR;
1060 /**************************************************************************
1061 * wodSetVolume [internal]
1063 static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1067 dprintf_mciwave(stddeb,"wodSetVolume(%u, %08lX);\n", wDevID, dwParam);
1068 volume = (LOWORD(dwParam) >> 9 & 0x7F) +
1069 ((HIWORD(dwParam) >> 9 & 0x7F) << 8);
1070 if ((mixer = open("/dev/mixer", O_WRONLY)) < 0) {
1071 dprintf_mciwave(stddeb, "Linux 'wodSetVolume' // mixer device not available !\n");
1072 return MMSYSERR_NOTENABLED;
1074 if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
1075 dprintf_mciwave(stddeb,"Linux 'wodSetVolume' // unable set mixer !\n");
1076 return MMSYSERR_NOTENABLED;
1079 return MMSYSERR_NOERROR;
1084 /**************************************************************************
1085 * wodMessage [sample driver]
1087 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1088 DWORD dwParam1, DWORD dwParam2)
1090 dprintf_mciwave(stddeb,"wodMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1091 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1095 return wodOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1097 return wodClose(wDevID);
1099 return wodWrite(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1103 return wodGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1104 case WODM_BREAKLOOP:
1107 return wodPrepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1108 case WODM_UNPREPARE:
1109 return wodUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1110 case WODM_GETDEVCAPS:
1111 return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1112 case WODM_GETNUMDEVS:
1118 case WODM_GETPLAYBACKRATE:
1120 case WODM_SETPLAYBACKRATE:
1122 case WODM_GETVOLUME:
1123 return wodGetVolume(wDevID, (LPDWORD)PTR_SEG_TO_LIN(dwParam1));
1124 case WODM_SETVOLUME:
1125 return wodSetVolume(wDevID, dwParam1);
1127 return wodRestart(wDevID);
1129 return wodReset(wDevID);
1131 dprintf_mciwave(stddeb,"wodMessage // unknown message !\n");
1133 return MMSYSERR_NOTSUPPORTED;
1135 return MMSYSERR_NOTENABLED;
1140 /*-----------------------------------------------------------------------*/
1144 /**************************************************************************
1145 * widGetDevCaps [internal]
1147 static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
1151 int samplesize = 16;
1154 dprintf_mciwave(stddeb,
1155 "widGetDevCaps(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
1156 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1157 audio = open (SOUND_DEV, O_RDONLY, 0);
1158 if (audio == -1) return MMSYSERR_NOTENABLED;
1160 lpCaps->wMid = 0x0002;
1161 lpCaps->wPid = 0x0004;
1162 strcpy(lpCaps->szPname, "SB16 Wave Out");
1164 lpCaps->wMid = 0x00FF; /* Manufac ID */
1165 lpCaps->wPid = 0x0001; /* Product ID */
1166 strcpy(lpCaps->szPname, "Linux WAVIN Driver");
1168 lpCaps->dwFormats = 0x00000000;
1169 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
1170 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
1172 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1173 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
1174 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
1175 if (bytespersmpl > 1) {
1176 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
1177 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
1181 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1182 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
1183 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
1184 if (bytespersmpl > 1) {
1185 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
1186 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
1190 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1191 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
1192 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
1193 if (bytespersmpl > 1) {
1194 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
1195 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
1199 dprintf_mciwave(stddeb,
1200 "widGetDevCaps // dwFormats = %08lX\n", lpCaps->dwFormats);
1201 return MMSYSERR_NOERROR;
1205 /**************************************************************************
1206 * widOpen [internal]
1208 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1215 LPWAVEFORMAT lpFormat;
1216 dprintf_mciwave(stddeb, "widOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1217 if (lpDesc == NULL) {
1218 dprintf_mciwave(stddeb,"Linux 'widOpen' // Invalid Parameter !\n");
1219 return MMSYSERR_INVALPARAM;
1221 if (wDevID >= MAX_WAVINDRV) {
1222 dprintf_mciwave(stddeb,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
1223 return MMSYSERR_ALLOCATED;
1225 WInDev[wDevID].unixdev = 0;
1226 audio = open (SOUND_DEV, O_RDONLY, 0);
1228 dprintf_mciwave(stddeb,"Linux 'widOpen' // can't open !\n");
1229 return MMSYSERR_NOTENABLED;
1231 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
1232 if (abuf_size < 4096 || abuf_size > 65536) {
1233 if (abuf_size == -1)
1234 dprintf_mciwave(stddeb,"Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
1236 dprintf_mciwave(stddeb,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
1237 return MMSYSERR_NOTENABLED;
1239 WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1240 switch(WInDev[wDevID].wFlags) {
1242 dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_NULL !\n");
1245 dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_WINDOW !\n");
1248 dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_TASK !\n");
1251 dprintf_mciwave(stddeb, "Linux 'widOpen' // CALLBACK_FUNCTION !\n");
1254 WInDev[wDevID].lpQueueHdr = NULL;
1255 WInDev[wDevID].unixdev = audio;
1256 WInDev[wDevID].bufsize = abuf_size;
1257 WInDev[wDevID].dwTotalRecorded = 0;
1258 memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1259 lpFormat = lpDesc->lpFormat;
1260 if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1261 dprintf_mciwave(stddeb,"Linux 'widOpen' // Bad format %04X !\n",
1262 lpFormat->wFormatTag);
1263 return WAVERR_BADFORMAT;
1265 memcpy(&WInDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
1266 WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
1267 if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
1268 if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
1269 if (WInDev[wDevID].Format.wBitsPerSample == 0) {
1270 WInDev[wDevID].Format.wBitsPerSample = 8 *
1271 (WInDev[wDevID].Format.wf.nAvgBytesPerSec /
1272 WInDev[wDevID].Format.wf.nSamplesPerSec) /
1273 WInDev[wDevID].Format.wf.nChannels;
1275 samplesize = WInDev[wDevID].Format.wBitsPerSample;
1276 smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
1277 dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
1278 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
1279 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
1280 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
1281 dprintf_mciwave(stddeb,"Linux 'widOpen' // wBitsPerSample=%u !\n",
1282 WInDev[wDevID].Format.wBitsPerSample);
1283 dprintf_mciwave(stddeb,"Linux 'widOpen' // nSamplesPerSec=%lu !\n",
1284 WInDev[wDevID].Format.wf.nSamplesPerSec);
1285 dprintf_mciwave(stddeb,"Linux 'widOpen' // nChannels=%u !\n",
1286 WInDev[wDevID].Format.wf.nChannels);
1287 dprintf_mciwave(stddeb,"Linux 'widOpen' // nAvgBytesPerSec=%lu\n",
1288 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1289 if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1290 dprintf_mciwave(stddeb,"Linux 'widOpen' // can't notify client !\n");
1291 return MMSYSERR_INVALPARAM;
1293 return MMSYSERR_NOERROR;
1296 /**************************************************************************
1297 * widClose [internal]
1299 static DWORD widClose(WORD wDevID)
1301 dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
1302 if (WInDev[wDevID].unixdev == 0) {
1303 dprintf_mciwave(stddeb,"Linux 'widClose' // can't close !\n");
1304 return MMSYSERR_NOTENABLED;
1306 close(WInDev[wDevID].unixdev);
1307 WInDev[wDevID].unixdev = 0;
1308 WInDev[wDevID].bufsize = 0;
1309 if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1310 dprintf_mciwave(stddeb,"Linux 'widClose' // can't notify client !\n");
1311 return MMSYSERR_INVALPARAM;
1313 return MMSYSERR_NOERROR;
1316 /**************************************************************************
1317 * widAddBuffer [internal]
1319 static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1323 dprintf_mciwave(stddeb,
1324 "widAddBuffer(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1325 if (WInDev[wDevID].unixdev == 0) {
1326 dprintf_mciwave(stddeb,"Linux 'widAddBuffer' // can't do it !\n");
1327 return MMSYSERR_NOTENABLED;
1329 if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
1330 dprintf_mciwave(stddeb, "Linux 'widAddBuffer' // never been prepared !\n");
1331 return WAVERR_UNPREPARED;
1333 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
1334 dprintf_mciwave(stddeb, "Linux 'widAddBuffer' // header already in use !\n");
1335 return WAVERR_STILLPLAYING;
1337 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1338 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1339 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1340 lpWaveHdr->dwBytesRecorded = 0;
1341 if (WInDev[wDevID].lpQueueHdr == NULL) {
1342 /* begin the queue with a first header ... */
1343 WInDev[wDevID].lpQueueHdr = lpWaveHdr;
1344 WInDev[wDevID].dwTotalRecorded = 0;
1347 /* added to the queue, except if it's the one just prepared ... */
1348 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1349 while (lpWIHdr->lpNext != NULL) {
1350 lpWIHdr = lpWIHdr->lpNext;
1353 lpWIHdr->lpNext = lpWaveHdr;
1356 dprintf_mciwave(stddeb,
1357 "widAddBuffer // buffer added ! (now %u in queue)\n", count);
1358 return MMSYSERR_NOERROR;
1361 /**************************************************************************
1362 * widPrepare [internal]
1364 static DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1366 dprintf_mciwave(stddeb,
1367 "widPrepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1368 if (WInDev[wDevID].unixdev == 0) {
1369 dprintf_mciwave(stddeb,"Linux 'widPrepare' // can't prepare !\n");
1370 return MMSYSERR_NOTENABLED;
1372 if (WInDev[wDevID].lpQueueHdr != NULL) {
1373 dprintf_mciwave(stddeb,"Linux 'widPrepare' // already prepare !\n");
1374 return WAVERR_BADFORMAT;
1376 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1377 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1378 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1379 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1380 lpWaveHdr->dwBytesRecorded = 0;
1381 dprintf_mciwave(stddeb,"Linux 'widPrepare' // header prepared !\n");
1382 return MMSYSERR_NOERROR;
1385 /**************************************************************************
1386 * widUnprepare [internal]
1388 static DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1390 dprintf_mciwave(stddeb,
1391 "widUnprepare(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1392 if (WInDev[wDevID].unixdev == 0) {
1393 dprintf_mciwave(stddeb,"Linux 'widUnprepare' // can't unprepare !\n");
1394 return MMSYSERR_NOTENABLED;
1396 lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1397 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1398 lpWaveHdr->dwFlags |= WHDR_DONE;
1399 WInDev[wDevID].lpQueueHdr = NULL;
1400 dprintf_mciwave(stddeb,
1401 "Linux 'widUnprepare' // all headers unprepared !\n");
1402 return MMSYSERR_NOERROR;
1405 /**************************************************************************
1406 * widStart [internal]
1408 static DWORD widStart(WORD wDevID)
1412 dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
1413 if (WInDev[wDevID].unixdev == 0) {
1414 dprintf_mciwave(stddeb, "Linux 'widStart' // can't start recording !\n");
1415 return MMSYSERR_NOTENABLED;
1417 if (WInDev[wDevID].lpQueueHdr == NULL ||
1418 WInDev[wDevID].lpQueueHdr->lpData == NULL) {
1419 dprintf_mciwave(stddeb,"Linux 'widStart' // never been prepared !\n");
1420 return WAVERR_UNPREPARED;
1422 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1423 while(lpWIHdr != NULL) {
1424 lpWIHdr->dwBufferLength &= 0xFFFF;
1425 dprintf_mciwave(stddeb,
1426 "widStart // recording buf#%u=%p size=%lu \n",
1427 count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
1429 read (WInDev[wDevID].unixdev,
1430 PTR_SEG_TO_LIN(lpWIHdr->lpData),
1431 lpWIHdr->dwBufferLength);
1432 lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
1433 WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
1434 lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
1435 lpWIHdr->dwFlags |= WHDR_DONE;
1436 if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) !=
1438 dprintf_mciwave(stddeb, "Linux 'widStart' // can't notify client !\n");
1439 return MMSYSERR_INVALPARAM;
1441 lpWIHdr = lpWIHdr->lpNext;
1444 dprintf_mciwave(stddeb,"widStart // end of recording !\n");
1446 return MMSYSERR_NOERROR;
1449 /**************************************************************************
1450 * widStop [internal]
1452 static DWORD widStop(WORD wDevID)
1454 dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
1455 if (WInDev[wDevID].unixdev == 0) {
1456 dprintf_mciwave(stddeb,"Linux 'widStop' // can't stop !\n");
1457 return MMSYSERR_NOTENABLED;
1459 return MMSYSERR_NOERROR;
1462 /**************************************************************************
1463 * widReset [internal]
1465 static DWORD widReset(WORD wDevID)
1467 dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
1468 if (WInDev[wDevID].unixdev == 0) {
1469 dprintf_mciwave(stddeb,"Linux 'widReset' // can't reset !\n");
1470 return MMSYSERR_NOTENABLED;
1472 return MMSYSERR_NOERROR;
1475 /**************************************************************************
1476 * widGetPosition [internal]
1478 static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1482 dprintf_mciwave(stddeb,
1483 "widGetPosition(%u, %p, %lu);\n", wDevID, lpTime, uSize);
1484 if (WInDev[wDevID].unixdev == 0) {
1485 dprintf_mciwave(stddeb,"Linux 'widGetPosition' // can't get pos !\n");
1486 return MMSYSERR_NOTENABLED;
1488 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1489 dprintf_mciwave(stddeb,"widGetPosition // wType=%04X !\n",
1491 dprintf_mciwave(stddeb,"widGetPosition // wBitsPerSample=%u\n",
1492 WInDev[wDevID].Format.wBitsPerSample);
1493 dprintf_mciwave(stddeb,"widGetPosition // nSamplesPerSec=%lu\n",
1494 WInDev[wDevID].Format.wf.nSamplesPerSec);
1495 dprintf_mciwave(stddeb,"widGetPosition // nChannels=%u\n",
1496 WInDev[wDevID].Format.wf.nChannels);
1497 dprintf_mciwave(stddeb,"widGetPosition // nAvgBytesPerSec=%lu\n",
1498 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1500 switch(lpTime->wType) {
1502 lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
1503 dprintf_mciwave(stddeb,
1504 "widGetPosition // TIME_BYTES=%lu\n", lpTime->u.cb);
1507 lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
1508 WInDev[wDevID].Format.wBitsPerSample;
1509 dprintf_mciwave(stddeb,
1510 "widGetPosition // TIME_SAMPLES=%lu\n",
1514 time = WInDev[wDevID].dwTotalRecorded /
1515 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1516 lpTime->u.smpte.hour = time / 108000;
1517 time -= lpTime->u.smpte.hour * 108000;
1518 lpTime->u.smpte.min = time / 1800;
1519 time -= lpTime->u.smpte.min * 1800;
1520 lpTime->u.smpte.sec = time / 30;
1521 time -= lpTime->u.smpte.sec * 30;
1522 lpTime->u.smpte.frame = time;
1523 lpTime->u.smpte.fps = 30;
1524 dprintf_mciwave(stddeb,"widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1525 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1526 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1529 dprintf_mciwave(stddeb,"widGetPosition() format not supported ! use TIME_MS !\n");
1530 lpTime->wType = TIME_MS;
1532 lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
1533 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1534 dprintf_mciwave(stddeb,
1535 "widGetPosition // TIME_MS=%lu\n", lpTime->u.ms);
1538 return MMSYSERR_NOERROR;
1543 /**************************************************************************
1544 * widMessage [sample driver]
1546 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1547 DWORD dwParam1, DWORD dwParam2)
1549 dprintf_mciwave(stddeb,"widMessage(%u, %04X, %08lX, %08lX, %08lX);\n",
1550 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1554 return widOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1556 return widClose(wDevID);
1557 case WIDM_ADDBUFFER:
1558 return widAddBuffer(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1560 return widPrepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1561 case WIDM_UNPREPARE:
1562 return widUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1563 case WIDM_GETDEVCAPS:
1564 return widGetDevCaps(wDevID, (LPWAVEINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1565 case WIDM_GETNUMDEVS:
1568 return widGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
1570 return widReset(wDevID);
1572 return widStart(wDevID);
1574 return widStop(wDevID);
1576 dprintf_mciwave(stddeb,"widMessage // unknown message !\n");
1578 return MMSYSERR_NOTSUPPORTED;
1580 return MMSYSERR_NOTENABLED;
1585 /**************************************************************************
1586 * AUDIO_DriverProc [sample driver]
1588 LONG WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
1589 DWORD dwParam1, DWORD dwParam2)
1592 dprintf_mciwave(stddeb,"WAVE_DriverProc(%08lX, %04X, %04X, %08lX, %08lX)\n",
1593 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1607 case DRV_QUERYCONFIGURE:
1610 MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !",
1611 "MMLinux Driver", MB_OK);
1614 return DRVCNF_RESTART;
1616 return DRVCNF_RESTART;
1617 case MCI_OPEN_DRIVER:
1619 return WAVE_mciOpen(dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
1620 case MCI_CLOSE_DRIVER:
1622 return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1624 return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
1626 return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
1628 return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1630 return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
1632 return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1634 return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
1636 return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1637 case MCI_GETDEVCAPS:
1638 return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
1640 return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
1642 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1645 return MMSYSERR_NOTENABLED;
1650 #endif /* #ifdef BUILTIN_MMSYSTEM */