Release 941122
[wine/multimedia.git] / multimedia / audio.c
blob3f7cd4ed6e9818dc9958cf901b59b067fd4c3a3b
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 #define EMULATE_SB16
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <sys/ioctl.h>
21 #include "win.h"
22 #include "user.h"
23 #include "driver.h"
24 #include "mmsystem.h"
26 #ifdef linux
27 #include <linux/soundcard.h>
28 #endif
30 #include "stddebug.h"
31 /* #define DEBUG_MCIWAVE /* */
32 /* #undef DEBUG_MCIWAVE /* */
33 #include "debug.h"
35 #ifdef linux
36 #define SOUND_DEV "/dev/dsp"
38 #ifdef SOUND_VERSION
39 #define IOCTL(a,b,c) ioctl(a,b,&c)
40 #else
41 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
42 #endif
44 #define MAX_WAVOUTDRV 2
45 #define MAX_WAVINDRV 2
46 #define MAX_MCIWAVDRV 2
48 typedef struct {
49 int unixdev;
50 int state;
51 DWORD bufsize;
52 WAVEOPENDESC waveDesc;
53 WORD wFlags;
54 PCMWAVEFORMAT Format;
55 LPWAVEHDR lpQueueHdr;
56 DWORD dwTotalPlayed;
57 } LINUX_WAVEOUT;
59 typedef struct {
60 int unixdev;
61 int state;
62 DWORD bufsize; /* Linux '/dev/dsp' give us that size */
63 WAVEOPENDESC waveDesc;
64 WORD wFlags;
65 PCMWAVEFORMAT Format;
66 LPWAVEHDR lpQueueHdr;
67 DWORD dwTotalRecorded;
68 } LINUX_WAVEIN;
70 typedef struct {
71 int nUseCount; /* Incremented for each shared open */
72 BOOL fShareable; /* TRUE if first open was shareable */
73 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
74 HANDLE hCallback; /* Callback handle for pending notification */
75 HMMIO hFile; /* mmio file handle open as Element */
76 MCI_WAVE_OPEN_PARMS openParms;
77 PCMWAVEFORMAT WaveFormat;
78 WAVEHDR WaveHdr;
79 } LINUX_MCIWAVE;
81 static LINUX_WAVEOUT WOutDev[MAX_WAVOUTDRV];
82 static LINUX_WAVEIN WInDev[MAX_WAVOUTDRV];
83 static LINUX_MCIWAVE MCIWavDev[MAX_MCIWAVDRV];
84 #endif
86 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
87 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
88 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
89 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
90 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
91 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
92 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
93 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms);
94 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms);
95 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
96 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms);
98 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize);
99 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags);
100 DWORD wodClose(WORD wDevID);
101 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
102 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
103 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
106 /**************************************************************************
107 * WAVE_NotifyClient [internal]
109 DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg,
110 DWORD dwParam1, DWORD dwParam2)
112 #ifdef linux
113 if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
114 WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags,
115 WInDev[wDevID].waveDesc.hWave, wMsg,
116 WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
117 fprintf(stderr,"WAVE_NotifyClient // can't notify client !\n");
118 return MMSYSERR_NOERROR;
120 #else
121 return MMSYSERR_NOTENABLED;
122 #endif
126 /**************************************************************************
127 * AUDIO_DriverProc [sample driver]
129 LRESULT WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
130 DWORD dwParam1, DWORD dwParam2)
132 #ifdef linux
133 switch(wMsg) {
134 case DRV_LOAD:
135 return (LRESULT)1L;
136 case DRV_FREE:
137 return (LRESULT)1L;
138 case DRV_OPEN:
139 return (LRESULT)1L;
140 case DRV_CLOSE:
141 return (LRESULT)1L;
142 case DRV_ENABLE:
143 return (LRESULT)1L;
144 case DRV_DISABLE:
145 return (LRESULT)1L;
146 case DRV_QUERYCONFIGURE:
147 return (LRESULT)1L;
148 case DRV_CONFIGURE:
149 MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !",
150 "MMLinux Driver", MB_OK);
151 return (LRESULT)1L;
152 case DRV_INSTALL:
153 return (LRESULT)DRVCNF_RESTART;
154 case DRV_REMOVE:
155 return (LRESULT)DRVCNF_RESTART;
156 case MCI_OPEN_DRIVER:
157 case MCI_OPEN:
158 return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)dwParam2);
159 case MCI_CLOSE_DRIVER:
160 case MCI_CLOSE:
161 return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
162 case MCI_PLAY:
163 return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
164 case MCI_RECORD:
165 return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
166 case MCI_STOP:
167 return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
168 case MCI_SET:
169 return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
170 case MCI_PAUSE:
171 return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
172 case MCI_RESUME:
173 return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
174 case MCI_STATUS:
175 return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
176 case MCI_GETDEVCAPS:
177 return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
178 case MCI_INFO:
179 return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
180 default:
181 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
183 #else
184 return MMSYSERR_NOTENABLED;
185 #endif
188 /**************************************************************************
189 * WAVE_mciOpen */
190 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
192 #ifdef linux
193 int hFile;
194 UINT wDevID;
195 OFSTRUCT OFstruct;
196 LPPCMWAVEFORMAT lpWaveFormat;
197 WAVEOPENDESC WaveDesc;
198 DWORD dwRet;
199 char str[128];
200 LPSTR ptr;
201 dprintf_mciwave(stddeb,"WAVE_mciOpen(%08X, %08X)\n", dwFlags, lpParms);
202 if (lpParms == NULL) return MCIERR_INTERNAL;
203 wDevID = lpParms->wDeviceID;
204 if (MCIWavDev[wDevID].nUseCount > 0) {
205 /* The driver already open on this channel */
206 /* If the driver was opened shareable before and this open specifies */
207 /* shareable then increment the use count */
208 if (MCIWavDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
209 ++MCIWavDev[wDevID].nUseCount;
210 else
211 return MCIERR_MUST_USE_SHAREABLE;
213 else {
214 MCIWavDev[wDevID].nUseCount = 1;
215 MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
217 if (dwFlags & MCI_OPEN_ELEMENT) {
218 dprintf_mciwave(stddeb,"WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
219 lpParms->lpstrElementName);
220 /* printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
221 if (strlen(lpParms->lpstrElementName) > 0) {
222 strcpy(str, lpParms->lpstrElementName);
223 AnsiUpper(str);
224 MCIWavDev[wDevID].hFile = mmioOpen(str, NULL,
225 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
226 if (MCIWavDev[wDevID].hFile == 0) {
227 fprintf(stderr,"WAVE_mciOpen // can't find file='%s' !\n", str);
228 return MCIERR_FILE_NOT_FOUND;
231 else
232 MCIWavDev[wDevID].hFile = 0;
234 dprintf_mciwave(stddeb,"WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
235 memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
236 MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
237 lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
238 WaveDesc.hWave = 0;
239 WaveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
240 lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
241 lpWaveFormat->wBitsPerSample = 8;
242 lpWaveFormat->wf.nChannels = 1;
243 lpWaveFormat->wf.nSamplesPerSec = 11025;
244 lpWaveFormat->wf.nAvgBytesPerSec = 11025;
245 lpWaveFormat->wf.nBlockAlign = 1;
246 if (MCIWavDev[wDevID].hFile != 0) {
247 MMCKINFO mmckInfo;
248 MMCKINFO ckMainRIFF;
249 if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
250 return MCIERR_INTERNAL;
252 dprintf_mciwave(stddeb,
253 "WAVE_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
254 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
255 ckMainRIFF.cksize);
256 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
257 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) {
258 return MCIERR_INTERNAL;
260 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
261 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
262 return MCIERR_INTERNAL;
264 dprintf_mciwave(stddeb,
265 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
266 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
267 mmckInfo.cksize);
268 if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
269 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) {
270 return MCIERR_INTERNAL;
272 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
273 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
274 return MCIERR_INTERNAL;
276 dprintf_mciwave(stddeb,
277 "WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
278 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
279 mmckInfo.cksize);
280 dprintf_mciwave(stddeb,
281 "WAVE_mciOpen // nChannels=%d nSamplesPerSec=%d\n",
282 lpWaveFormat->wf.nChannels, lpWaveFormat->wf.nSamplesPerSec);
283 lpWaveFormat->wBitsPerSample = 0;
285 lpWaveFormat->wf.nAvgBytesPerSec =
286 lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
287 dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
288 dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
289 return 0;
290 #else
291 return MMSYSERR_NOTENABLED;
292 #endif
295 /**************************************************************************
296 * WAVE_mciClose [internal]
298 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
300 #ifdef linux
301 DWORD dwRet;
302 dprintf_mciwave(stddeb,
303 "WAVE_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
304 MCIWavDev[wDevID].nUseCount--;
305 if (MCIWavDev[wDevID].nUseCount == 0) {
306 if (MCIWavDev[wDevID].hFile != 0) {
307 mmioClose(MCIWavDev[wDevID].hFile, 0);
308 MCIWavDev[wDevID].hFile = 0;
310 dwRet = wodMessage(0, WODM_CLOSE, 0, 0L, 0L);
311 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
312 dwRet = widMessage(0, WIDM_CLOSE, 0, 0L, 0L);
313 if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
315 return 0;
316 #else
317 return 0;
318 #endif
322 /**************************************************************************
323 * WAVE_mciPlay [internal]
325 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
327 #ifdef linux
328 int count;
329 int start, end;
330 LPWAVEHDR lpWaveHdr;
331 DWORD dwRet;
332 dprintf_mciwave(stddeb,
333 "WAVE_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
334 if (MCIWavDev[wDevID].hFile == 0) {
335 fprintf(stderr,"WAVE_mciPlay // can't find file='%s' !\n",
336 MCIWavDev[wDevID].openParms.lpstrElementName);
337 return MCIERR_FILE_NOT_FOUND;
339 start = 1; end = 99999;
340 if (dwFlags & MCI_FROM) {
341 start = lpParms->dwFrom;
342 dprintf_mciwave(stddeb,
343 "WAVE_mciPlay // MCI_FROM=%d \n", start);
345 if (dwFlags & MCI_TO) {
346 end = lpParms->dwTo;
347 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_TO=%d \n", end);
349 /**/
350 if (dwFlags & MCI_NOTIFY) {
351 dprintf_mciwave(stddeb,
352 "WAVE_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
353 switch(fork()) {
354 case -1:
355 fprintf(stderr,
356 "WAVE_mciPlay // Can't 'fork' process !\n");
357 break;
358 case 0:
359 break;
360 default:
361 dprintf_mciwave(stddeb,"WAVE_mciPlay // process started ! return to caller...\n");
362 return 0;
365 /**/
366 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
367 lpWaveHdr->lpData = (LPSTR) malloc(64000);
368 lpWaveHdr->dwBufferLength = 32000;
369 lpWaveHdr->dwUser = 0L;
370 lpWaveHdr->dwFlags = 0L;
371 lpWaveHdr->dwLoops = 0L;
372 dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
373 /* printf("WAVE_mciPlay // after WODM_PREPARE \n"); */
374 while(TRUE) {
375 count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength);
376 if (count < 1) break;
377 lpWaveHdr->dwBytesRecorded = count;
378 dprintf_mciwave(stddeb,"WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%08X dwBytesRecorded=%u\n",
379 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
380 dwRet = wodMessage(0, WODM_WRITE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
382 dwRet = wodMessage(0, WODM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
383 if (lpWaveHdr->lpData != NULL) {
384 free(lpWaveHdr->lpData);
385 lpWaveHdr->lpData = NULL;
387 if (dwFlags & MCI_NOTIFY) {
388 dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
389 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
390 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
391 exit(0);
393 return 0;
394 #else
395 return MMSYSERR_NOTENABLED;
396 #endif
400 /**************************************************************************
401 * WAVE_mciRecord [internal]
403 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
405 #ifdef linux
406 int count;
407 int start, end;
408 LPWAVEHDR lpWaveHdr;
409 DWORD dwRet;
410 dprintf_mciwave(stddeb,
411 "WAVE_mciRecord(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
412 if (MCIWavDev[wDevID].hFile == 0) {
413 fprintf(stderr,"WAVE_mciRecord // can't find file='%s' !\n",
414 MCIWavDev[wDevID].openParms.lpstrElementName);
415 return MCIERR_FILE_NOT_FOUND;
417 start = 1; end = 99999;
418 if (dwFlags & MCI_FROM) {
419 start = lpParms->dwFrom;
420 dprintf_mciwave(stddeb,
421 "WAVE_mciRecord // MCI_FROM=%d \n", start);
423 if (dwFlags & MCI_TO) {
424 end = lpParms->dwTo;
425 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_TO=%d \n", end);
427 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
428 lpWaveHdr->lpData = (LPSTR) malloc(64000);
429 lpWaveHdr->dwBufferLength = 32000;
430 lpWaveHdr->dwUser = 0L;
431 lpWaveHdr->dwFlags = 0L;
432 lpWaveHdr->dwLoops = 0L;
433 dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
434 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_PREPARE \n");
435 while(TRUE) {
436 lpWaveHdr->dwBytesRecorded = 0;
437 dwRet = widMessage(0, WIDM_START, 0, 0L, 0L);
438 dprintf_mciwave(stddeb,
439 "WAVE_mciRecord // after WIDM_START lpWaveHdr=%08X dwBytesRecorded=%u\n",
440 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
441 if (lpWaveHdr->dwBytesRecorded == 0) break;
443 dprintf_mciwave(stddeb,"WAVE_mciRecord // before WIDM_UNPREPARE \n");
444 dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
445 dprintf_mciwave(stddeb,"WAVE_mciRecord // after WIDM_UNPREPARE \n");
446 if (lpWaveHdr->lpData != NULL) {
447 free(lpWaveHdr->lpData);
448 lpWaveHdr->lpData = NULL;
450 if (dwFlags & MCI_NOTIFY) {
451 dprintf_mciwave(stddeb,"WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
452 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
453 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
455 return 0;
456 #else
457 return MMSYSERR_NOTENABLED;
458 #endif
462 /**************************************************************************
463 * WAVE_mciStop [internal]
465 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
467 #ifdef linux
468 dprintf_mciwave(stddeb,
469 "WAVE_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
470 if (lpParms == NULL) return MCIERR_INTERNAL;
471 return 0;
472 #else
473 return MCIERR_INTERNAL;
474 #endif
478 /**************************************************************************
479 * WAVE_mciPause [internal]
481 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
483 #ifdef linux
484 dprintf_mciwave(stddeb,
485 "WAVE_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
486 if (lpParms == NULL) return MCIERR_INTERNAL;
487 return 0;
488 #else
489 return MCIERR_INTERNAL;
490 #endif
494 /**************************************************************************
495 * WAVE_mciResume [internal]
497 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
499 #ifdef linux
500 dprintf_mciwave(stddeb,
501 "WAVE_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
502 if (lpParms == NULL) return MCIERR_INTERNAL;
503 return 0;
504 #else
505 return MCIERR_INTERNAL;
506 #endif
510 /**************************************************************************
511 * WAVE_mciSet [internal]
513 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
515 #ifdef linux
516 dprintf_mciwave(stddeb,
517 "WAVE_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
518 if (lpParms == NULL) return MCIERR_INTERNAL;
519 dprintf_mciwave(stddeb,
520 "WAVE_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
521 dprintf_mciwave(stddeb,
522 "WAVE_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
523 if (dwFlags & MCI_SET_TIME_FORMAT) {
524 switch (lpParms->dwTimeFormat) {
525 case MCI_FORMAT_MILLISECONDS:
526 dprintf_mciwave(stddeb,
527 "WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
528 break;
529 case MCI_FORMAT_BYTES:
530 dprintf_mciwave(stddeb,
531 "WAVE_mciSet // MCI_FORMAT_BYTES !\n");
532 break;
533 case MCI_FORMAT_SAMPLES:
534 dprintf_mciwave(stddeb,
535 "WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
536 break;
537 default:
538 fprintf(stderr,
539 "WAVE_mciSet // bad time format !\n");
540 return MCIERR_BAD_TIME_FORMAT;
543 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
544 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
545 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
546 if (dwFlags & MCI_SET_AUDIO)
547 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO !\n");
548 if (dwFlags && MCI_SET_ON) {
549 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_ON !\n");
550 if (dwFlags && MCI_SET_AUDIO_LEFT)
551 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
552 if (dwFlags && MCI_SET_AUDIO_RIGHT)
553 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
555 if (dwFlags & MCI_SET_OFF)
556 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_SET_OFF !\n");
557 if (dwFlags & MCI_WAVE_INPUT)
558 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_INPUT !\n");
559 if (dwFlags & MCI_WAVE_OUTPUT)
560 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
561 if (dwFlags & MCI_WAVE_SET_ANYINPUT)
562 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
563 if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)
564 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
565 if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC)
566 dprintf_mciwave(stddeb,
567 "WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
568 if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE)
569 dprintf_mciwave(stddeb,
570 "WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
571 if (dwFlags & MCI_WAVE_SET_BLOCKALIGN)
572 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
573 if (dwFlags & MCI_WAVE_SET_CHANNELS)
574 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
575 if (dwFlags & MCI_WAVE_SET_FORMATTAG)
576 dprintf_mciwave(stddeb,"WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
577 if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC)
578 dprintf_mciwave(stddeb,
579 "WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
580 return 0;
581 #else
582 return MCIERR_INTERNAL;
583 #endif
587 /**************************************************************************
588 * WAVE_mciStatus [internal]
590 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
592 #ifdef linux
593 dprintf_mciwave(stddeb,
594 "WAVE_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
595 if (lpParms == NULL) return MCIERR_INTERNAL;
596 if (dwFlags & MCI_STATUS_ITEM) {
597 switch(lpParms->dwItem) {
598 case MCI_STATUS_CURRENT_TRACK:
599 lpParms->dwReturn = 1;
600 break;
601 case MCI_STATUS_LENGTH:
602 lpParms->dwReturn = 5555;
603 if (dwFlags & MCI_TRACK) {
604 lpParms->dwTrack = 1;
605 lpParms->dwReturn = 2222;
607 break;
608 case MCI_STATUS_MODE:
609 lpParms->dwReturn = MCI_MODE_STOP;
610 break;
611 case MCI_STATUS_MEDIA_PRESENT:
612 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
613 lpParms->dwReturn = TRUE;
614 break;
615 case MCI_STATUS_NUMBER_OF_TRACKS:
616 lpParms->dwReturn = 1;
617 break;
618 case MCI_STATUS_POSITION:
619 lpParms->dwReturn = 3333;
620 if (dwFlags & MCI_STATUS_START) {
621 lpParms->dwItem = 1;
623 if (dwFlags & MCI_TRACK) {
624 lpParms->dwTrack = 1;
625 lpParms->dwReturn = 777;
627 break;
628 case MCI_STATUS_READY:
629 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_READY !\n");
630 lpParms->dwReturn = TRUE;
631 break;
632 case MCI_STATUS_TIME_FORMAT:
633 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
634 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
635 break;
636 case MCI_WAVE_INPUT:
637 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_INPUT !\n");
638 lpParms->dwReturn = 0;
639 break;
640 case MCI_WAVE_OUTPUT:
641 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
642 lpParms->dwReturn = 0;
643 break;
644 case MCI_WAVE_STATUS_AVGBYTESPERSEC:
645 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
646 lpParms->dwReturn = 22050;
647 break;
648 case MCI_WAVE_STATUS_BITSPERSAMPLE:
649 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
650 lpParms->dwReturn = 8;
651 break;
652 case MCI_WAVE_STATUS_BLOCKALIGN:
653 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
654 lpParms->dwReturn = 1;
655 break;
656 case MCI_WAVE_STATUS_CHANNELS:
657 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
658 lpParms->dwReturn = 1;
659 break;
660 case MCI_WAVE_STATUS_FORMATTAG:
661 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
662 lpParms->dwReturn = WAVE_FORMAT_PCM;
663 break;
664 case MCI_WAVE_STATUS_LEVEL:
665 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
666 lpParms->dwReturn = 0xAAAA5555;
667 break;
668 case MCI_WAVE_STATUS_SAMPLESPERSEC:
669 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
670 lpParms->dwReturn = 22050;
671 break;
672 default:
673 fprintf(stderr,"WAVE_mciStatus // unknown command %04X !\n", lpParms->dwItem);
674 return MCIERR_UNRECOGNIZED_COMMAND;
677 if (dwFlags & MCI_NOTIFY) {
678 dprintf_mciwave(stddeb,"WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
679 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
680 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
682 return 0;
683 #else
684 return MCIERR_INTERNAL;
685 #endif
688 /**************************************************************************
689 * WAVE_mciGetDevCaps [internal]
691 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
692 LPMCI_GETDEVCAPS_PARMS lpParms)
694 #ifdef linux
695 dprintf_mciwave(stddeb,
696 "WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
697 if (lpParms == NULL) return MCIERR_INTERNAL;
698 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
699 switch(lpParms->dwItem) {
700 case MCI_GETDEVCAPS_CAN_RECORD:
701 lpParms->dwReturn = TRUE;
702 break;
703 case MCI_GETDEVCAPS_HAS_AUDIO:
704 lpParms->dwReturn = TRUE;
705 break;
706 case MCI_GETDEVCAPS_HAS_VIDEO:
707 lpParms->dwReturn = FALSE;
708 break;
709 case MCI_GETDEVCAPS_DEVICE_TYPE:
710 lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
711 break;
712 case MCI_GETDEVCAPS_USES_FILES:
713 lpParms->dwReturn = TRUE;
714 break;
715 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
716 lpParms->dwReturn = TRUE;
717 break;
718 case MCI_GETDEVCAPS_CAN_EJECT:
719 lpParms->dwReturn = FALSE;
720 break;
721 case MCI_GETDEVCAPS_CAN_PLAY:
722 lpParms->dwReturn = TRUE;
723 break;
724 case MCI_GETDEVCAPS_CAN_SAVE:
725 lpParms->dwReturn = TRUE;
726 break;
727 case MCI_WAVE_GETDEVCAPS_INPUTS:
728 lpParms->dwReturn = 1;
729 break;
730 case MCI_WAVE_GETDEVCAPS_OUTPUTS:
731 lpParms->dwReturn = 1;
732 break;
733 default:
734 return MCIERR_UNRECOGNIZED_COMMAND;
737 return 0;
738 #else
739 return MCIERR_INTERNAL;
740 #endif
743 /**************************************************************************
744 * WAVE_mciInfo [internal]
746 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
748 #ifdef linux
749 dprintf_mciwave(stddeb,
750 "WAVE_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
751 if (lpParms == NULL) return MCIERR_INTERNAL;
752 lpParms->lpstrReturn = NULL;
753 switch(dwFlags) {
754 case MCI_INFO_PRODUCT:
755 lpParms->lpstrReturn = "Linux Sound System 0.5";
756 break;
757 case MCI_INFO_FILE:
758 lpParms->lpstrReturn =
759 (LPSTR)MCIWavDev[wDevID].openParms.lpstrElementName;
760 break;
761 case MCI_WAVE_INPUT:
762 lpParms->lpstrReturn = "Linux Sound System 0.5";
763 break;
764 case MCI_WAVE_OUTPUT:
765 lpParms->lpstrReturn = "Linux Sound System 0.5";
766 break;
767 default:
768 return MCIERR_UNRECOGNIZED_COMMAND;
770 if (lpParms->lpstrReturn != NULL)
771 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
772 else
773 lpParms->dwRetSize = 0;
774 return 0;
775 #else
776 return MCIERR_INTERNAL;
777 #endif
781 /*-----------------------------------------------------------------------*/
784 /**************************************************************************
785 * wodGetDevCaps [internal]
787 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
789 #ifdef linux
790 int audio;
791 int smplrate;
792 int samplesize = 16;
793 int dsp_stereo = 1;
794 int bytespersmpl;
795 dprintf_mciwave(stddeb,
796 "wodGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
797 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
798 audio = open (SOUND_DEV, O_WRONLY, 0);
799 if (audio == -1) return MMSYSERR_NOTENABLED;
800 #ifdef EMULATE_SB16
801 lpCaps->wMid = 0x0002;
802 lpCaps->wPid = 0x0104;
803 strcpy(lpCaps->szPname, "SB16 Wave Out");
804 #else
805 lpCaps->wMid = 0x00FF; /* Manufac ID */
806 lpCaps->wPid = 0x0001; /* Product ID */
807 strcpy(lpCaps->szPname, "Linux WAVOUT Driver");
808 #endif
809 lpCaps->dwFormats = 0x00000000;
810 lpCaps->dwSupport = WAVECAPS_VOLUME;
811 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
812 if (lpCaps->wChannels > 1) lpCaps->dwSupport |= WAVECAPS_LRVOLUME;
813 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
814 smplrate = 44100;
815 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
816 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
817 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
818 if (bytespersmpl > 1) {
819 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
820 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
823 smplrate = 22050;
824 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
825 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
826 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
827 if (bytespersmpl > 1) {
828 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
829 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
832 smplrate = 11025;
833 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
834 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
835 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
836 if (bytespersmpl > 1) {
837 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
838 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
841 close(audio);
842 dprintf_mciwave(stddeb,
843 "wodGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
844 return MMSYSERR_NOERROR;
845 #else
846 return MMSYSERR_NOTENABLED;
847 #endif
851 /**************************************************************************
852 * wodOpen [internal]
854 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
856 #ifdef linux
857 int audio;
858 int abuf_size;
859 int smplrate;
860 int samplesize;
861 int dsp_stereo;
862 dprintf_mciwave(stddeb,
863 "wodOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
864 if (lpDesc == NULL) {
865 fprintf(stderr,"Linux 'wodOpen' // Invalid Parameter !\n");
866 return MMSYSERR_INVALPARAM;
868 if (wDevID >= MAX_WAVOUTDRV) {
869 fprintf(stderr,"Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
870 return MMSYSERR_ALLOCATED;
872 WOutDev[wDevID].unixdev = 0;
873 audio = open (SOUND_DEV, O_WRONLY, 0);
874 if (audio == -1) {
875 fprintf(stderr,"Linux 'wodOpen' // can't open !\n");
876 return MMSYSERR_NOTENABLED;
878 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
879 if (abuf_size < 4096 || abuf_size > 65536) {
880 if (abuf_size == -1)
881 fprintf(stderr,"Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
882 else
883 fprintf(stderr,"Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
884 return MMSYSERR_NOTENABLED;
886 WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
887 switch(WOutDev[wDevID].wFlags) {
888 case DCB_NULL:
889 fprintf(stderr,"Linux 'wodOpen' // CALLBACK_NULL !\n");
890 break;
891 case DCB_WINDOW:
892 dprintf_mciwave(stddeb,
893 "Linux 'wodOpen' // CALLBACK_WINDOW !\n");
894 break;
895 case DCB_TASK:
896 dprintf_mciwave(stddeb,
897 "Linux 'wodOpen' // CALLBACK_TASK !\n");
898 break;
899 case DCB_FUNCTION:
900 dprintf_mciwave(stddeb,
901 "Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
902 break;
904 WOutDev[wDevID].lpQueueHdr = NULL;
905 WOutDev[wDevID].unixdev = audio;
906 WOutDev[wDevID].dwTotalPlayed = 0;
907 WOutDev[wDevID].bufsize = abuf_size;
908 memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
909 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
910 fprintf(stderr,"Linux 'wodOpen' // Bad format %04X !\n",
911 lpDesc->lpFormat->wFormatTag);
912 return WAVERR_BADFORMAT;
914 memcpy(&WOutDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
915 if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
916 if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
917 if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
918 WOutDev[wDevID].Format.wBitsPerSample = 8 *
919 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
920 WOutDev[wDevID].Format.wf.nSamplesPerSec) /
921 WOutDev[wDevID].Format.wf.nChannels;
923 samplesize = WOutDev[wDevID].Format.wBitsPerSample;
924 smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
925 dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
926 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
927 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
928 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
929 dprintf_mciwave(stddeb,"Linux 'wodOpen' // wBitsPerSample=%u !\n",
930 WOutDev[wDevID].Format.wBitsPerSample);
931 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nSamplesPerSec=%u !\n",
932 WOutDev[wDevID].Format.wf.nSamplesPerSec);
933 dprintf_mciwave(stddeb,"Linux 'wodOpen' // nChannels=%u !\n",
934 WOutDev[wDevID].Format.wf.nChannels);
935 if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
936 fprintf(stderr,"Linux 'wodOpen' // can't notify client !\n");
937 return MMSYSERR_INVALPARAM;
939 return MMSYSERR_NOERROR;
940 #else
941 return MMSYSERR_NOTENABLED;
942 #endif
945 /**************************************************************************
946 * wodClose [internal]
948 DWORD wodClose(WORD wDevID)
950 #ifdef linux
951 dprintf_mciwave(stddeb,"wodClose(%u);\n", wDevID);
952 if (WOutDev[wDevID].unixdev == 0) {
953 fprintf(stderr,"Linux 'wodClose' // can't close !\n");
954 return MMSYSERR_NOTENABLED;
956 close(WOutDev[wDevID].unixdev);
957 WOutDev[wDevID].unixdev = 0;
958 WOutDev[wDevID].bufsize = 0;
959 if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
960 fprintf(stderr,"Linux 'wodClose' // can't notify client !\n");
961 return MMSYSERR_INVALPARAM;
963 return MMSYSERR_NOERROR;
964 #else
965 return MMSYSERR_NOTENABLED;
966 #endif
969 /**************************************************************************
970 * wodWrite [internal]
972 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
974 #ifdef linux
975 dprintf_mciwave(stddeb,"wodWrite(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
976 if (WOutDev[wDevID].unixdev == 0) {
977 fprintf(stderr,"Linux 'wodWrite' // can't play !\n");
978 return MMSYSERR_NOTENABLED;
980 if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
981 if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
982 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
983 lpWaveHdr->dwFlags &= ~WHDR_DONE;
984 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
985 dprintf_mciwave(stddeb,
986 "wodWrite() // dwBytesRecorded %u !\n", lpWaveHdr->dwBytesRecorded);
987 if (write (WOutDev[wDevID].unixdev, lpWaveHdr->lpData,
988 lpWaveHdr->dwBytesRecorded) != lpWaveHdr->dwBytesRecorded) {
989 return MMSYSERR_NOTENABLED;
991 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
992 lpWaveHdr->dwFlags |= WHDR_DONE;
993 if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
994 fprintf(stderr,"Linux 'wodWrite' // can't notify client !\n");
995 return MMSYSERR_INVALPARAM;
997 return MMSYSERR_NOERROR;
998 #else
999 return MMSYSERR_NOTENABLED;
1000 #endif
1003 /**************************************************************************
1004 * wodPrepare [internal]
1006 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1008 #ifdef linux
1009 dprintf_mciwave(stddeb,
1010 "wodPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1011 if (WOutDev[wDevID].unixdev == 0) {
1012 fprintf(stderr,"Linux 'wodPrepare' // can't prepare !\n");
1013 return MMSYSERR_NOTENABLED;
1015 if (WOutDev[wDevID].lpQueueHdr != NULL) {
1016 fprintf(stderr,"Linux 'wodPrepare' // already prepare !\n");
1017 return MMSYSERR_NOTENABLED;
1019 WOutDev[wDevID].dwTotalPlayed = 0;
1020 WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
1021 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1022 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1023 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1024 return MMSYSERR_NOERROR;
1025 #else
1026 return MMSYSERR_NOTENABLED;
1027 #endif
1030 /**************************************************************************
1031 * wodUnprepare [internal]
1033 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1035 #ifdef linux
1036 dprintf_mciwave(stddeb,
1037 "wodUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1038 if (WOutDev[wDevID].unixdev == 0) {
1039 fprintf(stderr,"Linux 'wodUnprepare' // can't unprepare !\n");
1040 return MMSYSERR_NOTENABLED;
1042 return MMSYSERR_NOERROR;
1043 #else
1044 return MMSYSERR_NOTENABLED;
1045 #endif
1048 /**************************************************************************
1049 * wodRestart [internal]
1051 DWORD wodRestart(WORD wDevID)
1053 #ifdef linux
1054 dprintf_mciwave(stddeb,"wodRestart(%u);\n", wDevID);
1055 if (WOutDev[wDevID].unixdev == 0) {
1056 fprintf(stderr,"Linux 'wodRestart' // can't restart !\n");
1057 return MMSYSERR_NOTENABLED;
1059 return MMSYSERR_NOERROR;
1060 #else
1061 return MMSYSERR_NOTENABLED;
1062 #endif
1065 /**************************************************************************
1066 * wodReset [internal]
1068 DWORD wodReset(WORD wDevID)
1070 #ifdef linux
1071 dprintf_mciwave(stddeb,"wodReset(%u);\n", wDevID);
1072 if (WOutDev[wDevID].unixdev == 0) {
1073 fprintf(stderr,"Linux 'wodReset' // can't reset !\n");
1074 return MMSYSERR_NOTENABLED;
1076 return MMSYSERR_NOERROR;
1077 #else
1078 return MMSYSERR_NOTENABLED;
1079 #endif
1083 /**************************************************************************
1084 * wodGetPosition [internal]
1086 DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1088 #ifdef linux
1089 int time;
1090 dprintf_mciwave(stddeb,"wodGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1091 if (WOutDev[wDevID].unixdev == 0) {
1092 fprintf(stderr,"Linux 'wodGetPosition' // can't get pos !\n");
1093 return MMSYSERR_NOTENABLED;
1095 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1096 TryAGAIN:
1097 switch(lpTime->wType) {
1098 case TIME_BYTES:
1099 lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
1100 dprintf_mciwave(stddeb,"wodGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1101 break;
1102 case TIME_SAMPLES:
1103 lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
1104 WOutDev[wDevID].Format.wBitsPerSample;
1105 dprintf_mciwave(stddeb,"wodGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
1106 break;
1107 case TIME_MS:
1108 lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
1109 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1110 dprintf_mciwave(stddeb,"wodGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1111 break;
1112 case TIME_SMPTE:
1113 time = WOutDev[wDevID].dwTotalPlayed /
1114 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1115 lpTime->u.smpte.hour = time / 108000;
1116 time -= lpTime->u.smpte.hour * 108000;
1117 lpTime->u.smpte.min = time / 1800;
1118 time -= lpTime->u.smpte.min * 1800;
1119 lpTime->u.smpte.sec = time / 30;
1120 time -= lpTime->u.smpte.sec * 30;
1121 lpTime->u.smpte.frame = time;
1122 lpTime->u.smpte.fps = 30;
1123 dprintf_mciwave(stddeb,
1124 "wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1125 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1126 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1127 break;
1128 default:
1129 fprintf(stderr,"wodGetPosition() format not supported ! use TIME_MS !\n");
1130 lpTime->wType = TIME_MS;
1131 goto TryAGAIN;
1133 return MMSYSERR_NOERROR;
1134 #else
1135 return MMSYSERR_NOTENABLED;
1136 #endif
1139 /**************************************************************************
1140 * wodGetVolume [internal]
1142 DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
1144 #ifdef linux
1145 int mixer;
1146 int volume;
1147 dprintf_mciwave(stddeb,"wodGetVolume(%u, %08X);\n", wDevID, lpdwVol);
1148 if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
1149 if (WOutDev[wDevID].unixdev == 0) {
1150 fprintf(stderr,"Linux 'wodGetVolume' // can't read volume !\n");
1151 return MMSYSERR_NOTENABLED;
1153 if ((mixer = open("/dev/mixer", O_RDONLY)) < 0) {
1154 fprintf(stderr, "Linux 'wodGetVolume' // mixer device not available !\n");
1155 return MMSYSERR_NOTENABLED;
1157 if (ioctl(mixer, SOUND_MIXER_READ_PCM, &volume) == -1) {
1158 fprintf(stderr,"Linux 'wodGetVolume' // unable read mixer !\n");
1159 return MMSYSERR_NOTENABLED;
1161 close(mixer);
1162 *lpdwVol = MAKELONG(volume, volume);
1163 return MMSYSERR_NOERROR;
1164 #else
1165 return MMSYSERR_NOTENABLED;
1166 #endif
1170 /**************************************************************************
1171 * wodSetVolume [internal]
1173 DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1175 #ifdef linux
1176 int mixer;
1177 int volume;
1178 dprintf_mciwave(stddeb,"wodSetVolume(%u, %08X);\n", wDevID, dwParam);
1179 volume = LOWORD(dwParam);
1180 if (WOutDev[wDevID].unixdev == 0) {
1181 fprintf(stderr,"Linux 'wodSetVolume' // can't set volume !\n");
1182 return MMSYSERR_NOTENABLED;
1184 if ((mixer = open("/dev/mixer", O_WRONLY)) < 0) {
1185 fprintf(stderr, "Linux 'wodSetVolume' // mixer device not available !\n");
1186 return MMSYSERR_NOTENABLED;
1188 if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
1189 fprintf(stderr,"Linux 'wodSetVolume' // unable set mixer !\n");
1190 return MMSYSERR_NOTENABLED;
1192 close(mixer);
1193 return MMSYSERR_NOERROR;
1194 #else
1195 return MMSYSERR_NOTENABLED;
1196 #endif
1200 /**************************************************************************
1201 * wodMessage [sample driver]
1203 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1204 DWORD dwParam1, DWORD dwParam2)
1206 dprintf_mciwave(stddeb,"wodMessage(%u, %04X, %08X, %08X, %08X);\n",
1207 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1208 switch(wMsg) {
1209 case WODM_OPEN:
1210 return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1211 case WODM_CLOSE:
1212 return wodClose(wDevID);
1213 case WODM_WRITE:
1214 return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1215 case WODM_PAUSE:
1216 return 0L;
1217 case WODM_GETPOS:
1218 return wodGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1219 case WODM_BREAKLOOP:
1220 return 0L;
1221 case WODM_PREPARE:
1222 return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1223 case WODM_UNPREPARE:
1224 return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1225 case WODM_GETDEVCAPS:
1226 return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)dwParam1, dwParam2);
1227 case WODM_GETNUMDEVS:
1228 return 1L;
1229 case WODM_GETPITCH:
1230 return 0L;
1231 case WODM_SETPITCH:
1232 return 0L;
1233 case WODM_GETPLAYBACKRATE:
1234 return 0L;
1235 case WODM_SETPLAYBACKRATE:
1236 return 0L;
1237 case WODM_GETVOLUME:
1238 return wodGetVolume(wDevID, (LPDWORD)dwParam1);
1239 case WODM_SETVOLUME:
1240 return wodSetVolume(wDevID, dwParam1);
1241 case WODM_RESTART:
1242 return wodRestart(wDevID);
1243 case WODM_RESET:
1244 return wodReset(wDevID);
1246 return MMSYSERR_NOTSUPPORTED;
1250 /*-----------------------------------------------------------------------*/
1252 /**************************************************************************
1253 * widGetDevCaps [internal]
1255 DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
1257 #ifdef linux
1258 int audio;
1259 int smplrate;
1260 int samplesize = 16;
1261 int dsp_stereo = 1;
1262 int bytespersmpl;
1263 dprintf_mciwave(stddeb,
1264 "widGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
1265 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1266 audio = open (SOUND_DEV, O_RDONLY, 0);
1267 if (audio == -1) return MMSYSERR_NOTENABLED;
1268 #ifdef EMULATE_SB16
1269 lpCaps->wMid = 0x0002;
1270 lpCaps->wPid = 0x0004;
1271 strcpy(lpCaps->szPname, "SB16 Wave Out");
1272 #else
1273 lpCaps->wMid = 0x00FF; /* Manufac ID */
1274 lpCaps->wPid = 0x0001; /* Product ID */
1275 strcpy(lpCaps->szPname, "Linux WAVIN Driver");
1276 #endif
1277 lpCaps->dwFormats = 0x00000000;
1278 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
1279 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
1280 smplrate = 44100;
1281 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1282 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
1283 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
1284 if (bytespersmpl > 1) {
1285 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
1286 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
1289 smplrate = 22050;
1290 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1291 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
1292 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
1293 if (bytespersmpl > 1) {
1294 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
1295 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
1298 smplrate = 11025;
1299 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1300 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
1301 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
1302 if (bytespersmpl > 1) {
1303 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
1304 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
1307 close(audio);
1308 dprintf_mciwave(stddeb,
1309 "widGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
1310 return MMSYSERR_NOERROR;
1311 #else
1312 return MMSYSERR_NOTENABLED;
1313 #endif
1317 /**************************************************************************
1318 * widOpen [internal]
1320 DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1322 #ifdef linux
1323 int audio;
1324 int abuf_size;
1325 int smplrate;
1326 int samplesize;
1327 int dsp_stereo;
1328 dprintf_mciwave(stddeb,
1329 "widOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
1330 if (lpDesc == NULL) {
1331 fprintf(stderr,"Linux 'widOpen' // Invalid Parameter !\n");
1332 return MMSYSERR_INVALPARAM;
1334 if (wDevID >= MAX_WAVINDRV) {
1335 fprintf(stderr,"Linux 'widOpen' // MAX_WAVINDRV reached !\n");
1336 return MMSYSERR_ALLOCATED;
1338 WInDev[wDevID].unixdev = 0;
1339 audio = open (SOUND_DEV, O_RDONLY, 0);
1340 if (audio == -1) {
1341 fprintf(stderr,"Linux 'widOpen' // can't open !\n");
1342 return MMSYSERR_NOTENABLED;
1344 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
1345 if (abuf_size < 4096 || abuf_size > 65536) {
1346 if (abuf_size == -1)
1347 fprintf(stderr,"Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
1348 else
1349 fprintf(stderr,"Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
1350 return MMSYSERR_NOTENABLED;
1352 WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1353 switch(WInDev[wDevID].wFlags) {
1354 case DCB_NULL:
1355 dprintf_mciwave(stddeb,
1356 "Linux 'widOpen' // CALLBACK_NULL !\n");
1357 break;
1358 case DCB_WINDOW:
1359 dprintf_mciwave(stddeb,
1360 "Linux 'widOpen' // CALLBACK_WINDOW !\n");
1361 break;
1362 case DCB_TASK:
1363 dprintf_mciwave(stddeb,
1364 "Linux 'widOpen' // CALLBACK_TASK !\n");
1365 break;
1366 case DCB_FUNCTION:
1367 dprintf_mciwave(stddeb,
1368 "Linux 'widOpen' // CALLBACK_FUNCTION !\n");
1369 break;
1371 WInDev[wDevID].lpQueueHdr = NULL;
1372 WInDev[wDevID].unixdev = audio;
1373 WInDev[wDevID].bufsize = abuf_size;
1374 WInDev[wDevID].dwTotalRecorded = 0;
1375 memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1376 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1377 fprintf(stderr,"Linux 'widOpen' // Bad format %04X !\n",
1378 lpDesc->lpFormat->wFormatTag);
1379 return WAVERR_BADFORMAT;
1381 memcpy(&WInDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
1382 WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
1383 if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
1384 if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
1385 if (WInDev[wDevID].Format.wBitsPerSample == 0) {
1386 WInDev[wDevID].Format.wBitsPerSample = 8 *
1387 (WInDev[wDevID].Format.wf.nAvgBytesPerSec /
1388 WInDev[wDevID].Format.wf.nSamplesPerSec) /
1389 WInDev[wDevID].Format.wf.nChannels;
1391 samplesize = WInDev[wDevID].Format.wBitsPerSample;
1392 smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
1393 dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
1394 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
1395 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
1396 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
1397 dprintf_mciwave(stddeb,"Linux 'widOpen' // wBitsPerSample=%u !\n",
1398 WInDev[wDevID].Format.wBitsPerSample);
1399 dprintf_mciwave(stddeb,"Linux 'widOpen' // nSamplesPerSec=%u !\n",
1400 WInDev[wDevID].Format.wf.nSamplesPerSec);
1401 dprintf_mciwave(stddeb,"Linux 'widOpen' // nChannels=%u !\n",
1402 WInDev[wDevID].Format.wf.nChannels);
1403 dprintf_mciwave(stddeb,"Linux 'widOpen' // nAvgBytesPerSec=%u\n",
1404 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1405 if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1406 fprintf(stderr,"Linux 'widOpen' // can't notify client !\n");
1407 return MMSYSERR_INVALPARAM;
1409 return MMSYSERR_NOERROR;
1410 #else
1411 return MMSYSERR_NOTENABLED;
1412 #endif
1415 /**************************************************************************
1416 * widClose [internal]
1418 DWORD widClose(WORD wDevID)
1420 #ifdef linux
1421 dprintf_mciwave(stddeb,"widClose(%u);\n", wDevID);
1422 if (WInDev[wDevID].unixdev == 0) {
1423 fprintf(stderr,"Linux 'widClose' // can't close !\n");
1424 return MMSYSERR_NOTENABLED;
1426 close(WInDev[wDevID].unixdev);
1427 WInDev[wDevID].unixdev = 0;
1428 WInDev[wDevID].bufsize = 0;
1429 if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1430 fprintf(stderr,"Linux 'widClose' // can't notify client !\n");
1431 return MMSYSERR_INVALPARAM;
1433 return MMSYSERR_NOERROR;
1434 #else
1435 return MMSYSERR_NOTENABLED;
1436 #endif
1439 /**************************************************************************
1440 * widAddBuffer [internal]
1442 DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1444 #ifdef linux
1445 int count = 1;
1446 LPWAVEHDR lpWIHdr;
1447 dprintf_mciwave(stddeb,
1448 "widAddBuffer(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1449 if (WInDev[wDevID].unixdev == 0) {
1450 fprintf(stderr,"Linux 'widAddBuffer' // can't do it !\n");
1451 return MMSYSERR_NOTENABLED;
1453 if (WInDev[wDevID].lpQueueHdr == NULL ||
1454 !(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
1455 fprintf(stderr,
1456 "Linux 'widAddBuffer' // never been prepared !\n");
1457 return WAVERR_UNPREPARED;
1459 if ((lpWaveHdr->dwFlags & WHDR_INQUEUE) &&
1460 (WInDev[wDevID].lpQueueHdr != lpWaveHdr)) {
1461 /* except if it's the one just prepared ... */
1462 fprintf(stderr,
1463 "Linux 'widAddBuffer' // header already in use !\n");
1464 return WAVERR_STILLPLAYING;
1466 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1467 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1468 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1469 lpWaveHdr->dwBytesRecorded = 0;
1470 /* added to the queue, except if it's the one just prepared ... */
1471 if (WInDev[wDevID].lpQueueHdr != lpWaveHdr) {
1472 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1473 while (lpWIHdr->lpNext != NULL) {
1474 lpWIHdr = lpWIHdr->lpNext;
1475 count++;
1477 lpWIHdr->lpNext = lpWaveHdr;
1478 count++;
1480 dprintf_mciwave(stddeb,
1481 "widAddBuffer // buffer added ! (now %u in queue)\n", count);
1482 return MMSYSERR_NOERROR;
1483 #else
1484 return MMSYSERR_NOTENABLED;
1485 #endif
1488 /**************************************************************************
1489 * widPrepare [internal]
1491 DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1493 #ifdef linux
1494 dprintf_mciwave(stddeb,
1495 "widPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1496 if (WInDev[wDevID].unixdev == 0) {
1497 fprintf(stderr,"Linux 'widPrepare' // can't prepare !\n");
1498 return MMSYSERR_NOTENABLED;
1500 if (WInDev[wDevID].lpQueueHdr != NULL) {
1501 fprintf(stderr,"Linux 'widPrepare' // already prepare !\n");
1502 return WAVERR_BADFORMAT;
1504 WInDev[wDevID].dwTotalRecorded = 0;
1505 WInDev[wDevID].lpQueueHdr = lpWaveHdr;
1506 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1507 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1508 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1509 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1510 lpWaveHdr->dwBytesRecorded = 0;
1511 dprintf_mciwave(stddeb,"Linux 'widPrepare' // header prepared !\n");
1512 return MMSYSERR_NOERROR;
1513 #else
1514 return MMSYSERR_NOTENABLED;
1515 #endif
1518 /**************************************************************************
1519 * widUnprepare [internal]
1521 DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1523 #ifdef linux
1524 dprintf_mciwave(stddeb,
1525 "widUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1526 if (WInDev[wDevID].unixdev == 0) {
1527 fprintf(stderr,"Linux 'widUnprepare' // can't unprepare !\n");
1528 return MMSYSERR_NOTENABLED;
1530 lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1531 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1532 lpWaveHdr->dwFlags |= WHDR_DONE;
1533 WInDev[wDevID].lpQueueHdr = NULL;
1534 dprintf_mciwave(stddeb,
1535 "Linux 'widUnprepare' // all headers unprepared !\n");
1536 return MMSYSERR_NOERROR;
1537 #else
1538 return MMSYSERR_NOTENABLED;
1539 #endif
1542 /**************************************************************************
1543 * widStart [internal]
1545 DWORD widStart(WORD wDevID)
1547 #ifdef linux
1548 int count = 1;
1549 LPWAVEHDR lpWIHdr;
1550 dprintf_mciwave(stddeb,"widStart(%u);\n", wDevID);
1551 if (WInDev[wDevID].unixdev == 0) {
1552 fprintf(stderr,
1553 "Linux 'widStart' // can't start recording !\n");
1554 return MMSYSERR_NOTENABLED;
1556 if (WInDev[wDevID].lpQueueHdr == NULL ||
1557 WInDev[wDevID].lpQueueHdr->lpData == NULL) {
1558 fprintf(stderr,"Linux 'widStart' // never been prepared !\n");
1559 return WAVERR_UNPREPARED;
1561 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1562 while(lpWIHdr != NULL) {
1563 lpWIHdr->dwBufferLength &= 0xFFFF;
1564 dprintf_mciwave(stddeb,
1565 "widStart // recording buf#%u=%08X size=%u \n",
1566 count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
1567 fflush(stddeb);
1568 read (WInDev[wDevID].unixdev, lpWIHdr->lpData,
1569 lpWIHdr->dwBufferLength);
1570 lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
1571 WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
1572 lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
1573 lpWIHdr->dwFlags |= WHDR_DONE;
1574 if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) !=
1575 MMSYSERR_NOERROR) {
1576 fprintf(stderr,
1577 "Linux 'widStart' // can't notify client !\n");
1578 return MMSYSERR_INVALPARAM;
1580 lpWIHdr = lpWIHdr->lpNext;
1581 count++;
1583 dprintf_mciwave(stddeb,"widStart // end of recording !\n");
1584 fflush(stdout);
1585 return MMSYSERR_NOERROR;
1586 #else
1587 return MMSYSERR_NOTENABLED;
1588 #endif
1591 /**************************************************************************
1592 * widStop [internal]
1594 DWORD widStop(WORD wDevID)
1596 #ifdef linux
1597 dprintf_mciwave(stddeb,"widStop(%u);\n", wDevID);
1598 if (WInDev[wDevID].unixdev == 0) {
1599 fprintf(stderr,"Linux 'widStop' // can't stop !\n");
1600 return MMSYSERR_NOTENABLED;
1602 return MMSYSERR_NOERROR;
1603 #else
1604 return MMSYSERR_NOTENABLED;
1605 #endif
1608 /**************************************************************************
1609 * widReset [internal]
1611 DWORD widReset(WORD wDevID)
1613 #ifdef linux
1614 dprintf_mciwave(stddeb,"widReset(%u);\n", wDevID);
1615 if (WInDev[wDevID].unixdev == 0) {
1616 fprintf(stderr,"Linux 'widReset' // can't reset !\n");
1617 return MMSYSERR_NOTENABLED;
1619 return MMSYSERR_NOERROR;
1620 #else
1621 return MMSYSERR_NOTENABLED;
1622 #endif
1625 /**************************************************************************
1626 * widGetPosition [internal]
1628 DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1630 #ifdef linux
1631 int time;
1632 dprintf_mciwave(stddeb,
1633 "widGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1634 if (WInDev[wDevID].unixdev == 0) {
1635 fprintf(stderr,"Linux 'widGetPosition' // can't get pos !\n");
1636 return MMSYSERR_NOTENABLED;
1638 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1639 TryAGAIN:
1640 dprintf_mciwave(stddeb,"widGetPosition // wType=%04X !\n",
1641 lpTime->wType);
1642 dprintf_mciwave(stddeb,"widGetPosition // wBitsPerSample=%u\n",
1643 WInDev[wDevID].Format.wBitsPerSample);
1644 dprintf_mciwave(stddeb,"widGetPosition // nSamplesPerSec=%u\n",
1645 WInDev[wDevID].Format.wf.nSamplesPerSec);
1646 dprintf_mciwave(stddeb,"widGetPosition // nChannels=%u\n",
1647 WInDev[wDevID].Format.wf.nChannels);
1648 dprintf_mciwave(stddeb,"widGetPosition // nAvgBytesPerSec=%u\n",
1649 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1650 fflush(stddeb);
1651 switch(lpTime->wType) {
1652 case TIME_BYTES:
1653 lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
1654 dprintf_mciwave(stddeb,
1655 "widGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1656 break;
1657 case TIME_SAMPLES:
1658 lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
1659 WInDev[wDevID].Format.wBitsPerSample;
1660 dprintf_mciwave(stddeb,
1661 "widGetPosition // TIME_SAMPLES=%u\n",
1662 lpTime->u.sample);
1663 break;
1664 case TIME_MS:
1665 lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
1666 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1667 dprintf_mciwave(stddeb,
1668 "widGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1669 break;
1670 case TIME_SMPTE:
1671 time = WInDev[wDevID].dwTotalRecorded /
1672 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1673 lpTime->u.smpte.hour = time / 108000;
1674 time -= lpTime->u.smpte.hour * 108000;
1675 lpTime->u.smpte.min = time / 1800;
1676 time -= lpTime->u.smpte.min * 1800;
1677 lpTime->u.smpte.sec = time / 30;
1678 time -= lpTime->u.smpte.sec * 30;
1679 lpTime->u.smpte.frame = time;
1680 lpTime->u.smpte.fps = 30;
1681 dprintf_mciwave(stddeb,"widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1682 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1683 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1684 break;
1685 default:
1686 fprintf(stderr,"widGetPosition() format not supported ! use TIME_MS !\n");
1687 lpTime->wType = TIME_MS;
1688 goto TryAGAIN;
1690 return MMSYSERR_NOERROR;
1691 #else
1692 return MMSYSERR_NOTENABLED;
1693 #endif
1696 /**************************************************************************
1697 * widMessage [sample driver]
1699 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1700 DWORD dwParam1, DWORD dwParam2)
1702 dprintf_mciwave(stddeb,"widMessage(%u, %04X, %08X, %08X, %08X);\n",
1703 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1704 switch(wMsg) {
1705 case WIDM_OPEN:
1706 return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1707 case WIDM_CLOSE:
1708 return widClose(wDevID);
1709 case WIDM_ADDBUFFER:
1710 return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1711 case WIDM_PREPARE:
1712 return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1713 case WIDM_UNPREPARE:
1714 return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1715 case WIDM_GETDEVCAPS:
1716 return widGetDevCaps(wDevID, (LPWAVEINCAPS)dwParam1, dwParam2);
1717 case WIDM_GETNUMDEVS:
1718 return 1L;
1719 case WIDM_GETPOS:
1720 return widGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1721 case WIDM_RESET:
1722 return widReset(wDevID);
1723 case WIDM_START:
1724 return widStart(wDevID);
1725 case WIDM_STOP:
1726 return widStop(wDevID);
1728 return MMSYSERR_NOTSUPPORTED;
1732 #endif /* #ifdef BUILTIN_MMSYSTEM */