Release 941017
[wine/gsoc-2012-control.git] / misc / audio.c
blob1aad3cd845b1181fb09494ad855296b78813e77e
1 /*
2 * Sample Wine Driver for Linux
4 * Copyright 1994 Martin Ayotte
5 */
6 static char Copyright[] = "Copyright Martin Ayotte, 1994";
8 #ifndef WINELIB
9 #define BUILTIN_MMSYSTEM
10 #endif
12 #ifdef BUILTIN_MMSYSTEM
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <sys/ioctl.h>
19 #include "win.h"
20 #include "user.h"
21 #include "driver.h"
22 #include "mmsystem.h"
24 #ifdef linux
25 #include <linux/soundcard.h>
26 #endif
28 #include "stddebug.h"
29 /* #define DEBUG_MCIWAVE /* */
30 /* #undef DEBUG_MCIWAVE /* */
31 #include "debug.h"
33 #ifdef linux
34 #define SOUND_DEV "/dev/dsp"
36 #ifdef SOUND_VERSION
37 #define IOCTL(a,b,c) ioctl(a,b,&c)
38 #else
39 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
40 #endif
42 #define MAX_WAVOUTDRV 2
43 #define MAX_WAVINDRV 2
44 #define MAX_MCIWAVDRV 2
46 typedef struct {
47 int unixdev;
48 int state;
49 DWORD bufsize;
50 WAVEOPENDESC waveDesc;
51 WORD wFlags;
52 PCMWAVEFORMAT Format;
53 LPWAVEHDR lpQueueHdr;
54 DWORD dwTotalPlayed;
55 } LINUX_WAVEOUT;
57 typedef struct {
58 int unixdev;
59 int state;
60 DWORD bufsize; /* Linux '/dev/dsp' give us that size */
61 WAVEOPENDESC waveDesc;
62 WORD wFlags;
63 PCMWAVEFORMAT Format;
64 LPWAVEHDR lpQueueHdr;
65 DWORD dwTotalRecorded;
66 } LINUX_WAVEIN;
68 typedef struct {
69 int nUseCount; /* Incremented for each shared open */
70 BOOL fShareable; /* TRUE if first open was shareable */
71 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
72 HANDLE hCallback; /* Callback handle for pending notification */
73 HMMIO hFile; /* mmio file handle open as Element */
74 MCI_WAVE_OPEN_PARMS openParms;
75 PCMWAVEFORMAT WaveFormat;
76 WAVEHDR WaveHdr;
77 } LINUX_MCIWAVE;
79 static LINUX_WAVEOUT WOutDev[MAX_WAVOUTDRV];
80 static LINUX_WAVEIN WInDev[MAX_WAVOUTDRV];
81 static LINUX_MCIWAVE MCIWavDev[MAX_MCIWAVDRV];
82 #endif
84 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
85 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
86 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
87 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
88 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
89 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
90 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
91 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms);
92 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms);
93 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
94 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms);
96 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize);
97 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags);
98 DWORD wodClose(WORD wDevID);
99 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
100 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
101 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
104 /**************************************************************************
105 * WAVE_NotifyClient [internal]
107 DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg,
108 DWORD dwParam1, DWORD dwParam2)
110 #ifdef linux
111 if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
112 WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags,
113 WInDev[wDevID].waveDesc.hWave, wMsg,
114 WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
115 fprintf(stderr,"WAVE_NotifyClient // can't notify client !\n");
116 return MMSYSERR_NOERROR;
118 #else
119 return MMSYSERR_NOTENABLED;
120 #endif
124 /**************************************************************************
125 * AUDIO_DriverProc [sample driver]
127 LRESULT WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
128 DWORD dwParam1, DWORD dwParam2)
130 #ifdef linux
131 switch(wMsg) {
132 case DRV_LOAD:
133 return (LRESULT)1L;
134 case DRV_FREE:
135 return (LRESULT)1L;
136 case DRV_OPEN:
137 return (LRESULT)1L;
138 case DRV_CLOSE:
139 return (LRESULT)1L;
140 case DRV_ENABLE:
141 return (LRESULT)1L;
142 case DRV_DISABLE:
143 return (LRESULT)1L;
144 case DRV_QUERYCONFIGURE:
145 return (LRESULT)1L;
146 case DRV_CONFIGURE:
147 MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !",
148 "MMLinux Driver", MB_OK);
149 return (LRESULT)1L;
150 case DRV_INSTALL:
151 return (LRESULT)DRVCNF_RESTART;
152 case DRV_REMOVE:
153 return (LRESULT)DRVCNF_RESTART;
154 case MCI_OPEN_DRIVER:
155 case MCI_OPEN:
156 return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)dwParam2);
157 case MCI_CLOSE_DRIVER:
158 case MCI_CLOSE:
159 return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
160 case MCI_PLAY:
161 return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
162 case MCI_RECORD:
163 return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
164 case MCI_STOP:
165 return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
166 case MCI_SET:
167 return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
168 case MCI_PAUSE:
169 return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
170 case MCI_RESUME:
171 return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
172 case MCI_STATUS:
173 return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
174 case MCI_GETDEVCAPS:
175 return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
176 case MCI_INFO:
177 return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
178 default:
179 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
181 #else
182 return MMSYSERR_NOTENABLED;
183 #endif
186 /**************************************************************************
187 * WAVE_mciOpen */
188 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
190 #ifdef linux
191 int hFile;
192 UINT wDevID;
193 OFSTRUCT OFstruct;
194 LPPCMWAVEFORMAT lpWaveFormat;
195 WAVEOPENDESC WaveDesc;
196 DWORD dwRet;
197 char str[128];
198 LPSTR ptr;
199 dprintf_mciwave(stddeb,"WAVE_mciOpen(%08X, %08X)\n", dwFlags, lpParms);
200 if (lpParms == NULL) return MCIERR_INTERNAL;
201 wDevID = lpParms->wDeviceID;
202 if (MCIWavDev[wDevID].nUseCount > 0) {
203 /* The driver already open on this channel */
204 /* If the driver was opened shareable before and this open specifies */
205 /* shareable then increment the use count */
206 if (MCIWavDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
207 ++MCIWavDev[wDevID].nUseCount;
208 else
209 return MCIERR_MUST_USE_SHAREABLE;
211 else {
212 MCIWavDev[wDevID].nUseCount = 1;
213 MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
215 if (dwFlags & MCI_OPEN_ELEMENT) {
216 dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
217 lpParms->lpstrElementName);
218 /* printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
219 if (strlen(lpParms->lpstrElementName) > 0) {
220 strcpy(str, lpParms->lpstrElementName);
221 AnsiUpper(str);
222 MCIWavDev[wDevID].hFile = mmioOpen(str, NULL,
223 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
224 if (MCIWavDev[wDevID].hFile == 0) {
225 fprintf(stderr,"WAVE_mciOpen // can't find file='%s' !\n", str);
226 return MCIERR_FILE_NOT_FOUND;
229 else
230 MCIWavDev[wDevID].hFile = 0;
232 dprintf_mciwave(stddeb,"WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
233 memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
234 MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
235 lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
236 WaveDesc.hWave = 0;
237 WaveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
238 lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
239 lpWaveFormat->wBitsPerSample = 8;
240 lpWaveFormat->wf.nChannels = 1;
241 lpWaveFormat->wf.nSamplesPerSec = 11025;
242 lpWaveFormat->wf.nAvgBytesPerSec = 11025;
243 lpWaveFormat->wf.nBlockAlign = 1;
244 if (MCIWavDev[wDevID].hFile != 0) {
245 MMCKINFO mmckInfo;
246 MMCKINFO ckMainRIFF;
247 if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
248 return MCIERR_INTERNAL;
250 dprintf_mciwave(stddeb,
251 "WAVE_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
252 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
253 ckMainRIFF.cksize);
254 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
255 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) {
256 return MCIERR_INTERNAL;
258 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
259 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
260 return MCIERR_INTERNAL;
262 dprintf_mciwave(stddeb,
263 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
264 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
265 mmckInfo.cksize);
266 if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
267 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) {
268 return MCIERR_INTERNAL;
270 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
271 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
272 return MCIERR_INTERNAL;
274 dprintf_mciwave(stddeb,
275 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
276 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
277 mmckInfo.cksize);
278 dprintf_mciwave(stddeb,
279 "WAVE_mciOpen // nChannels=%d nSamplesPerSec=%d\n",
280 lpWaveFormat->wf.nChannels, lpWaveFormat->wf.nSamplesPerSec);
281 lpWaveFormat->wBitsPerSample = 0;
283 lpWaveFormat->wf.nAvgBytesPerSec =
284 lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
285 dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
286 dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
287 return 0;
288 #else
289 return MMSYSERR_NOTENABLED;
290 #endif
293 /**************************************************************************
294 * WAVE_mciClose [internal]
296 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
298 #ifdef linux
299 DWORD dwRet;
300 dprintf_mciwave(stddeb,
301 "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;
313 return 0;
314 #else
315 return 0;
316 #endif
320 /**************************************************************************
321 * WAVE_mciPlay [internal]
323 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
325 #ifdef linux
326 int count;
327 int start, end;
328 LPWAVEHDR lpWaveHdr;
329 DWORD dwRet;
330 dprintf_mciwave(stddeb,
331 "WAVE_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
332 if (MCIWavDev[wDevID].hFile == 0) {
333 fprintf(stderr,"WAVE_mciPlay // can't find file='%s' !\n",
334 MCIWavDev[wDevID].openParms.lpstrElementName);
335 return MCIERR_FILE_NOT_FOUND;
337 start = 1; end = 99999;
338 if (dwFlags & MCI_FROM) {
339 start = lpParms->dwFrom;
340 dprintf_mciwave(stddeb,
341 "WAVE_mciPlay // MCI_FROM=%d \n", start);
343 if (dwFlags & MCI_TO) {
344 end = lpParms->dwTo;
345 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_TO=%d \n", end);
348 if (dwFlags & MCI_NOTIFY) {
349 dprintf_mciwave(stddeb,
350 "WAVE_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
351 switch(fork()) {
352 case -1:
353 fprintf(stderr,
354 "WAVE_mciPlay // Can't 'fork' process !\n");
355 break;
356 case 0:
357 break;
358 default:
359 dprintf_mciwave(stddeb,"WAVE_mciPlay // process started ! return to caller...\n");
360 return 0;
364 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
365 lpWaveHdr->lpData = (LPSTR) malloc(64000);
366 lpWaveHdr->dwBufferLength = 32000;
367 lpWaveHdr->dwUser = 0L;
368 lpWaveHdr->dwFlags = 0L;
369 lpWaveHdr->dwLoops = 0L;
370 dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
371 /* printf("WAVE_mciPlay // after WODM_PREPARE \n"); */
372 while(TRUE) {
373 count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength);
374 if (count < 1) break;
375 lpWaveHdr->dwBytesRecorded = count;
376 dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%08X dwBytesRecorded=%u\n",
377 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) {
386 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
387 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
388 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
390 return 0;
391 #else
392 return MMSYSERR_NOTENABLED;
393 #endif
397 /**************************************************************************
398 * WAVE_mciRecord [internal]
400 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
402 #ifdef linux
403 int count;
404 int start, end;
405 LPWAVEHDR lpWaveHdr;
406 DWORD dwRet;
407 dprintf_mciwave(stddeb,
408 "WAVE_mciRecord(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
409 if (MCIWavDev[wDevID].hFile == 0) {
410 fprintf(stderr,"WAVE_mciRecord // can't find file='%s' !\n",
411 MCIWavDev[wDevID].openParms.lpstrElementName);
412 return MCIERR_FILE_NOT_FOUND;
414 start = 1; end = 99999;
415 if (dwFlags & MCI_FROM) {
416 start = lpParms->dwFrom;
417 dprintf_mciwave(stddeb,
418 "WAVE_mciRecord // MCI_FROM=%d \n", start);
420 if (dwFlags & MCI_TO) {
421 end = lpParms->dwTo;
422 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_TO=%d \n", end);
424 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
425 lpWaveHdr->lpData = (LPSTR) malloc(64000);
426 lpWaveHdr->dwBufferLength = 32000;
427 lpWaveHdr->dwUser = 0L;
428 lpWaveHdr->dwFlags = 0L;
429 lpWaveHdr->dwLoops = 0L;
430 dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
431 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
432 while(TRUE) {
433 lpWaveHdr->dwBytesRecorded = 0;
434 dwRet = widMessage(0, WIDM_START, 0, 0L, 0L);
435 dprintf_mciwave(stddeb,
436 "WAVE_mciRecord // after WIDM_START lpWaveHdr=%08X dwBytesRecorded=%u\n",
437 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
438 if (lpWaveHdr->dwBytesRecorded == 0) break;
440 dprintf_mciwave(stddeb,"WAVE_mciRecord // before WIDM_UNPREPARE \n");
441 dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
442 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
443 if (lpWaveHdr->lpData != NULL) {
444 free(lpWaveHdr->lpData);
445 lpWaveHdr->lpData = NULL;
447 if (dwFlags & MCI_NOTIFY) {
448 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
449 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
450 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
452 return 0;
453 #else
454 return MMSYSERR_NOTENABLED;
455 #endif
459 /**************************************************************************
460 * WAVE_mciStop [internal]
462 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
464 #ifdef linux
465 dprintf_mciwave(stddeb,
466 "WAVE_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
467 if (lpParms == NULL) return MCIERR_INTERNAL;
468 return 0;
469 #else
470 return MCIERR_INTERNAL;
471 #endif
475 /**************************************************************************
476 * WAVE_mciPause [internal]
478 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
480 #ifdef linux
481 dprintf_mciwave(stddeb,
482 "WAVE_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
483 if (lpParms == NULL) return MCIERR_INTERNAL;
484 return 0;
485 #else
486 return MCIERR_INTERNAL;
487 #endif
491 /**************************************************************************
492 * WAVE_mciResume [internal]
494 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
496 #ifdef linux
497 dprintf_mciwave(stddeb,
498 "WAVE_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
499 if (lpParms == NULL) return MCIERR_INTERNAL;
500 return 0;
501 #else
502 return MCIERR_INTERNAL;
503 #endif
507 /**************************************************************************
508 * WAVE_mciSet [internal]
510 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
512 #ifdef linux
513 dprintf_mciwave(stddeb,
514 "WAVE_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
515 if (lpParms == NULL) return MCIERR_INTERNAL;
516 dprintf_mciwave(stddeb,
517 "WAVE_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
518 dprintf_mciwave(stddeb,
519 "WAVE_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
520 if (dwFlags & MCI_SET_TIME_FORMAT) {
521 switch (lpParms->dwTimeFormat) {
522 case MCI_FORMAT_MILLISECONDS:
523 dprintf_mciwave(stddeb,
524 "WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
525 break;
526 case MCI_FORMAT_BYTES:
527 dprintf_mciwave(stddeb,
528 "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
529 break;
530 case MCI_FORMAT_SAMPLES:
531 dprintf_mciwave(stddeb,
532 "WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
533 break;
534 default:
535 fprintf(stderr,
536 "WAVE_mciSet // bad time format !\n");
537 return MCIERR_BAD_TIME_FORMAT;
540 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
541 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
542 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
543 if (dwFlags & MCI_SET_AUDIO)
544 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO !\n");
545 if (dwFlags && MCI_SET_ON) {
546 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_ON !\n");
547 if (dwFlags && MCI_SET_AUDIO_LEFT)
548 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
549 if (dwFlags && MCI_SET_AUDIO_RIGHT)
550 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
552 if (dwFlags & MCI_SET_OFF)
553 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_OFF !\n");
554 if (dwFlags & MCI_WAVE_INPUT)
555 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_INPUT !\n");
556 if (dwFlags & MCI_WAVE_OUTPUT)
557 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
558 if (dwFlags & MCI_WAVE_SET_ANYINPUT)
559 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
560 if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)
561 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
562 if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC)
563 dprintf_mciwave(stddeb,
564 "WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
565 if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE)
566 dprintf_mciwave(stddeb,
567 "WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
568 if (dwFlags & MCI_WAVE_SET_BLOCKALIGN)
569 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
570 if (dwFlags & MCI_WAVE_SET_CHANNELS)
571 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
572 if (dwFlags & MCI_WAVE_SET_FORMATTAG)
573 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
574 if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC)
575 dprintf_mciwave(stddeb,
576 "WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
577 return 0;
578 #else
579 return MCIERR_INTERNAL;
580 #endif
584 /**************************************************************************
585 * WAVE_mciStatus [internal]
587 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
589 #ifdef linux
590 dprintf_mciwave(stddeb,
591 "WAVE_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
592 if (lpParms == NULL) return MCIERR_INTERNAL;
593 if (dwFlags & MCI_STATUS_ITEM) {
594 switch(lpParms->dwItem) {
595 case MCI_STATUS_CURRENT_TRACK:
596 lpParms->dwReturn = 1;
597 break;
598 case MCI_STATUS_LENGTH:
599 lpParms->dwReturn = 5555;
600 if (dwFlags & MCI_TRACK) {
601 lpParms->dwTrack = 1;
602 lpParms->dwReturn = 2222;
604 break;
605 case MCI_STATUS_MODE:
606 lpParms->dwReturn = MCI_MODE_STOP;
607 break;
608 case MCI_STATUS_MEDIA_PRESENT:
609 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
610 lpParms->dwReturn = TRUE;
611 break;
612 case MCI_STATUS_NUMBER_OF_TRACKS:
613 lpParms->dwReturn = 1;
614 break;
615 case MCI_STATUS_POSITION:
616 lpParms->dwReturn = 3333;
617 if (dwFlags & MCI_STATUS_START) {
618 lpParms->dwItem = 1;
620 if (dwFlags & MCI_TRACK) {
621 lpParms->dwTrack = 1;
622 lpParms->dwReturn = 777;
624 break;
625 case MCI_STATUS_READY:
626 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_READY !\n");
627 lpParms->dwReturn = TRUE;
628 break;
629 case MCI_STATUS_TIME_FORMAT:
630 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
631 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
632 break;
633 case MCI_WAVE_INPUT:
634 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_INPUT !\n");
635 lpParms->dwReturn = 0;
636 break;
637 case MCI_WAVE_OUTPUT:
638 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
639 lpParms->dwReturn = 0;
640 break;
641 case MCI_WAVE_STATUS_AVGBYTESPERSEC:
642 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
643 lpParms->dwReturn = 22050;
644 break;
645 case MCI_WAVE_STATUS_BITSPERSAMPLE:
646 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
647 lpParms->dwReturn = 8;
648 break;
649 case MCI_WAVE_STATUS_BLOCKALIGN:
650 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
651 lpParms->dwReturn = 1;
652 break;
653 case MCI_WAVE_STATUS_CHANNELS:
654 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
655 lpParms->dwReturn = 1;
656 break;
657 case MCI_WAVE_STATUS_FORMATTAG:
658 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
659 lpParms->dwReturn = WAVE_FORMAT_PCM;
660 break;
661 case MCI_WAVE_STATUS_LEVEL:
662 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
663 lpParms->dwReturn = 0xAAAA5555;
664 break;
665 case MCI_WAVE_STATUS_SAMPLESPERSEC:
666 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
667 lpParms->dwReturn = 22050;
668 break;
669 default:
670 fprintf(stderr,"WAVE_mciStatus // unknown command %04X !\n", lpParms->dwItem);
671 return MCIERR_UNRECOGNIZED_COMMAND;
674 if (dwFlags & MCI_NOTIFY) {
675 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
676 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
677 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
679 return 0;
680 #else
681 return MCIERR_INTERNAL;
682 #endif
685 /**************************************************************************
686 * WAVE_mciGetDevCaps [internal]
688 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
689 LPMCI_GETDEVCAPS_PARMS lpParms)
691 #ifdef linux
692 dprintf_mciwave(stddeb,
693 "WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
694 if (lpParms == NULL) return MCIERR_INTERNAL;
695 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
696 switch(lpParms->dwItem) {
697 case MCI_GETDEVCAPS_CAN_RECORD:
698 lpParms->dwReturn = TRUE;
699 break;
700 case MCI_GETDEVCAPS_HAS_AUDIO:
701 lpParms->dwReturn = TRUE;
702 break;
703 case MCI_GETDEVCAPS_HAS_VIDEO:
704 lpParms->dwReturn = FALSE;
705 break;
706 case MCI_GETDEVCAPS_DEVICE_TYPE:
707 lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
708 break;
709 case MCI_GETDEVCAPS_USES_FILES:
710 lpParms->dwReturn = TRUE;
711 break;
712 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
713 lpParms->dwReturn = TRUE;
714 break;
715 case MCI_GETDEVCAPS_CAN_EJECT:
716 lpParms->dwReturn = FALSE;
717 break;
718 case MCI_GETDEVCAPS_CAN_PLAY:
719 lpParms->dwReturn = TRUE;
720 break;
721 case MCI_GETDEVCAPS_CAN_SAVE:
722 lpParms->dwReturn = FALSE;
723 break;
724 case MCI_WAVE_GETDEVCAPS_INPUTS:
725 lpParms->dwReturn = 1;
726 break;
727 case MCI_WAVE_GETDEVCAPS_OUTPUTS:
728 lpParms->dwReturn = 1;
729 break;
730 default:
731 return MCIERR_UNRECOGNIZED_COMMAND;
734 return 0;
735 #else
736 return MCIERR_INTERNAL;
737 #endif
740 /**************************************************************************
741 * WAVE_mciInfo [internal]
743 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
745 #ifdef linux
746 dprintf_mciwave(stddeb,
747 "WAVE_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
748 if (lpParms == NULL) return MCIERR_INTERNAL;
749 lpParms->lpstrReturn = NULL;
750 switch(dwFlags) {
751 case MCI_INFO_PRODUCT:
752 lpParms->lpstrReturn = "Linux Sound System 0.5";
753 break;
754 case MCI_INFO_FILE:
755 lpParms->lpstrReturn = "FileName";
756 break;
757 case MCI_WAVE_INPUT:
758 lpParms->lpstrReturn = "Linux Sound System 0.5";
759 break;
760 case MCI_WAVE_OUTPUT:
761 lpParms->lpstrReturn = "Linux Sound System 0.5";
762 break;
763 default:
764 return MCIERR_UNRECOGNIZED_COMMAND;
766 if (lpParms->lpstrReturn != NULL)
767 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
768 else
769 lpParms->dwRetSize = 0;
770 return 0;
771 #else
772 return MCIERR_INTERNAL;
773 #endif
777 /*-----------------------------------------------------------------------*/
780 /**************************************************************************
781 * wodGetDevCaps [internal]
783 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
785 #ifdef linux
786 int audio;
787 int smplrate;
788 int samplesize = 16;
789 int dsp_stereo = 1;
790 int bytespersmpl;
791 dprintf_mciwave(stddeb,
792 "wodGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
793 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
794 audio = open (SOUND_DEV, O_WRONLY, 0);
795 if (audio == -1) return MMSYSERR_NOTENABLED;
796 lpCaps->wMid = 0xFF; /* Manufac ID */
797 lpCaps->wPid = 0x01; /* Product ID */
798 strcpy(lpCaps->szPname, "Linux WAV Driver");
799 lpCaps->dwFormats = 0;
800 lpCaps->dwSupport = 0;
801 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
802 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
803 smplrate = 44100;
804 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
805 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
806 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
807 if (bytespersmpl > 1) {
808 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
809 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
812 smplrate = 22050;
813 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
814 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
815 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
816 if (bytespersmpl > 1) {
817 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
818 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
821 smplrate = 11025;
822 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
823 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
824 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
825 if (bytespersmpl > 1) {
826 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
827 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
830 close(audio);
831 dprintf_mciwave(stddeb,
832 "wodGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
833 return MMSYSERR_NOERROR;
834 #else
835 return MMSYSERR_NOTENABLED;
836 #endif
840 /**************************************************************************
841 * wodOpen [internal]
843 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
845 #ifdef linux
846 int audio;
847 int abuf_size;
848 int smplrate;
849 int samplesize;
850 int dsp_stereo;
851 dprintf_mciwave(stddeb,
852 "wodOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
853 if (lpDesc == NULL) {
854 fprintf(stderr,"Linux 'wodOpen' // Invalid Parameter !\n");
855 return MMSYSERR_INVALPARAM;
857 if (wDevID >= MAX_WAVOUTDRV) {
858 fprintf(stderr,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
859 return MMSYSERR_ALLOCATED;
861 WOutDev[wDevID].unixdev = 0;
862 audio = open (SOUND_DEV, O_WRONLY, 0);
863 if (audio == -1) {
864 fprintf(stderr,"Linux 'wodOpen' // can't open !\n");
865 return MMSYSERR_NOTENABLED;
867 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
868 if (abuf_size < 4096 || abuf_size > 65536) {
869 if (abuf_size == -1)
870 fprintf(stderr,"Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
871 else
872 fprintf(stderr,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
873 return MMSYSERR_NOTENABLED;
875 WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
876 switch(WOutDev[wDevID].wFlags) {
877 case DCB_NULL:
878 fprintf(stderr,"Linux 'wodOpen' // CALLBACK_NULL !\n");
879 break;
880 case DCB_WINDOW:
881 dprintf_mciwave(stddeb,
882 "Linux 'wodOpen' // CALLBACK_WINDOW !\n");
883 break;
884 case DCB_TASK:
885 dprintf_mciwave(stddeb,
886 "Linux 'wodOpen' // CALLBACK_TASK !\n");
887 break;
888 case DCB_FUNCTION:
889 dprintf_mciwave(stddeb,
890 "Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
891 break;
893 WOutDev[wDevID].lpQueueHdr = NULL;
894 WOutDev[wDevID].unixdev = audio;
895 WOutDev[wDevID].dwTotalPlayed = 0;
896 WOutDev[wDevID].bufsize = abuf_size;
897 memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
898 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
899 fprintf(stderr,"Linux 'wodOpen' // Bad format %04X !\n",
900 lpDesc->lpFormat->wFormatTag);
901 return WAVERR_BADFORMAT;
903 memcpy(&WOutDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
904 if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
905 if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
906 if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
907 WOutDev[wDevID].Format.wBitsPerSample = 8 *
908 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
909 WOutDev[wDevID].Format.wf.nSamplesPerSec) /
910 WOutDev[wDevID].Format.wf.nChannels;
912 samplesize = WOutDev[wDevID].Format.wBitsPerSample;
913 smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
914 dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
915 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
916 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
917 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
918 dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
919 WOutDev[wDevID].Format.wBitsPerSample);
920 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nSamplesPerSec=%u !\n",
921 WOutDev[wDevID].Format.wf.nSamplesPerSec);
922 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nChannels=%u !\n",
923 WOutDev[wDevID].Format.wf.nChannels);
924 if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
925 fprintf(stderr,"Linux 'wodOpen' // can't notify client !\n");
926 return MMSYSERR_INVALPARAM;
928 return MMSYSERR_NOERROR;
929 #else
930 return MMSYSERR_NOTENABLED;
931 #endif
934 /**************************************************************************
935 * wodClose [internal]
937 DWORD wodClose(WORD wDevID)
939 #ifdef linux
940 dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
941 if (WOutDev[wDevID].unixdev == 0) {
942 fprintf(stderr,"Linux 'wodClose' // can't close !\n");
943 return MMSYSERR_NOTENABLED;
945 close(WOutDev[wDevID].unixdev);
946 WOutDev[wDevID].unixdev = 0;
947 WOutDev[wDevID].bufsize = 0;
948 if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
949 fprintf(stderr,"Linux 'wodClose' // can't notify client !\n");
950 return MMSYSERR_INVALPARAM;
952 return MMSYSERR_NOERROR;
953 #else
954 return MMSYSERR_NOTENABLED;
955 #endif
958 /**************************************************************************
959 * wodWrite [internal]
961 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
963 #ifdef linux
964 dprintf_mciwave(stddeb,"wodWrite(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
965 if (WOutDev[wDevID].unixdev == 0) {
966 fprintf(stderr,"Linux 'wodWrite' // can't play !\n");
967 return MMSYSERR_NOTENABLED;
969 if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
970 if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
971 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
972 lpWaveHdr->dwFlags &= ~WHDR_DONE;
973 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
974 dprintf_mciwave(stddeb,
975 "wodWrite() // dwBytesRecorded %u !\n", lpWaveHdr->dwBytesRecorded);
976 if (write (WOutDev[wDevID].unixdev, lpWaveHdr->lpData,
977 lpWaveHdr->dwBytesRecorded) != lpWaveHdr->dwBytesRecorded) {
978 return MMSYSERR_NOTENABLED;
980 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
981 lpWaveHdr->dwFlags |= WHDR_DONE;
982 if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
983 fprintf(stderr,"Linux 'wodWrite' // can't notify client !\n");
984 return MMSYSERR_INVALPARAM;
986 return MMSYSERR_NOERROR;
987 #else
988 return MMSYSERR_NOTENABLED;
989 #endif
992 /**************************************************************************
993 * wodPrepare [internal]
995 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
997 #ifdef linux
998 dprintf_mciwave(stddeb,
999 "wodPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1000 if (WOutDev[wDevID].unixdev == 0) {
1001 fprintf(stderr,"Linux 'wodPrepare' // can't prepare !\n");
1002 return MMSYSERR_NOTENABLED;
1004 if (WOutDev[wDevID].lpQueueHdr != NULL) {
1005 fprintf(stderr,"Linux 'wodPrepare' // already prepare !\n");
1006 return MMSYSERR_NOTENABLED;
1008 WOutDev[wDevID].dwTotalPlayed = 0;
1009 WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
1010 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1011 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1012 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1013 return MMSYSERR_NOERROR;
1014 #else
1015 return MMSYSERR_NOTENABLED;
1016 #endif
1019 /**************************************************************************
1020 * wodUnprepare [internal]
1022 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1024 #ifdef linux
1025 dprintf_mciwave(stddeb,
1026 "wodUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1027 if (WOutDev[wDevID].unixdev == 0) {
1028 fprintf(stderr,"Linux 'wodUnprepare' // can't unprepare !\n");
1029 return MMSYSERR_NOTENABLED;
1031 return MMSYSERR_NOERROR;
1032 #else
1033 return MMSYSERR_NOTENABLED;
1034 #endif
1037 /**************************************************************************
1038 * wodRestart [internal]
1040 DWORD wodRestart(WORD wDevID)
1042 #ifdef linux
1043 dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
1044 if (WOutDev[wDevID].unixdev == 0) {
1045 fprintf(stderr,"Linux 'wodRestart' // can't restart !\n");
1046 return MMSYSERR_NOTENABLED;
1048 return MMSYSERR_NOERROR;
1049 #else
1050 return MMSYSERR_NOTENABLED;
1051 #endif
1054 /**************************************************************************
1055 * wodReset [internal]
1057 DWORD wodReset(WORD wDevID)
1059 #ifdef linux
1060 dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
1061 if (WOutDev[wDevID].unixdev == 0) {
1062 fprintf(stderr,"Linux 'wodReset' // can't reset !\n");
1063 return MMSYSERR_NOTENABLED;
1065 return MMSYSERR_NOERROR;
1066 #else
1067 return MMSYSERR_NOTENABLED;
1068 #endif
1072 /**************************************************************************
1073 * wodGetPosition [internal]
1075 DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1077 #ifdef linux
1078 int time;
1079 dprintf_mciwave(stddeb,"wodGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1080 if (WOutDev[wDevID].unixdev == 0) {
1081 fprintf(stderr,"Linux 'wodGetPosition' // can't get pos !\n");
1082 return MMSYSERR_NOTENABLED;
1084 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1085 TryAGAIN:
1086 switch(lpTime->wType) {
1087 case TIME_BYTES:
1088 lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
1089 dprintf_mciwave(stddeb,"wodGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1090 break;
1091 case TIME_SAMPLES:
1092 lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
1093 WOutDev[wDevID].Format.wBitsPerSample;
1094 dprintf_mciwave(stddeb,"wodGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
1095 break;
1096 case TIME_MS:
1097 lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
1098 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1099 dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1100 break;
1101 case TIME_SMPTE:
1102 time = WOutDev[wDevID].dwTotalPlayed /
1103 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1104 lpTime->u.smpte.hour = time / 108000;
1105 time -= lpTime->u.smpte.hour * 108000;
1106 lpTime->u.smpte.min = time / 1800;
1107 time -= lpTime->u.smpte.min * 1800;
1108 lpTime->u.smpte.sec = time / 30;
1109 time -= lpTime->u.smpte.sec * 30;
1110 lpTime->u.smpte.frame = time;
1111 lpTime->u.smpte.fps = 30;
1112 dprintf_mciwave(stddeb,
1113 "wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1114 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1115 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1116 break;
1117 default:
1118 fprintf(stderr,"wodGetPosition() format not supported ! use TIME_MS !\n");
1119 lpTime->wType = TIME_MS;
1120 goto TryAGAIN;
1122 return MMSYSERR_NOERROR;
1123 #else
1124 return MMSYSERR_NOTENABLED;
1125 #endif
1128 /**************************************************************************
1129 * wodSetVolume [internal]
1131 DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1133 #ifdef linux
1134 int mixer;
1135 int volume = 50;
1136 dprintf_mciwave(stddeb,"wodSetVolume(%u, %08X);\n", wDevID, dwParam);
1137 if (WOutDev[wDevID].unixdev == 0) {
1138 fprintf(stderr,"Linux 'wodSetVolume' // can't set volume !\n");
1139 return MMSYSERR_NOTENABLED;
1141 if ((mixer = open("/dev/mixer", O_RDWR)) < 0) {
1142 fprintf(stderr,
1143 "Linux 'wodSetVolume' // mixer device not available !\n");
1144 return MMSYSERR_NOTENABLED;
1146 if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
1147 fprintf(stderr,"Linux 'wodSetVolume' // unable set mixer !\n");
1148 return MMSYSERR_NOTENABLED;
1150 close(mixer);
1151 return MMSYSERR_NOERROR;
1152 #else
1153 return MMSYSERR_NOTENABLED;
1154 #endif
1158 /**************************************************************************
1159 * wodMessage [sample driver]
1161 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1162 DWORD dwParam1, DWORD dwParam2)
1164 dprintf_mciwave(stddeb,"wodMessage(%u, %04X, %08X, %08X, %08X);\n",
1165 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1166 switch(wMsg) {
1167 case WODM_OPEN:
1168 return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1169 case WODM_CLOSE:
1170 return wodClose(wDevID);
1171 case WODM_WRITE:
1172 return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1173 case WODM_PAUSE:
1174 return 0L;
1175 case WODM_GETPOS:
1176 return wodGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1177 case WODM_BREAKLOOP:
1178 return 0L;
1179 case WODM_PREPARE:
1180 return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1181 case WODM_UNPREPARE:
1182 return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1183 case WODM_GETDEVCAPS:
1184 return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)dwParam1, dwParam2);
1185 case WODM_GETNUMDEVS:
1186 return 1L;
1187 case WODM_GETPITCH:
1188 return 0L;
1189 case WODM_SETPITCH:
1190 return 0L;
1191 case WODM_GETPLAYBACKRATE:
1192 return 0L;
1193 case WODM_SETPLAYBACKRATE:
1194 return 0L;
1195 case WODM_GETVOLUME:
1196 return 0L;
1197 case WODM_SETVOLUME:
1198 return wodSetVolume(wDevID, dwParam1);
1199 case WODM_RESTART:
1200 return wodRestart(wDevID);
1201 case WODM_RESET:
1202 return wodReset(wDevID);
1204 return MMSYSERR_NOTSUPPORTED;
1208 /*-----------------------------------------------------------------------*/
1210 /**************************************************************************
1211 * widGetDevCaps [internal]
1213 DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
1215 #ifdef linux
1216 int audio;
1217 int smplrate;
1218 int samplesize = 16;
1219 int dsp_stereo = 1;
1220 int bytespersmpl;
1221 dprintf_mciwave(stddeb,
1222 "widGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
1223 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1224 audio = open (SOUND_DEV, O_RDONLY, 0);
1225 if (audio == -1) return MMSYSERR_NOTENABLED;
1226 lpCaps->wMid = 0xFF; /* Manufac ID */
1227 lpCaps->wPid = 0x01; /* Product ID */
1228 strcpy(lpCaps->szPname, "Linux WAV Driver");
1229 lpCaps->dwFormats = 0;
1230 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
1231 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
1232 smplrate = 44100;
1233 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1234 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
1235 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
1236 if (bytespersmpl > 1) {
1237 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
1238 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
1241 smplrate = 22050;
1242 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1243 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
1244 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
1245 if (bytespersmpl > 1) {
1246 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
1247 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
1250 smplrate = 11025;
1251 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1252 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
1253 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
1254 if (bytespersmpl > 1) {
1255 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
1256 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
1259 close(audio);
1260 dprintf_mciwave(stddeb,
1261 "widGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
1262 return MMSYSERR_NOERROR;
1263 #else
1264 return MMSYSERR_NOTENABLED;
1265 #endif
1269 /**************************************************************************
1270 * widOpen [internal]
1272 DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1274 #ifdef linux
1275 int audio;
1276 int abuf_size;
1277 int smplrate;
1278 int samplesize;
1279 int dsp_stereo;
1280 dprintf_mciwave(stddeb,
1281 "widOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
1282 if (lpDesc == NULL) {
1283 fprintf(stderr,"Linux 'widOpen' // Invalid Parameter !\n");
1284 return MMSYSERR_INVALPARAM;
1286 if (wDevID >= MAX_WAVINDRV) {
1287 fprintf(stderr,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
1288 return MMSYSERR_ALLOCATED;
1290 WInDev[wDevID].unixdev = 0;
1291 audio = open (SOUND_DEV, O_RDONLY, 0);
1292 if (audio == -1) {
1293 fprintf(stderr,"Linux 'widOpen' // can't open !\n");
1294 return MMSYSERR_NOTENABLED;
1296 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
1297 if (abuf_size < 4096 || abuf_size > 65536) {
1298 if (abuf_size == -1)
1299 fprintf(stderr,"Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
1300 else
1301 fprintf(stderr,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
1302 return MMSYSERR_NOTENABLED;
1304 WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1305 switch(WInDev[wDevID].wFlags) {
1306 case DCB_NULL:
1307 dprintf_mciwave(stddeb,
1308 "Linux 'widOpen' // CALLBACK_NULL !\n");
1309 break;
1310 case DCB_WINDOW:
1311 dprintf_mciwave(stddeb,
1312 "Linux 'widOpen' // CALLBACK_WINDOW !\n");
1313 break;
1314 case DCB_TASK:
1315 dprintf_mciwave(stddeb,
1316 "Linux 'widOpen' // CALLBACK_TASK !\n");
1317 break;
1318 case DCB_FUNCTION:
1319 dprintf_mciwave(stddeb,
1320 "Linux 'widOpen' // CALLBACK_FUNCTION !\n");
1321 break;
1323 WInDev[wDevID].lpQueueHdr = NULL;
1324 WInDev[wDevID].unixdev = audio;
1325 WInDev[wDevID].bufsize = abuf_size;
1326 WInDev[wDevID].dwTotalRecorded = 0;
1327 memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1328 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1329 fprintf(stderr,"Linux 'widOpen' // Bad format %04X !\n",
1330 lpDesc->lpFormat->wFormatTag);
1331 return WAVERR_BADFORMAT;
1333 memcpy(&WInDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
1334 WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
1335 if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
1336 if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
1337 if (WInDev[wDevID].Format.wBitsPerSample == 0) {
1338 WInDev[wDevID].Format.wBitsPerSample = 8 *
1339 (WInDev[wDevID].Format.wf.nAvgBytesPerSec /
1340 WInDev[wDevID].Format.wf.nSamplesPerSec) /
1341 WInDev[wDevID].Format.wf.nChannels;
1343 samplesize = WInDev[wDevID].Format.wBitsPerSample;
1344 smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
1345 dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
1346 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
1347 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
1348 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
1349 dprintf_mciwave(stddeb,"Linux 'widOpen' // wBitsPerSample=%u !\n",
1350 WInDev[wDevID].Format.wBitsPerSample);
1351 dprintf_mciwave(stddeb,"Linux 'widOpen' // nSamplesPerSec=%u !\n",
1352 WInDev[wDevID].Format.wf.nSamplesPerSec);
1353 dprintf_mciwave(stddeb,"Linux 'widOpen' // nChannels=%u !\n",
1354 WInDev[wDevID].Format.wf.nChannels);
1355 dprintf_mciwave(stddeb,"Linux 'widOpen' // nAvgBytesPerSec=%u\n",
1356 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1357 if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1358 fprintf(stderr,"Linux 'widOpen' // can't notify client !\n");
1359 return MMSYSERR_INVALPARAM;
1361 return MMSYSERR_NOERROR;
1362 #else
1363 return MMSYSERR_NOTENABLED;
1364 #endif
1367 /**************************************************************************
1368 * widClose [internal]
1370 DWORD widClose(WORD wDevID)
1372 #ifdef linux
1373 dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
1374 if (WInDev[wDevID].unixdev == 0) {
1375 fprintf(stderr,"Linux 'widClose' // can't close !\n");
1376 return MMSYSERR_NOTENABLED;
1378 close(WInDev[wDevID].unixdev);
1379 WInDev[wDevID].unixdev = 0;
1380 WInDev[wDevID].bufsize = 0;
1381 if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1382 fprintf(stderr,"Linux 'widClose' // can't notify client !\n");
1383 return MMSYSERR_INVALPARAM;
1385 return MMSYSERR_NOERROR;
1386 #else
1387 return MMSYSERR_NOTENABLED;
1388 #endif
1391 /**************************************************************************
1392 * widAddBuffer [internal]
1394 DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1396 #ifdef linux
1397 int count = 1;
1398 LPWAVEHDR lpWIHdr;
1399 dprintf_mciwave(stddeb,
1400 "widAddBuffer(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1401 if (WInDev[wDevID].unixdev == 0) {
1402 fprintf(stderr,"Linux 'widAddBuffer' // can't do it !\n");
1403 return MMSYSERR_NOTENABLED;
1405 if (WInDev[wDevID].lpQueueHdr == NULL ||
1406 !(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
1407 fprintf(stderr,
1408 "Linux 'widAddBuffer' // never been prepared !\n");
1409 return WAVERR_UNPREPARED;
1411 if ((lpWaveHdr->dwFlags & WHDR_INQUEUE) &&
1412 (WInDev[wDevID].lpQueueHdr != lpWaveHdr)) {
1413 /* except if it's the one just prepared ... */
1414 fprintf(stderr,
1415 "Linux 'widAddBuffer' // header already in use !\n");
1416 return WAVERR_STILLPLAYING;
1418 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1419 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1420 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1421 lpWaveHdr->dwBytesRecorded = 0;
1422 /* added to the queue, except if it's the one just prepared ... */
1423 if (WInDev[wDevID].lpQueueHdr != lpWaveHdr) {
1424 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1425 while (lpWIHdr->lpNext != NULL) {
1426 lpWIHdr = lpWIHdr->lpNext;
1427 count++;
1429 lpWIHdr->lpNext = lpWaveHdr;
1430 count++;
1432 dprintf_mciwave(stddeb,
1433 "widAddBuffer // buffer added ! (now %u in queue)\n", count);
1434 return MMSYSERR_NOERROR;
1435 #else
1436 return MMSYSERR_NOTENABLED;
1437 #endif
1440 /**************************************************************************
1441 * widPrepare [internal]
1443 DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1445 #ifdef linux
1446 dprintf_mciwave(stddeb,
1447 "widPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1448 if (WInDev[wDevID].unixdev == 0) {
1449 fprintf(stderr,"Linux 'widPrepare' // can't prepare !\n");
1450 return MMSYSERR_NOTENABLED;
1452 if (WInDev[wDevID].lpQueueHdr != NULL) {
1453 fprintf(stderr,"Linux 'widPrepare' // already prepare !\n");
1454 return WAVERR_BADFORMAT;
1456 WInDev[wDevID].dwTotalRecorded = 0;
1457 WInDev[wDevID].lpQueueHdr = lpWaveHdr;
1458 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1459 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1460 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1461 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1462 lpWaveHdr->dwBytesRecorded = 0;
1463 dprintf_mciwave(stddeb,"Linux 'widPrepare' // header prepared !\n");
1464 return MMSYSERR_NOERROR;
1465 #else
1466 return MMSYSERR_NOTENABLED;
1467 #endif
1470 /**************************************************************************
1471 * widUnprepare [internal]
1473 DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1475 #ifdef linux
1476 dprintf_mciwave(stddeb,
1477 "widUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1478 if (WInDev[wDevID].unixdev == 0) {
1479 fprintf(stderr,"Linux 'widUnprepare' // can't unprepare !\n");
1480 return MMSYSERR_NOTENABLED;
1482 lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1483 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1484 lpWaveHdr->dwFlags |= WHDR_DONE;
1485 WInDev[wDevID].lpQueueHdr = NULL;
1486 dprintf_mciwave(stddeb,
1487 "Linux 'widUnprepare' // all headers unprepared !\n");
1488 return MMSYSERR_NOERROR;
1489 #else
1490 return MMSYSERR_NOTENABLED;
1491 #endif
1494 /**************************************************************************
1495 * widStart [internal]
1497 DWORD widStart(WORD wDevID)
1499 #ifdef linux
1500 int count = 1;
1501 LPWAVEHDR lpWIHdr;
1502 dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
1503 if (WInDev[wDevID].unixdev == 0) {
1504 fprintf(stderr,
1505 "Linux 'widStart' // can't start recording !\n");
1506 return MMSYSERR_NOTENABLED;
1508 if (WInDev[wDevID].lpQueueHdr == NULL ||
1509 WInDev[wDevID].lpQueueHdr->lpData == NULL) {
1510 fprintf(stderr,"Linux 'widStart' // never been prepared !\n");
1511 return WAVERR_UNPREPARED;
1513 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1514 while(lpWIHdr != NULL) {
1515 lpWIHdr->dwBufferLength &= 0xFFFF;
1516 dprintf_mciwave(stddeb,
1517 "widStart // recording buf#%u=%08X size=%u \n",
1518 count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
1519 fflush(stddeb);
1520 read (WInDev[wDevID].unixdev, lpWIHdr->lpData,
1521 lpWIHdr->dwBufferLength);
1522 lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
1523 WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
1524 lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
1525 lpWIHdr->dwFlags |= WHDR_DONE;
1526 if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) !=
1527 MMSYSERR_NOERROR) {
1528 fprintf(stderr,
1529 "Linux 'widStart' // can't notify client !\n");
1530 return MMSYSERR_INVALPARAM;
1532 lpWIHdr = lpWIHdr->lpNext;
1533 count++;
1535 dprintf_mciwave(stddeb,"widStart // end of recording !\n");
1536 fflush(stdout);
1537 return MMSYSERR_NOERROR;
1538 #else
1539 return MMSYSERR_NOTENABLED;
1540 #endif
1543 /**************************************************************************
1544 * widStop [internal]
1546 DWORD widStop(WORD wDevID)
1548 #ifdef linux
1549 dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
1550 if (WInDev[wDevID].unixdev == 0) {
1551 fprintf(stderr,"Linux 'widStop' // can't stop !\n");
1552 return MMSYSERR_NOTENABLED;
1554 return MMSYSERR_NOERROR;
1555 #else
1556 return MMSYSERR_NOTENABLED;
1557 #endif
1560 /**************************************************************************
1561 * widReset [internal]
1563 DWORD widReset(WORD wDevID)
1565 #ifdef linux
1566 dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
1567 if (WInDev[wDevID].unixdev == 0) {
1568 fprintf(stderr,"Linux 'widReset' // can't reset !\n");
1569 return MMSYSERR_NOTENABLED;
1571 return MMSYSERR_NOERROR;
1572 #else
1573 return MMSYSERR_NOTENABLED;
1574 #endif
1577 /**************************************************************************
1578 * widGetPosition [internal]
1580 DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1582 #ifdef linux
1583 int time;
1584 dprintf_mciwave(stddeb,
1585 "widGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1586 if (WInDev[wDevID].unixdev == 0) {
1587 fprintf(stderr,"Linux 'widGetPosition' // can't get pos !\n");
1588 return MMSYSERR_NOTENABLED;
1590 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1591 TryAGAIN:
1592 dprintf_mciwave(stddeb,"widGetPosition // wType=%04X !\n",
1593 lpTime->wType);
1594 dprintf_mciwave(stddeb,"widGetPosition // wBitsPerSample=%u\n",
1595 WInDev[wDevID].Format.wBitsPerSample);
1596 dprintf_mciwave(stddeb,"widGetPosition // nSamplesPerSec=%u\n",
1597 WInDev[wDevID].Format.wf.nSamplesPerSec);
1598 dprintf_mciwave(stddeb,"widGetPosition // nChannels=%u\n",
1599 WInDev[wDevID].Format.wf.nChannels);
1600 dprintf_mciwave(stddeb,"widGetPosition // nAvgBytesPerSec=%u\n",
1601 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1602 fflush(stddeb);
1603 switch(lpTime->wType) {
1604 case TIME_BYTES:
1605 lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
1606 dprintf_mciwave(stddeb,
1607 "widGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1608 break;
1609 case TIME_SAMPLES:
1610 lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
1611 WInDev[wDevID].Format.wBitsPerSample;
1612 dprintf_mciwave(stddeb,
1613 "widGetPosition // TIME_SAMPLES=%u\n",
1614 lpTime->u.sample);
1615 break;
1616 case TIME_MS:
1617 lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
1618 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1619 dprintf_mciwave(stddeb,
1620 "widGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1621 break;
1622 case TIME_SMPTE:
1623 time = WInDev[wDevID].dwTotalRecorded /
1624 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1625 lpTime->u.smpte.hour = time / 108000;
1626 time -= lpTime->u.smpte.hour * 108000;
1627 lpTime->u.smpte.min = time / 1800;
1628 time -= lpTime->u.smpte.min * 1800;
1629 lpTime->u.smpte.sec = time / 30;
1630 time -= lpTime->u.smpte.sec * 30;
1631 lpTime->u.smpte.frame = time;
1632 lpTime->u.smpte.fps = 30;
1633 dprintf_mciwave(stddeb,"widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1634 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1635 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1636 break;
1637 default:
1638 fprintf(stderr,"widGetPosition() format not supported ! use TIME_MS !\n");
1639 lpTime->wType = TIME_MS;
1640 goto TryAGAIN;
1642 return MMSYSERR_NOERROR;
1643 #else
1644 return MMSYSERR_NOTENABLED;
1645 #endif
1648 /**************************************************************************
1649 * widMessage [sample driver]
1651 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1652 DWORD dwParam1, DWORD dwParam2)
1654 dprintf_mciwave(stddeb,"widMessage(%u, %04X, %08X, %08X, %08X);\n",
1655 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1656 switch(wMsg) {
1657 case WIDM_OPEN:
1658 return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1659 case WIDM_CLOSE:
1660 return widClose(wDevID);
1661 case WIDM_ADDBUFFER:
1662 return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1663 case WIDM_PREPARE:
1664 return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1665 case WIDM_UNPREPARE:
1666 return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1667 case WIDM_GETDEVCAPS:
1668 return widGetDevCaps(wDevID, (LPWAVEINCAPS)dwParam1, dwParam2);
1669 case WIDM_GETNUMDEVS:
1670 return 1L;
1671 case WIDM_GETPOS:
1672 return widGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1673 case WIDM_RESET:
1674 return widReset(wDevID);
1675 case WIDM_START:
1676 return widStart(wDevID);
1677 case WIDM_STOP:
1678 return widStop(wDevID);
1680 return MMSYSERR_NOTSUPPORTED;
1684 /*-----------------------------------------------------------------------*/
1688 /**************************************************************************
1689 * midMessage [sample driver]
1691 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1692 DWORD dwParam1, DWORD dwParam2)
1694 return MMSYSERR_NOTENABLED;
1697 /**************************************************************************
1698 * modMessage [sample driver]
1700 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1701 DWORD dwParam1, DWORD dwParam2)
1703 return MMSYSERR_NOTENABLED;
1706 #endif /* #ifdef BUILTIN_MMSYSTEM */