Release 940804
[wine/gsoc-2012-control.git] / misc / audio.c
blob2d81e3751086779b3b622d7a7e1626a69665b8a5
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 DEBUG_MCIWAVE
16 #include "stdio.h"
17 #include "win.h"
18 #include "user.h"
19 #include "driver.h"
20 #include "mmsystem.h"
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #ifdef linux
25 #include <linux/soundcard.h>
26 #endif
28 #ifdef linux
29 #define SOUND_DEV "/dev/dsp"
31 #ifdef SOUND_VERSION
32 #define IOCTL(a,b,c) ioctl(a,b,&c)
33 #else
34 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
35 #endif
37 #define MAX_WAVOUTDRV 2
38 #define MAX_WAVINDRV 2
39 #define MAX_MCIWAVDRV 2
41 typedef struct {
42 int unixdev;
43 int state;
44 DWORD bufsize;
45 WAVEOPENDESC waveDesc;
46 WORD wFlags;
47 PCMWAVEFORMAT Format;
48 LPWAVEHDR lpQueueHdr;
49 DWORD dwTotalPlayed;
50 } LINUX_WAVEOUT;
52 typedef struct {
53 int unixdev;
54 int state;
55 DWORD bufsize; /* Linux '/dev/dsp' give us that size */
56 WAVEOPENDESC waveDesc;
57 WORD wFlags;
58 PCMWAVEFORMAT Format;
59 LPWAVEHDR lpQueueHdr;
60 DWORD dwTotalRecorded;
61 } LINUX_WAVEIN;
63 typedef struct {
64 int nUseCount; /* Incremented for each shared open */
65 BOOL fShareable; /* TRUE if first open was shareable */
66 WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
67 HANDLE hCallback; /* Callback handle for pending notification */
68 HMMIO hFile; /* mmio file handle open as Element */
69 MCI_WAVE_OPEN_PARMS openParms;
70 PCMWAVEFORMAT WaveFormat;
71 WAVEHDR WaveHdr;
72 } LINUX_MCIWAVE;
74 static LINUX_WAVEOUT WOutDev[MAX_WAVOUTDRV];
75 static LINUX_WAVEIN WInDev[MAX_WAVOUTDRV];
76 static LINUX_MCIWAVE MCIWavDev[MAX_MCIWAVDRV];
77 #endif
79 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
80 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
81 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms);
82 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms);
83 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
84 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
85 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
86 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms);
87 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms);
88 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
89 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms);
91 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize);
92 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags);
93 DWORD wodClose(WORD wDevID);
94 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
95 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
96 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize);
99 /**************************************************************************
100 * WAVE_NotifyClient [internal]
102 DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg,
103 DWORD dwParam1, DWORD dwParam2)
105 #ifdef linux
106 if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
107 WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags,
108 WInDev[wDevID].waveDesc.hWave, wMsg,
109 WInDev[wDevID].waveDesc.dwInstance, dwParam1, dwParam2)) {
110 printf("WAVE_NotifyClient // can't notify client !\n");
111 return MMSYSERR_NOERROR;
113 #else
114 return MMSYSERR_NOTENABLED;
115 #endif
119 /**************************************************************************
120 * AUDIO_DriverProc [sample driver]
122 LRESULT WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
123 DWORD dwParam1, DWORD dwParam2)
125 #ifdef linux
126 switch(wMsg) {
127 case DRV_LOAD:
128 return (LRESULT)1L;
129 case DRV_FREE:
130 return (LRESULT)1L;
131 case DRV_OPEN:
132 return (LRESULT)1L;
133 case DRV_CLOSE:
134 return (LRESULT)1L;
135 case DRV_ENABLE:
136 return (LRESULT)1L;
137 case DRV_DISABLE:
138 return (LRESULT)1L;
139 case DRV_QUERYCONFIGURE:
140 return (LRESULT)1L;
141 case DRV_CONFIGURE:
142 MessageBox((HWND)NULL, "Sample MultiMedia Linux Driver !",
143 "MMLinux Driver", MB_OK);
144 return (LRESULT)1L;
145 case DRV_INSTALL:
146 return (LRESULT)DRVCNF_RESTART;
147 case DRV_REMOVE:
148 return (LRESULT)DRVCNF_RESTART;
149 case MCI_OPEN_DRIVER:
150 case MCI_OPEN:
151 return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)dwParam2);
152 case MCI_CLOSE_DRIVER:
153 case MCI_CLOSE:
154 return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
155 case MCI_PLAY:
156 return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
157 case MCI_RECORD:
158 return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
159 case MCI_STOP:
160 return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
161 case MCI_SET:
162 return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
163 case MCI_PAUSE:
164 return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
165 case MCI_RESUME:
166 return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
167 case MCI_STATUS:
168 return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
169 case MCI_GETDEVCAPS:
170 return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
171 case MCI_INFO:
172 return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
173 default:
174 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
176 #else
177 return MMSYSERR_NOTENABLED;
178 #endif
181 /**************************************************************************
182 * WAVE_mciOpen */
183 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
185 #ifdef linux
186 int hFile;
187 UINT wDevID;
188 OFSTRUCT OFstruct;
189 LPPCMWAVEFORMAT lpWaveFormat;
190 WAVEOPENDESC WaveDesc;
191 DWORD dwRet;
192 char str[128];
193 LPSTR ptr;
194 #ifdef DEBUG_MCIWAVE
195 printf("WAVE_mciOpen(%08X, %08X)\n", dwFlags, lpParms);
196 #endif
197 if (lpParms == NULL) return MCIERR_INTERNAL;
198 wDevID = lpParms->wDeviceID;
199 if (MCIWavDev[wDevID].nUseCount > 0) {
200 /* The driver already open on this channel */
201 /* If the driver was opened shareable before and this open specifies */
202 /* shareable then increment the use count */
203 if (MCIWavDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
204 ++MCIWavDev[wDevID].nUseCount;
205 else
206 return MCIERR_MUST_USE_SHAREABLE;
208 else {
209 MCIWavDev[wDevID].nUseCount = 1;
210 MCIWavDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
212 if (dwFlags & MCI_OPEN_ELEMENT) {
213 printf("WAVE_mciOpen // MCI_OPEN_ELEMENT '%s' !\n",
214 lpParms->lpstrElementName);
215 /* printf("WAVE_mciOpen // cdw='%s'\n", DOS_GetCurrentDir(DOS_GetDefaultDrive())); */
216 if (strlen(lpParms->lpstrElementName) > 0) {
217 strcpy(str, lpParms->lpstrElementName);
218 AnsiUpper(str);
219 MCIWavDev[wDevID].hFile = mmioOpen(str, NULL,
220 MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
221 if (MCIWavDev[wDevID].hFile == 0) {
222 printf("WAVE_mciOpen // can't find file='%s' !\n", str);
223 return MCIERR_FILE_NOT_FOUND;
226 else
227 MCIWavDev[wDevID].hFile = 0;
229 printf("WAVE_mciOpen // hFile=%u\n", MCIWavDev[wDevID].hFile);
230 memcpy(&MCIWavDev[wDevID].openParms, lpParms, sizeof(MCI_WAVE_OPEN_PARMS));
231 MCIWavDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
232 lpWaveFormat = &MCIWavDev[wDevID].WaveFormat;
233 WaveDesc.hWave = 0;
234 WaveDesc.lpFormat = (LPWAVEFORMAT)lpWaveFormat;
235 lpWaveFormat->wf.wFormatTag = WAVE_FORMAT_PCM;
236 lpWaveFormat->wBitsPerSample = 8;
237 lpWaveFormat->wf.nChannels = 1;
238 lpWaveFormat->wf.nSamplesPerSec = 11025;
239 lpWaveFormat->wf.nAvgBytesPerSec = 11025;
240 lpWaveFormat->wf.nBlockAlign = 1;
241 if (MCIWavDev[wDevID].hFile != 0) {
242 MMCKINFO mmckInfo;
243 MMCKINFO ckMainRIFF;
244 if (mmioDescend(MCIWavDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
245 return MCIERR_INTERNAL;
247 #ifdef DEBUG_MCIWAVE
248 printf("WAVE_mciOpen // ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
249 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
250 ckMainRIFF.cksize);
251 #endif
252 if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
253 (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) {
254 return MCIERR_INTERNAL;
256 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
257 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
258 return MCIERR_INTERNAL;
260 #ifdef DEBUG_MCIWAVE
261 printf("WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
262 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
263 mmckInfo.cksize);
264 #endif
265 if (mmioRead(MCIWavDev[wDevID].hFile, (HPSTR) lpWaveFormat,
266 (long) sizeof(PCMWAVEFORMAT)) != (long) sizeof(PCMWAVEFORMAT)) {
267 return MCIERR_INTERNAL;
269 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
270 if (mmioDescend(MCIWavDev[wDevID].hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) != 0) {
271 return MCIERR_INTERNAL;
273 #ifdef DEBUG_MCIWAVE
274 printf("WAVE_mciOpen // Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
275 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType,
276 mmckInfo.cksize);
277 printf("WAVE_mciOpen // nChannels=%d nSamplesPerSec=%d\n",
278 lpWaveFormat->wf.nChannels, lpWaveFormat->wf.nSamplesPerSec);
279 #endif
280 lpWaveFormat->wBitsPerSample = 0;
282 lpWaveFormat->wf.nAvgBytesPerSec =
283 lpWaveFormat->wf.nSamplesPerSec * lpWaveFormat->wf.nBlockAlign;
284 dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
285 dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
286 return 0;
287 #else
288 return MMSYSERR_NOTENABLED;
289 #endif
292 /**************************************************************************
293 * WAVE_mciClose [internal]
295 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
297 #ifdef linux
298 DWORD dwRet;
299 #ifdef DEBUG_MCIWAVE
300 printf("WAVE_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
301 #endif
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 #ifdef DEBUG_MCIWAVE
331 printf("WAVE_mciPlay(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
332 #endif
333 if (MCIWavDev[wDevID].hFile == 0) {
334 printf("WAVE_mciPlay // can't find file='%s' !\n",
335 MCIWavDev[wDevID].openParms.lpstrElementName);
336 return MCIERR_FILE_NOT_FOUND;
338 start = 1; end = 99999;
339 if (dwFlags & MCI_FROM) {
340 start = lpParms->dwFrom;
341 printf("WAVE_mciPlay // MCI_FROM=%d \n", start);
343 if (dwFlags & MCI_TO) {
344 end = lpParms->dwTo;
345 printf("WAVE_mciPlay // MCI_TO=%d \n", end);
348 if (dwFlags & MCI_NOTIFY) {
349 printf("WAVE_mciPlay // MCI_NOTIFY %08X !\n", lpParms->dwCallback);
350 switch(fork()) {
351 case -1:
352 printf("WAVE_mciPlay // Can't 'fork' process !\n");
353 break;
354 case 0:
355 break;
356 default:
357 printf("WAVE_mciPlay // process started ! return to caller...\n");
358 return 0;
362 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
363 lpWaveHdr->lpData = (LPSTR) malloc(64000);
364 lpWaveHdr->dwBufferLength = 32000;
365 lpWaveHdr->dwUser = 0L;
366 lpWaveHdr->dwFlags = 0L;
367 lpWaveHdr->dwLoops = 0L;
368 dwRet = wodMessage(0, WODM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
369 /* printf("WAVE_mciPlay // after WODM_PREPARE \n"); */
370 while(TRUE) {
371 count = mmioRead(MCIWavDev[wDevID].hFile, lpWaveHdr->lpData, lpWaveHdr->dwBufferLength);
372 if (count < 1) break;
373 lpWaveHdr->dwBytesRecorded = count;
374 #ifdef DEBUG_MCIWAVE
375 printf("WAVE_mciPlay // before WODM_WRITE lpWaveHdr=%08X dwBytesRecorded=%u\n",
376 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
377 #endif
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 #ifdef DEBUG_MCIWAVE
387 printf("WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
388 #endif
389 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
390 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
392 return 0;
393 #else
394 return MMSYSERR_NOTENABLED;
395 #endif
399 /**************************************************************************
400 * WAVE_mciRecord [internal]
402 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
404 #ifdef linux
405 int count;
406 int start, end;
407 LPWAVEHDR lpWaveHdr;
408 DWORD dwRet;
409 #ifdef DEBUG_MCIWAVE
410 printf("WAVE_mciRecord(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
411 #endif
412 if (MCIWavDev[wDevID].hFile == 0) {
413 printf("WAVE_mciRecord // can't find file='%s' !\n",
414 MCIWavDev[wDevID].openParms.lpstrElementName);
415 return MCIERR_FILE_NOT_FOUND;
417 start = 1; end = 99999;
418 if (dwFlags & MCI_FROM) {
419 start = lpParms->dwFrom;
420 printf("WAVE_mciRecord // MCI_FROM=%d \n", start);
422 if (dwFlags & MCI_TO) {
423 end = lpParms->dwTo;
424 printf("WAVE_mciRecord // MCI_TO=%d \n", end);
426 lpWaveHdr = &MCIWavDev[wDevID].WaveHdr;
427 lpWaveHdr->lpData = (LPSTR) malloc(64000);
428 lpWaveHdr->dwBufferLength = 32000;
429 lpWaveHdr->dwUser = 0L;
430 lpWaveHdr->dwFlags = 0L;
431 lpWaveHdr->dwLoops = 0L;
432 dwRet = widMessage(0, WIDM_PREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
433 printf("WAVE_mciRecord // after WIDM_PREPARE \n");
434 while(TRUE) {
435 lpWaveHdr->dwBytesRecorded = 0;
436 dwRet = widMessage(0, WIDM_START, 0, 0L, 0L);
437 printf("WAVE_mciRecord // after WIDM_START lpWaveHdr=%08X dwBytesRecorded=%u\n",
438 lpWaveHdr, lpWaveHdr->dwBytesRecorded);
439 if (lpWaveHdr->dwBytesRecorded == 0) break;
441 printf("WAVE_mciRecord // before WIDM_UNPREPARE \n");
442 dwRet = widMessage(0, WIDM_UNPREPARE, 0, (DWORD)lpWaveHdr, sizeof(WAVEHDR));
443 printf("WAVE_mciRecord // after WIDM_UNPREPARE \n");
444 if (lpWaveHdr->lpData != NULL) {
445 free(lpWaveHdr->lpData);
446 lpWaveHdr->lpData = NULL;
448 if (dwFlags & MCI_NOTIFY) {
449 #ifdef DEBUG_MCIWAVE
450 printf("WAVE_mciRecord // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
451 #endif
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 #ifdef DEBUG_MCIWAVE
469 printf("WAVE_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
470 #endif
471 if (lpParms == NULL) return MCIERR_INTERNAL;
472 return 0;
473 #else
474 return MCIERR_INTERNAL;
475 #endif
479 /**************************************************************************
480 * WAVE_mciPause [internal]
482 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
484 #ifdef linux
485 #ifdef DEBUG_MCIWAVE
486 printf("WAVE_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
487 #endif
488 if (lpParms == NULL) return MCIERR_INTERNAL;
489 return 0;
490 #else
491 return MCIERR_INTERNAL;
492 #endif
496 /**************************************************************************
497 * WAVE_mciResume [internal]
499 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
501 #ifdef linux
502 #ifdef DEBUG_MCIWAVE
503 printf("WAVE_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
504 #endif
505 if (lpParms == NULL) return MCIERR_INTERNAL;
506 return 0;
507 #else
508 return MCIERR_INTERNAL;
509 #endif
513 /**************************************************************************
514 * WAVE_mciSet [internal]
516 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
518 #ifdef linux
519 #ifdef DEBUG_MCIWAVE
520 printf("WAVE_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
521 #endif
522 if (lpParms == NULL) return MCIERR_INTERNAL;
523 #ifdef DEBUG_MCIWAVE
524 printf("WAVE_mciSet // dwTimeFormat=%08X\n", lpParms->dwTimeFormat);
525 printf("WAVE_mciSet // dwAudio=%08X\n", lpParms->dwAudio);
526 #endif
527 if (dwFlags & MCI_SET_TIME_FORMAT) {
528 switch (lpParms->dwTimeFormat) {
529 case MCI_FORMAT_MILLISECONDS:
530 printf("WAVE_mciSet // MCI_FORMAT_MILLISECONDS !\n");
531 break;
532 case MCI_FORMAT_BYTES:
533 printf("WAVE_mciSet // MCI_FORMAT_BYTES !\n");
534 break;
535 case MCI_FORMAT_SAMPLES:
536 printf("WAVE_mciSet // MCI_FORMAT_SAMPLES !\n");
537 break;
538 default:
539 printf("WAVE_mciSet // bad time format !\n");
540 return MCIERR_BAD_TIME_FORMAT;
543 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
544 if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
545 if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
546 if (dwFlags & MCI_SET_AUDIO) {
547 printf("WAVE_mciSet // MCI_SET_AUDIO !\n");
549 if (dwFlags && MCI_SET_ON) {
550 printf("WAVE_mciSet // MCI_SET_ON !\n");
551 if (dwFlags && MCI_SET_AUDIO_LEFT) {
552 printf("WAVE_mciSet // MCI_SET_AUDIO_LEFT !\n");
554 if (dwFlags && MCI_SET_AUDIO_RIGHT) {
555 printf("WAVE_mciSet // MCI_SET_AUDIO_RIGHT !\n");
558 if (dwFlags & MCI_SET_OFF) {
559 printf("WAVE_mciSet // MCI_SET_OFF !\n");
561 if (dwFlags & MCI_WAVE_INPUT) {
562 printf("WAVE_mciSet // MCI_WAVE_INPUT !\n");
564 if (dwFlags & MCI_WAVE_OUTPUT) {
565 printf("WAVE_mciSet // MCI_WAVE_OUTPUT !\n");
567 if (dwFlags & MCI_WAVE_SET_ANYINPUT) {
568 printf("WAVE_mciSet // MCI_WAVE_SET_ANYINPUT !\n");
570 if (dwFlags & MCI_WAVE_SET_ANYOUTPUT) {
571 printf("WAVE_mciSet // MCI_WAVE_SET_ANYOUTPUT !\n");
573 if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) {
574 printf("WAVE_mciSet // MCI_WAVE_SET_AVGBYTESPERSEC !\n");
576 if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE) {
577 printf("WAVE_mciSet // MCI_WAVE_SET_BITSPERSAMPLE !\n");
579 if (dwFlags & MCI_WAVE_SET_BLOCKALIGN) {
580 printf("WAVE_mciSet // MCI_WAVE_SET_BLOCKALIGN !\n");
582 if (dwFlags & MCI_WAVE_SET_CHANNELS) {
583 printf("WAVE_mciSet // MCI_WAVE_SET_CHANNELS !\n");
585 if (dwFlags & MCI_WAVE_SET_FORMATTAG) {
586 printf("WAVE_mciSet // MCI_WAVE_SET_FORMATTAG !\n");
588 if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC) {
589 printf("WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
591 return 0;
592 #else
593 return MCIERR_INTERNAL;
594 #endif
598 /**************************************************************************
599 * WAVE_mciStatus [internal]
601 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
603 #ifdef linux
604 #ifdef DEBUG_MCIWAVE
605 printf("WAVE_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
606 #endif
607 if (lpParms == NULL) return MCIERR_INTERNAL;
608 if (dwFlags & MCI_STATUS_ITEM) {
609 switch(lpParms->dwItem) {
610 case MCI_STATUS_CURRENT_TRACK:
611 lpParms->dwReturn = 1;
612 break;
613 case MCI_STATUS_LENGTH:
614 lpParms->dwReturn = 5555;
615 if (dwFlags & MCI_TRACK) {
616 lpParms->dwTrack = 1;
617 lpParms->dwReturn = 2222;
619 break;
620 case MCI_STATUS_MODE:
621 lpParms->dwReturn = MCI_MODE_STOP;
622 break;
623 case MCI_STATUS_MEDIA_PRESENT:
624 printf("WAVE_mciStatus // MCI_STATUS_MEDIA_PRESENT !\n");
625 lpParms->dwReturn = TRUE;
626 break;
627 case MCI_STATUS_NUMBER_OF_TRACKS:
628 lpParms->dwReturn = 1;
629 break;
630 case MCI_STATUS_POSITION:
631 lpParms->dwReturn = 3333;
632 if (dwFlags & MCI_STATUS_START) {
633 lpParms->dwItem = 1;
635 if (dwFlags & MCI_TRACK) {
636 lpParms->dwTrack = 1;
637 lpParms->dwReturn = 777;
639 break;
640 case MCI_STATUS_READY:
641 printf("WAVE_mciStatus // MCI_STATUS_READY !\n");
642 lpParms->dwReturn = TRUE;
643 break;
644 case MCI_STATUS_TIME_FORMAT:
645 printf("WAVE_mciStatus // MCI_STATUS_TIME_FORMAT !\n");
646 lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
647 break;
648 case MCI_WAVE_INPUT:
649 printf("WAVE_mciStatus // MCI_WAVE_INPUT !\n");
650 lpParms->dwReturn = 0;
651 break;
652 case MCI_WAVE_OUTPUT:
653 printf("WAVE_mciStatus // MCI_WAVE_OUTPUT !\n");
654 lpParms->dwReturn = 0;
655 break;
656 case MCI_WAVE_STATUS_AVGBYTESPERSEC:
657 printf("WAVE_mciStatus // MCI_WAVE_STATUS_AVGBYTESPERSEC !\n");
658 lpParms->dwReturn = 22050;
659 break;
660 case MCI_WAVE_STATUS_BITSPERSAMPLE:
661 printf("WAVE_mciStatus // MCI_WAVE_STATUS_BITSPERSAMPLE !\n");
662 lpParms->dwReturn = 8;
663 break;
664 case MCI_WAVE_STATUS_BLOCKALIGN:
665 printf("WAVE_mciStatus // MCI_WAVE_STATUS_BLOCKALIGN !\n");
666 lpParms->dwReturn = 1;
667 break;
668 case MCI_WAVE_STATUS_CHANNELS:
669 printf("WAVE_mciStatus // MCI_WAVE_STATUS_CHANNELS !\n");
670 lpParms->dwReturn = 1;
671 break;
672 case MCI_WAVE_STATUS_FORMATTAG:
673 printf("WAVE_mciStatus // MCI_WAVE_FORMATTAG !\n");
674 lpParms->dwReturn = WAVE_FORMAT_PCM;
675 break;
676 case MCI_WAVE_STATUS_LEVEL:
677 printf("WAVE_mciStatus // MCI_WAVE_STATUS_LEVEL !\n");
678 lpParms->dwReturn = 0xAAAA5555;
679 break;
680 case MCI_WAVE_STATUS_SAMPLESPERSEC:
681 printf("WAVE_mciStatus // MCI_WAVE_STATUS_SAMPLESPERSEC !\n");
682 lpParms->dwReturn = 22050;
683 break;
684 default:
685 printf("WAVE_mciStatus // unknowm command %04X !\n", lpParms->dwItem);
686 return MCIERR_UNRECOGNIZED_COMMAND;
689 if (dwFlags & MCI_NOTIFY) {
690 printf("WAVE_mciStatus // MCI_NOTIFY_SUCCESSFUL %08X !\n", lpParms->dwCallback);
691 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
692 MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
694 return 0;
695 #else
696 return MCIERR_INTERNAL;
697 #endif
700 /**************************************************************************
701 * WAVE_mciGetDevCaps [internal]
703 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
704 LPMCI_GETDEVCAPS_PARMS lpParms)
706 #ifdef linux
707 printf("WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
708 if (lpParms == NULL) return MCIERR_INTERNAL;
709 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
710 switch(lpParms->dwItem) {
711 case MCI_GETDEVCAPS_CAN_RECORD:
712 lpParms->dwReturn = TRUE;
713 break;
714 case MCI_GETDEVCAPS_HAS_AUDIO:
715 lpParms->dwReturn = TRUE;
716 break;
717 case MCI_GETDEVCAPS_HAS_VIDEO:
718 lpParms->dwReturn = FALSE;
719 break;
720 case MCI_GETDEVCAPS_DEVICE_TYPE:
721 lpParms->dwReturn = MCI_DEVTYPE_WAVEFORM_AUDIO;
722 break;
723 case MCI_GETDEVCAPS_USES_FILES:
724 lpParms->dwReturn = TRUE;
725 break;
726 case MCI_GETDEVCAPS_COMPOUND_DEVICE:
727 lpParms->dwReturn = TRUE;
728 break;
729 case MCI_GETDEVCAPS_CAN_EJECT:
730 lpParms->dwReturn = FALSE;
731 break;
732 case MCI_GETDEVCAPS_CAN_PLAY:
733 lpParms->dwReturn = TRUE;
734 break;
735 case MCI_GETDEVCAPS_CAN_SAVE:
736 lpParms->dwReturn = FALSE;
737 break;
738 case MCI_WAVE_GETDEVCAPS_INPUTS:
739 lpParms->dwReturn = 1;
740 break;
741 case MCI_WAVE_GETDEVCAPS_OUTPUTS:
742 lpParms->dwReturn = 1;
743 break;
744 default:
745 return MCIERR_UNRECOGNIZED_COMMAND;
748 return 0;
749 #else
750 return MCIERR_INTERNAL;
751 #endif
754 /**************************************************************************
755 * WAVE_mciInfo [internal]
757 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
759 #ifdef linux
760 printf("WAVE_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
761 if (lpParms == NULL) return MCIERR_INTERNAL;
762 lpParms->lpstrReturn = NULL;
763 switch(dwFlags) {
764 case MCI_INFO_PRODUCT:
765 lpParms->lpstrReturn = "Linux Sound System 0.5";
766 break;
767 case MCI_INFO_FILE:
768 lpParms->lpstrReturn = "FileName";
769 break;
770 case MCI_WAVE_INPUT:
771 lpParms->lpstrReturn = "Linux Sound System 0.5";
772 break;
773 case MCI_WAVE_OUTPUT:
774 lpParms->lpstrReturn = "Linux Sound System 0.5";
775 break;
776 default:
777 return MCIERR_UNRECOGNIZED_COMMAND;
779 if (lpParms->lpstrReturn != NULL)
780 lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
781 else
782 lpParms->dwRetSize = 0;
783 return 0;
784 #else
785 return MCIERR_INTERNAL;
786 #endif
790 /*-----------------------------------------------------------------------*/
793 /**************************************************************************
794 * wodGetDevCaps [internal]
796 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
798 #ifdef linux
799 int audio;
800 int smplrate;
801 int samplesize = 16;
802 int dsp_stereo = 1;
803 int bytespersmpl;
804 printf("wodGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
805 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
806 audio = open (SOUND_DEV, O_WRONLY, 0);
807 if (audio == -1) return MMSYSERR_NOTENABLED;
808 lpCaps->wMid = 0xFF; /* Manufac ID */
809 lpCaps->wPid = 0x01; /* Product ID */
810 strcpy(lpCaps->szPname, "Linux WAV Driver");
811 lpCaps->dwFormats = 0;
812 lpCaps->dwSupport = 0;
813 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
814 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
815 smplrate = 44100;
816 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
817 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
818 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
819 if (bytespersmpl > 1) {
820 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
821 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
824 smplrate = 22050;
825 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
826 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
827 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
828 if (bytespersmpl > 1) {
829 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
830 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
833 smplrate = 11025;
834 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
835 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
836 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
837 if (bytespersmpl > 1) {
838 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
839 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
842 close(audio);
843 printf("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 printf("wodOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
863 if (lpDesc == NULL) {
864 printf("Linux 'wodOpen' // Invalid Parameter !\n");
865 return MMSYSERR_INVALPARAM;
867 if (wDevID >= MAX_WAVOUTDRV) {
868 printf("Linux 'wodOpen' // MAX_WAVOUTDRV reached !\n");
869 return MMSYSERR_ALLOCATED;
871 WOutDev[wDevID].unixdev = 0;
872 audio = open (SOUND_DEV, O_WRONLY, 0);
873 if (audio == -1) {
874 printf("Linux 'wodOpen' // can't open !\n");
875 return MMSYSERR_NOTENABLED;
877 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
878 if (abuf_size < 4096 || abuf_size > 65536) {
879 if (abuf_size == -1)
880 printf("Linux 'wodOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
881 else
882 printf("Linux 'wodOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
883 return MMSYSERR_NOTENABLED;
885 WOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
886 switch(WOutDev[wDevID].wFlags) {
887 case DCB_NULL:
888 printf("Linux 'wodOpen' // CALLBACK_NULL !\n");
889 break;
890 case DCB_WINDOW:
891 printf("Linux 'wodOpen' // CALLBACK_WINDOW !\n");
892 break;
893 case DCB_TASK:
894 printf("Linux 'wodOpen' // CALLBACK_TASK !\n");
895 break;
896 case DCB_FUNCTION:
897 printf("Linux 'wodOpen' // CALLBACK_FUNCTION !\n");
898 break;
900 WOutDev[wDevID].lpQueueHdr = NULL;
901 WOutDev[wDevID].unixdev = audio;
902 WOutDev[wDevID].dwTotalPlayed = 0;
903 WOutDev[wDevID].bufsize = abuf_size;
904 memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
905 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
906 printf("Linux 'wodOpen' // Bad format %04X !\n",
907 lpDesc->lpFormat->wFormatTag);
908 return WAVERR_BADFORMAT;
910 memcpy(&WOutDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
911 if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
912 if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
913 if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
914 WOutDev[wDevID].Format.wBitsPerSample = 8 *
915 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec /
916 WOutDev[wDevID].Format.wf.nSamplesPerSec) /
917 WOutDev[wDevID].Format.wf.nChannels;
919 samplesize = WOutDev[wDevID].Format.wBitsPerSample;
920 smplrate = WOutDev[wDevID].Format.wf.nSamplesPerSec;
921 dsp_stereo = (WOutDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
922 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
923 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
924 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
925 printf("Linux 'wodOpen' // wBitsPerSample=%u !\n",
926 WOutDev[wDevID].Format.wBitsPerSample);
927 printf("Linux 'wodOpen' // nSamplesPerSec=%u !\n",
928 WOutDev[wDevID].Format.wf.nSamplesPerSec);
929 printf("Linux 'wodOpen' // nChannels=%u !\n",
930 WOutDev[wDevID].Format.wf.nChannels);
931 if (WAVE_NotifyClient(wDevID, WOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
932 printf("Linux 'wodOpen' // can't notify client !\n");
933 return MMSYSERR_INVALPARAM;
935 return MMSYSERR_NOERROR;
936 #else
937 return MMSYSERR_NOTENABLED;
938 #endif
941 /**************************************************************************
942 * wodClose [internal]
944 DWORD wodClose(WORD wDevID)
946 #ifdef linux
947 printf("wodClose(%u);\n", wDevID);
948 if (WOutDev[wDevID].unixdev == 0) {
949 printf("Linux 'wodClose' // can't close !\n");
950 return MMSYSERR_NOTENABLED;
952 close(WOutDev[wDevID].unixdev);
953 WOutDev[wDevID].unixdev = 0;
954 WOutDev[wDevID].bufsize = 0;
955 if (WAVE_NotifyClient(wDevID, WOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
956 printf("Linux 'wodClose' // can't notify client !\n");
957 return MMSYSERR_INVALPARAM;
959 return MMSYSERR_NOERROR;
960 #else
961 return MMSYSERR_NOTENABLED;
962 #endif
965 /**************************************************************************
966 * wodWrite [internal]
968 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
970 #ifdef linux
971 printf("wodWrite(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
972 if (WOutDev[wDevID].unixdev == 0) {
973 printf("Linux 'wodWrite' // can't play !\n");
974 return MMSYSERR_NOTENABLED;
976 if (lpWaveHdr->lpData == NULL) return WAVERR_UNPREPARED;
977 if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) return WAVERR_UNPREPARED;
978 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
979 lpWaveHdr->dwFlags &= ~WHDR_DONE;
980 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
981 printf("wodWrite() // dwBytesRecorded %u !\n", lpWaveHdr->dwBytesRecorded);
982 if (write (WOutDev[wDevID].unixdev, lpWaveHdr->lpData,
983 lpWaveHdr->dwBytesRecorded) != lpWaveHdr->dwBytesRecorded) {
984 return MMSYSERR_NOTENABLED;
986 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
987 lpWaveHdr->dwFlags |= WHDR_DONE;
988 if (WAVE_NotifyClient(wDevID, WOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
989 printf("Linux 'wodWrite' // can't notify client !\n");
990 return MMSYSERR_INVALPARAM;
992 return MMSYSERR_NOERROR;
993 #else
994 return MMSYSERR_NOTENABLED;
995 #endif
998 /**************************************************************************
999 * wodPrepare [internal]
1001 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1003 #ifdef linux
1004 printf("wodPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1005 if (WOutDev[wDevID].unixdev == 0) {
1006 printf("Linux 'wodPrepare' // can't prepare !\n");
1007 return MMSYSERR_NOTENABLED;
1009 if (WOutDev[wDevID].lpQueueHdr != NULL) {
1010 printf("Linux 'wodPrepare' // already prepare !\n");
1011 return MMSYSERR_NOTENABLED;
1013 WOutDev[wDevID].dwTotalPlayed = 0;
1014 WOutDev[wDevID].lpQueueHdr = lpWaveHdr;
1015 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1016 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1017 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1018 return MMSYSERR_NOERROR;
1019 #else
1020 return MMSYSERR_NOTENABLED;
1021 #endif
1024 /**************************************************************************
1025 * wodUnprepare [internal]
1027 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1029 #ifdef linux
1030 printf("wodUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1031 if (WOutDev[wDevID].unixdev == 0) {
1032 printf("Linux 'wodUnprepare' // can't unprepare !\n");
1033 return MMSYSERR_NOTENABLED;
1035 return MMSYSERR_NOERROR;
1036 #else
1037 return MMSYSERR_NOTENABLED;
1038 #endif
1041 /**************************************************************************
1042 * wodRestart [internal]
1044 DWORD wodRestart(WORD wDevID)
1046 #ifdef linux
1047 printf("wodRestart(%u);\n", wDevID);
1048 if (WOutDev[wDevID].unixdev == 0) {
1049 printf("Linux 'wodRestart' // can't restart !\n");
1050 return MMSYSERR_NOTENABLED;
1052 return MMSYSERR_NOERROR;
1053 #else
1054 return MMSYSERR_NOTENABLED;
1055 #endif
1058 /**************************************************************************
1059 * wodReset [internal]
1061 DWORD wodReset(WORD wDevID)
1063 #ifdef linux
1064 printf("wodReset(%u);\n", wDevID);
1065 if (WOutDev[wDevID].unixdev == 0) {
1066 printf("Linux 'wodReset' // can't reset !\n");
1067 return MMSYSERR_NOTENABLED;
1069 return MMSYSERR_NOERROR;
1070 #else
1071 return MMSYSERR_NOTENABLED;
1072 #endif
1076 /**************************************************************************
1077 * wodGetPosition [internal]
1079 DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1081 #ifdef linux
1082 int time;
1083 printf("wodGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1084 if (WOutDev[wDevID].unixdev == 0) {
1085 printf("Linux 'wodGetPosition' // can't get pos !\n");
1086 return MMSYSERR_NOTENABLED;
1088 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1089 TryAGAIN:
1090 switch(lpTime->wType) {
1091 case TIME_BYTES:
1092 lpTime->u.cb = WOutDev[wDevID].dwTotalPlayed;
1093 printf("wodGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1094 break;
1095 case TIME_SAMPLES:
1096 lpTime->u.sample = WOutDev[wDevID].dwTotalPlayed * 8 /
1097 WOutDev[wDevID].Format.wBitsPerSample;
1098 printf("wodGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
1099 break;
1100 case TIME_MS:
1101 lpTime->u.ms = WOutDev[wDevID].dwTotalPlayed /
1102 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1103 printf("wodGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1104 break;
1105 case TIME_SMPTE:
1106 time = WOutDev[wDevID].dwTotalPlayed /
1107 (WOutDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1108 lpTime->u.smpte.hour = time / 108000;
1109 time -= lpTime->u.smpte.hour * 108000;
1110 lpTime->u.smpte.min = time / 1800;
1111 time -= lpTime->u.smpte.min * 1800;
1112 lpTime->u.smpte.sec = time / 30;
1113 time -= lpTime->u.smpte.sec * 30;
1114 lpTime->u.smpte.frame = time;
1115 lpTime->u.smpte.fps = 30;
1116 printf("wodGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1117 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1118 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1119 break;
1120 default:
1121 printf("wodGetPosition() format not supported ! use TIME_MS !\n");
1122 lpTime->wType = TIME_MS;
1123 goto TryAGAIN;
1125 return MMSYSERR_NOERROR;
1126 #else
1127 return MMSYSERR_NOTENABLED;
1128 #endif
1131 /**************************************************************************
1132 * wodSetVolume [internal]
1134 DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1136 #ifdef linux
1137 int mixer;
1138 int volume = 50;
1139 printf("wodSetVolume(%u, %08X);\n", wDevID, dwParam);
1140 if (WOutDev[wDevID].unixdev == 0) {
1141 printf("Linux 'wodSetVolume' // can't set volume !\n");
1142 return MMSYSERR_NOTENABLED;
1144 if ((mixer = open("/dev/mixer", O_RDWR)) < 0) {
1145 printf("Linux 'wodSetVolume' // mixer device not available !\n");
1146 return MMSYSERR_NOTENABLED;
1148 if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
1149 printf("Linux 'wodSetVolume' // unable set mixer !\n");
1150 return MMSYSERR_NOTENABLED;
1152 close(mixer);
1153 return MMSYSERR_NOERROR;
1154 #else
1155 return MMSYSERR_NOTENABLED;
1156 #endif
1160 /**************************************************************************
1161 * wodMessage [sample driver]
1163 DWORD wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1164 DWORD dwParam1, DWORD dwParam2)
1166 printf("wodMessage(%u, %04X, %08X, %08X, %08X);\n",
1167 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1168 switch(wMsg) {
1169 case WODM_OPEN:
1170 return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1171 case WODM_CLOSE:
1172 return wodClose(wDevID);
1173 case WODM_WRITE:
1174 return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1175 case WODM_PAUSE:
1176 return 0L;
1177 case WODM_GETPOS:
1178 return wodGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1179 case WODM_BREAKLOOP:
1180 return 0L;
1181 case WODM_PREPARE:
1182 return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1183 case WODM_UNPREPARE:
1184 return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1185 case WODM_GETDEVCAPS:
1186 return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)dwParam1, dwParam2);
1187 case WODM_GETNUMDEVS:
1188 return 1L;
1189 case WODM_GETPITCH:
1190 return 0L;
1191 case WODM_SETPITCH:
1192 return 0L;
1193 case WODM_GETPLAYBACKRATE:
1194 return 0L;
1195 case WODM_SETPLAYBACKRATE:
1196 return 0L;
1197 case WODM_GETVOLUME:
1198 return 0L;
1199 case WODM_SETVOLUME:
1200 return wodSetVolume(wDevID, dwParam1);
1201 case WODM_RESTART:
1202 return wodRestart(wDevID);
1203 case WODM_RESET:
1204 return wodReset(wDevID);
1206 return MMSYSERR_NOTSUPPORTED;
1210 /*-----------------------------------------------------------------------*/
1212 /**************************************************************************
1213 * widGetDevCaps [internal]
1215 DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
1217 #ifdef linux
1218 int audio;
1219 int smplrate;
1220 int samplesize = 16;
1221 int dsp_stereo = 1;
1222 int bytespersmpl;
1223 printf("widGetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
1224 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1225 audio = open (SOUND_DEV, O_RDONLY, 0);
1226 if (audio == -1) return MMSYSERR_NOTENABLED;
1227 lpCaps->wMid = 0xFF; /* Manufac ID */
1228 lpCaps->wPid = 0x01; /* Product ID */
1229 strcpy(lpCaps->szPname, "Linux WAV Driver");
1230 lpCaps->dwFormats = 0;
1231 lpCaps->wChannels = (IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo) != 0) ? 1 : 2;
1232 bytespersmpl = (IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize) != 0) ? 1 : 2;
1233 smplrate = 44100;
1234 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1235 lpCaps->dwFormats |= WAVE_FORMAT_4M08;
1236 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S08;
1237 if (bytespersmpl > 1) {
1238 lpCaps->dwFormats |= WAVE_FORMAT_4M16;
1239 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_4S16;
1242 smplrate = 22050;
1243 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1244 lpCaps->dwFormats |= WAVE_FORMAT_2M08;
1245 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S08;
1246 if (bytespersmpl > 1) {
1247 lpCaps->dwFormats |= WAVE_FORMAT_2M16;
1248 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_2S16;
1251 smplrate = 11025;
1252 if (IOCTL(audio, SNDCTL_DSP_SPEED, smplrate) == 0) {
1253 lpCaps->dwFormats |= WAVE_FORMAT_1M08;
1254 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S08;
1255 if (bytespersmpl > 1) {
1256 lpCaps->dwFormats |= WAVE_FORMAT_1M16;
1257 if (lpCaps->wChannels > 1) lpCaps->dwFormats |= WAVE_FORMAT_1S16;
1260 close(audio);
1261 printf("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 printf("widOpen(%u, %08X, %08X);\n", wDevID, lpDesc, dwFlags);
1281 if (lpDesc == NULL) {
1282 printf("Linux 'widOpen' // Invalid Parameter !\n");
1283 return MMSYSERR_INVALPARAM;
1285 if (wDevID >= MAX_WAVINDRV) {
1286 printf("Linux 'widOpen' // MAX_WAVINDRV reached !\n");
1287 return MMSYSERR_ALLOCATED;
1289 WInDev[wDevID].unixdev = 0;
1290 audio = open (SOUND_DEV, O_RDONLY, 0);
1291 if (audio == -1) {
1292 printf("Linux 'widOpen' // can't open !\n");
1293 return MMSYSERR_NOTENABLED;
1295 IOCTL(audio, SNDCTL_DSP_GETBLKSIZE, abuf_size);
1296 if (abuf_size < 4096 || abuf_size > 65536) {
1297 if (abuf_size == -1)
1298 printf("Linux 'widOpen' // IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
1299 else
1300 printf("Linux 'widOpen' // SNDCTL_DSP_GETBLKSIZE Invalid bufsize !\n");
1301 return MMSYSERR_NOTENABLED;
1303 WInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1304 switch(WInDev[wDevID].wFlags) {
1305 case DCB_NULL:
1306 printf("Linux 'widOpen' // CALLBACK_NULL !\n");
1307 break;
1308 case DCB_WINDOW:
1309 printf("Linux 'widOpen' // CALLBACK_WINDOW !\n");
1310 break;
1311 case DCB_TASK:
1312 printf("Linux 'widOpen' // CALLBACK_TASK !\n");
1313 break;
1314 case DCB_FUNCTION:
1315 printf("Linux 'widOpen' // CALLBACK_FUNCTION !\n");
1316 break;
1318 WInDev[wDevID].lpQueueHdr = NULL;
1319 WInDev[wDevID].unixdev = audio;
1320 WInDev[wDevID].bufsize = abuf_size;
1321 WInDev[wDevID].dwTotalRecorded = 0;
1322 memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1323 if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1324 printf("Linux 'widOpen' // Bad format %04X !\n",
1325 lpDesc->lpFormat->wFormatTag);
1326 return WAVERR_BADFORMAT;
1328 memcpy(&WInDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
1329 WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
1330 if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
1331 if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
1332 if (WInDev[wDevID].Format.wBitsPerSample == 0) {
1333 WInDev[wDevID].Format.wBitsPerSample = 8 *
1334 (WInDev[wDevID].Format.wf.nAvgBytesPerSec /
1335 WInDev[wDevID].Format.wf.nSamplesPerSec) /
1336 WInDev[wDevID].Format.wf.nChannels;
1338 samplesize = WInDev[wDevID].Format.wBitsPerSample;
1339 smplrate = WInDev[wDevID].Format.wf.nSamplesPerSec;
1340 dsp_stereo = (WInDev[wDevID].Format.wf.nChannels > 1) ? TRUE : FALSE;
1341 IOCTL(audio, SNDCTL_DSP_SPEED, smplrate);
1342 IOCTL(audio, SNDCTL_DSP_SAMPLESIZE, samplesize);
1343 IOCTL(audio, SNDCTL_DSP_STEREO, dsp_stereo);
1344 #ifdef DEBUG_MCIWAVE
1345 printf("Linux 'widOpen' // wBitsPerSample=%u !\n",
1346 WInDev[wDevID].Format.wBitsPerSample);
1347 printf("Linux 'widOpen' // nSamplesPerSec=%u !\n",
1348 WInDev[wDevID].Format.wf.nSamplesPerSec);
1349 printf("Linux 'widOpen' // nChannels=%u !\n",
1350 WInDev[wDevID].Format.wf.nChannels);
1351 printf("Linux 'widOpen' // nAvgBytesPerSec=%u\n",
1352 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1353 #endif
1354 if (WAVE_NotifyClient(wDevID, WIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
1355 printf("Linux 'widOpen' // can't notify client !\n");
1356 return MMSYSERR_INVALPARAM;
1358 return MMSYSERR_NOERROR;
1359 #else
1360 return MMSYSERR_NOTENABLED;
1361 #endif
1364 /**************************************************************************
1365 * widClose [internal]
1367 DWORD widClose(WORD wDevID)
1369 #ifdef linux
1370 printf("widClose(%u);\n", wDevID);
1371 if (WInDev[wDevID].unixdev == 0) {
1372 printf("Linux 'widClose' // can't close !\n");
1373 return MMSYSERR_NOTENABLED;
1375 close(WInDev[wDevID].unixdev);
1376 WInDev[wDevID].unixdev = 0;
1377 WInDev[wDevID].bufsize = 0;
1378 if (WAVE_NotifyClient(wDevID, WIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
1379 printf("Linux 'widClose' // can't notify client !\n");
1380 return MMSYSERR_INVALPARAM;
1382 return MMSYSERR_NOERROR;
1383 #else
1384 return MMSYSERR_NOTENABLED;
1385 #endif
1388 /**************************************************************************
1389 * widAddBuffer [internal]
1391 DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1393 #ifdef linux
1394 int count = 1;
1395 LPWAVEHDR lpWIHdr;
1396 printf("widAddBuffer(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1397 if (WInDev[wDevID].unixdev == 0) {
1398 printf("Linux 'widAddBuffer' // can't do it !\n");
1399 return MMSYSERR_NOTENABLED;
1401 if (WInDev[wDevID].lpQueueHdr == NULL ||
1402 !(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
1403 printf("Linux 'widAddBuffer' // never been prepared !\n");
1404 return WAVERR_UNPREPARED;
1406 if ((lpWaveHdr->dwFlags & WHDR_INQUEUE) &&
1407 (WInDev[wDevID].lpQueueHdr != lpWaveHdr)) {
1408 /* except if it's the one just prepared ... */
1409 printf("Linux 'widAddBuffer' // header already in use !\n");
1410 return WAVERR_STILLPLAYING;
1412 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1413 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1414 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1415 lpWaveHdr->dwBytesRecorded = 0;
1416 /* added to the queue, except if it's the one just prepared ... */
1417 if (WInDev[wDevID].lpQueueHdr != lpWaveHdr) {
1418 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1419 while (lpWIHdr->lpNext != NULL) {
1420 lpWIHdr = lpWIHdr->lpNext;
1421 count++;
1423 lpWIHdr->lpNext = lpWaveHdr;
1424 count++;
1426 printf("widAddBuffer // buffer added ! (now %u in queue)\n", count);
1427 return MMSYSERR_NOERROR;
1428 #else
1429 return MMSYSERR_NOTENABLED;
1430 #endif
1433 /**************************************************************************
1434 * widPrepare [internal]
1436 DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1438 #ifdef linux
1439 printf("widPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1440 if (WInDev[wDevID].unixdev == 0) {
1441 printf("Linux 'widPrepare' // can't prepare !\n");
1442 return MMSYSERR_NOTENABLED;
1444 if (WInDev[wDevID].lpQueueHdr != NULL) {
1445 printf("Linux 'widPrepare' // already prepare !\n");
1446 return WAVERR_BADFORMAT;
1448 WInDev[wDevID].dwTotalRecorded = 0;
1449 WInDev[wDevID].lpQueueHdr = lpWaveHdr;
1450 if (lpWaveHdr->dwFlags & WHDR_INQUEUE) return WAVERR_STILLPLAYING;
1451 lpWaveHdr->dwFlags |= WHDR_PREPARED;
1452 lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1453 lpWaveHdr->dwFlags &= ~WHDR_DONE;
1454 lpWaveHdr->dwBytesRecorded = 0;
1455 printf("Linux 'widPrepare' // header prepared !\n");
1456 return MMSYSERR_NOERROR;
1457 #else
1458 return MMSYSERR_NOTENABLED;
1459 #endif
1462 /**************************************************************************
1463 * widUnprepare [internal]
1465 DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1467 #ifdef linux
1468 printf("widUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
1469 if (WInDev[wDevID].unixdev == 0) {
1470 printf("Linux 'widUnprepare' // can't unprepare !\n");
1471 return MMSYSERR_NOTENABLED;
1473 lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1474 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1475 lpWaveHdr->dwFlags |= WHDR_DONE;
1476 WInDev[wDevID].lpQueueHdr = NULL;
1477 printf("Linux 'widUnprepare' // all headers unprepared !\n");
1478 return MMSYSERR_NOERROR;
1479 #else
1480 return MMSYSERR_NOTENABLED;
1481 #endif
1484 /**************************************************************************
1485 * widStart [internal]
1487 DWORD widStart(WORD wDevID)
1489 #ifdef linux
1490 int count = 1;
1491 LPWAVEHDR lpWIHdr;
1492 printf("widStart(%u);\n", wDevID);
1493 if (WInDev[wDevID].unixdev == 0) {
1494 printf("Linux 'widStart' // can't start recording !\n");
1495 return MMSYSERR_NOTENABLED;
1497 if (WInDev[wDevID].lpQueueHdr == NULL ||
1498 WInDev[wDevID].lpQueueHdr->lpData == NULL) {
1499 printf("Linux 'widStart' // never been prepared !\n");
1500 return WAVERR_UNPREPARED;
1502 lpWIHdr = WInDev[wDevID].lpQueueHdr;
1503 while(lpWIHdr != NULL) {
1504 lpWIHdr->dwBufferLength &= 0xFFFF;
1505 printf("widStart // recording buf#%u=%08X size=%u \n",
1506 count, lpWIHdr->lpData, lpWIHdr->dwBufferLength);
1507 fflush(stdout);
1508 read (WInDev[wDevID].unixdev, lpWIHdr->lpData,
1509 lpWIHdr->dwBufferLength);
1510 lpWIHdr->dwBytesRecorded = lpWIHdr->dwBufferLength;
1511 WInDev[wDevID].dwTotalRecorded += lpWIHdr->dwBytesRecorded;
1512 lpWIHdr->dwFlags &= ~WHDR_INQUEUE;
1513 lpWIHdr->dwFlags |= WHDR_DONE;
1514 if (WAVE_NotifyClient(wDevID, WIM_DATA, (DWORD)lpWIHdr, 0L) !=
1515 MMSYSERR_NOERROR) {
1516 printf("Linux 'widStart' // can't notify client !\n");
1517 return MMSYSERR_INVALPARAM;
1519 lpWIHdr = lpWIHdr->lpNext;
1520 count++;
1522 printf("widStart // end of recording !\n");
1523 fflush(stdout);
1524 return MMSYSERR_NOERROR;
1525 #else
1526 return MMSYSERR_NOTENABLED;
1527 #endif
1530 /**************************************************************************
1531 * widStop [internal]
1533 DWORD widStop(WORD wDevID)
1535 #ifdef linux
1536 printf("widStop(%u);\n", wDevID);
1537 if (WInDev[wDevID].unixdev == 0) {
1538 printf("Linux 'widStop' // can't stop !\n");
1539 return MMSYSERR_NOTENABLED;
1541 return MMSYSERR_NOERROR;
1542 #else
1543 return MMSYSERR_NOTENABLED;
1544 #endif
1547 /**************************************************************************
1548 * widReset [internal]
1550 DWORD widReset(WORD wDevID)
1552 #ifdef linux
1553 printf("widReset(%u);\n", wDevID);
1554 if (WInDev[wDevID].unixdev == 0) {
1555 printf("Linux 'widReset' // can't reset !\n");
1556 return MMSYSERR_NOTENABLED;
1558 return MMSYSERR_NOERROR;
1559 #else
1560 return MMSYSERR_NOTENABLED;
1561 #endif
1564 /**************************************************************************
1565 * widGetPosition [internal]
1567 DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1569 #ifdef linux
1570 int time;
1571 #ifdef DEBUG_MCIWAVE
1572 printf("widGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
1573 #endif
1574 if (WInDev[wDevID].unixdev == 0) {
1575 printf("Linux 'widGetPosition' // can't get pos !\n");
1576 return MMSYSERR_NOTENABLED;
1578 if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1579 TryAGAIN:
1580 #ifdef DEBUG_MCIWAVE
1581 printf("widGetPosition // wType=%04X !\n", lpTime->wType);
1582 printf("widGetPosition // wBitsPerSample=%u\n",
1583 WInDev[wDevID].Format.wBitsPerSample);
1584 printf("widGetPosition // nSamplesPerSec=%u\n",
1585 WInDev[wDevID].Format.wf.nSamplesPerSec);
1586 printf("widGetPosition // nChannels=%u\n",
1587 WInDev[wDevID].Format.wf.nChannels);
1588 printf("widGetPosition // nAvgBytesPerSec=%u\n",
1589 WInDev[wDevID].Format.wf.nAvgBytesPerSec);
1590 fflush(stdout);
1591 #endif
1592 switch(lpTime->wType) {
1593 case TIME_BYTES:
1594 lpTime->u.cb = WInDev[wDevID].dwTotalRecorded;
1595 printf("widGetPosition // TIME_BYTES=%u\n", lpTime->u.cb);
1596 break;
1597 case TIME_SAMPLES:
1598 lpTime->u.sample = WInDev[wDevID].dwTotalRecorded * 8 /
1599 WInDev[wDevID].Format.wBitsPerSample;
1600 printf("widGetPosition // TIME_SAMPLES=%u\n", lpTime->u.sample);
1601 break;
1602 case TIME_MS:
1603 lpTime->u.ms = WInDev[wDevID].dwTotalRecorded /
1604 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1605 printf("widGetPosition // TIME_MS=%u\n", lpTime->u.ms);
1606 break;
1607 case TIME_SMPTE:
1608 time = WInDev[wDevID].dwTotalRecorded /
1609 (WInDev[wDevID].Format.wf.nAvgBytesPerSec / 1000);
1610 lpTime->u.smpte.hour = time / 108000;
1611 time -= lpTime->u.smpte.hour * 108000;
1612 lpTime->u.smpte.min = time / 1800;
1613 time -= lpTime->u.smpte.min * 1800;
1614 lpTime->u.smpte.sec = time / 30;
1615 time -= lpTime->u.smpte.sec * 30;
1616 lpTime->u.smpte.frame = time;
1617 lpTime->u.smpte.fps = 30;
1618 printf("widGetPosition // TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1619 lpTime->u.smpte.hour, lpTime->u.smpte.min,
1620 lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1621 break;
1622 default:
1623 printf("widGetPosition() format not supported ! use TIME_MS !\n");
1624 lpTime->wType = TIME_MS;
1625 goto TryAGAIN;
1627 return MMSYSERR_NOERROR;
1628 #else
1629 return MMSYSERR_NOTENABLED;
1630 #endif
1633 /**************************************************************************
1634 * widMessage [sample driver]
1636 DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1637 DWORD dwParam1, DWORD dwParam2)
1639 printf("widMessage(%u, %04X, %08X, %08X, %08X);\n",
1640 wDevID, wMsg, dwUser, dwParam1, dwParam2);
1641 switch(wMsg) {
1642 case WIDM_OPEN:
1643 return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
1644 case WIDM_CLOSE:
1645 return widClose(wDevID);
1646 case WIDM_ADDBUFFER:
1647 return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1648 case WIDM_PREPARE:
1649 return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1650 case WIDM_UNPREPARE:
1651 return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
1652 case WIDM_GETDEVCAPS:
1653 return widGetDevCaps(wDevID, (LPWAVEINCAPS)dwParam1, dwParam2);
1654 case WIDM_GETNUMDEVS:
1655 return 1L;
1656 case WIDM_GETPOS:
1657 return widGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
1658 case WIDM_RESET:
1659 return widReset(wDevID);
1660 case WIDM_START:
1661 return widStart(wDevID);
1662 case WIDM_STOP:
1663 return widStop(wDevID);
1665 return MMSYSERR_NOTSUPPORTED;
1669 /*-----------------------------------------------------------------------*/
1673 /**************************************************************************
1674 * midMessage [sample driver]
1676 DWORD midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1677 DWORD dwParam1, DWORD dwParam2)
1679 return MMSYSERR_NOTENABLED;
1682 /**************************************************************************
1683 * modMessage [sample driver]
1685 DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
1686 DWORD dwParam1, DWORD dwParam2)
1688 return MMSYSERR_NOTENABLED;
1691 #endif /* #ifdef BUILTIN_MMSYSTEM */