iphlpapi: Support for non-linux platforms, including Mac OS X.
[wine] / dlls / wineesd.drv / audio.c
1 /*
2  * Wine Driver for EsounD Sound Server
3  * http://www.tux.org/~ricdude/EsounD.html
4  *
5  * Copyright 1994 Martin Ayotte
6  *           1999 Eric Pouech (async playing in waveOut/waveIn)
7  *           2000 Eric Pouech (loops in waveOut)
8  *           2004 Zhangrong Huang (EsounD version of this file)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 /* NOTE:
25  *    with esd we cannot stop the audio that is already in
26  *    the servers buffer.
27  *
28  * FIXME:
29  *      pause in waveOut does not work correctly in loop mode
30  *
31  *      does something need to be done in for WaveIn DirectSound?
32  *
33  */
34
35 #include "config.h"
36
37 #include <errno.h>
38 #include <math.h>
39 #include <stdlib.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <string.h>
43 #ifdef HAVE_UNISTD_H
44 # include <unistd.h>
45 #endif
46 #include <fcntl.h>
47 #ifdef HAVE_POLL_H
48 #include <poll.h>
49 #endif
50 #ifdef HAVE_SYS_POLL_H
51 # include <sys/poll.h>
52 #endif
53
54 #include "windef.h"
55 #include "winbase.h"
56 #include "wingdi.h"
57 #include "winerror.h"
58 #include "wine/winuser16.h"
59 #include "mmddk.h"
60 #include "mmreg.h"
61 #include "dsound.h"
62 #include "dsdriver.h"
63 #include "ks.h"
64 #include "ksguid.h"
65 #include "ksmedia.h"
66 #include "esound.h"
67 #include "wine/debug.h"
68
69 WINE_DEFAULT_DEBUG_CHANNEL(wave);
70
71 #ifdef HAVE_ESD
72
73 #include <esd.h>
74
75 /* unless someone makes a wineserver kernel module, Unix pipes are faster than win32 events */
76 #define USE_PIPE_SYNC
77
78 /* define if you want to use esd_monitor_stream instead of
79  * esd_record_stream for waveIn stream
80  */
81 /*#define WID_USE_ESDMON*/
82
83 #define BUFFER_REFILL_THRESHOLD 4
84
85 #define MAX_WAVEOUTDRV  (10)
86 #define MAX_WAVEINDRV   (10)
87 #define MAX_CHANNELS    2
88
89 /* state diagram for waveOut writing:
90  *
91  * +---------+-------------+---------------+---------------------------------+
92  * |  state  |  function   |     event     |            new state            |
93  * +---------+-------------+---------------+---------------------------------+
94  * |         | open()      |               | STOPPED                         |
95  * | PAUSED  | write()     |               | PAUSED                          |
96  * | STOPPED | write()     | <thrd create> | PLAYING                         |
97  * | PLAYING | write()     | HEADER        | PLAYING                         |
98  * | (other) | write()     | <error>       |                                 |
99  * | (any)   | pause()     | PAUSING       | PAUSED                          |
100  * | PAUSED  | restart()   | RESTARTING    | PLAYING (if no thrd => STOPPED) |
101  * | (any)   | reset()     | RESETTING     | STOPPED                         |
102  * | (any)   | close()     | CLOSING       | CLOSED                          |
103  * +---------+-------------+---------------+---------------------------------+
104  */
105
106 /* states of the playing device */
107 #define WINE_WS_PLAYING         0
108 #define WINE_WS_PAUSED          1
109 #define WINE_WS_STOPPED         2
110 #define WINE_WS_CLOSED          3
111
112 /* events to be send to device */
113 enum win_wm_message {
114     WINE_WM_PAUSING = WM_USER + 1, WINE_WM_RESTARTING, WINE_WM_RESETTING, WINE_WM_HEADER,
115     WINE_WM_UPDATE, WINE_WM_BREAKLOOP, WINE_WM_CLOSING, WINE_WM_STARTING, WINE_WM_STOPPING
116 };
117
118 #ifdef USE_PIPE_SYNC
119 #define SIGNAL_OMR(mr) do { int x = 0; write((mr)->msg_pipe[1], &x, sizeof(x)); } while (0)
120 #define CLEAR_OMR(mr) do { int x = 0; read((mr)->msg_pipe[0], &x, sizeof(x)); } while (0)
121 #define RESET_OMR(mr) do { } while (0)
122 #define WAIT_OMR(mr, sleep) \
123   do { struct pollfd pfd; pfd.fd = (mr)->msg_pipe[0]; \
124        pfd.events = POLLIN; poll(&pfd, 1, sleep); } while (0)
125 #else
126 #define SIGNAL_OMR(mr) do { SetEvent((mr)->msg_event); } while (0)
127 #define CLEAR_OMR(mr) do { } while (0)
128 #define RESET_OMR(mr) do { ResetEvent((mr)->msg_event); } while (0)
129 #define WAIT_OMR(mr, sleep) \
130   do { WaitForSingleObject((mr)->msg_event, sleep); } while (0)
131 #endif
132
133 typedef struct {
134     enum win_wm_message         msg;    /* message identifier */
135     DWORD                       param;  /* parameter for this message */
136     HANDLE                      hEvent; /* if message is synchronous, handle of event for synchro */
137 } RING_MSG;
138
139 /* implement an in-process message ring for better performance
140  * (compared to passing thru the server)
141  * this ring will be used by the input (resp output) record (resp playback) routine
142  */
143 #define ESD_RING_BUFFER_INCREMENT      64
144 typedef struct {
145     RING_MSG                    * messages;
146     int                         ring_buffer_size;
147     int                         msg_tosave;
148     int                         msg_toget;
149 #ifdef USE_PIPE_SYNC
150     int                         msg_pipe[2];
151 #else
152     HANDLE                      msg_event;
153 #endif
154     CRITICAL_SECTION            msg_crst;
155 } ESD_MSG_RING;
156
157 typedef struct {
158     volatile int                state;                  /* one of the WINE_WS_ manifest constants */
159     WAVEOPENDESC                waveDesc;
160     WORD                        wFlags;
161     WAVEFORMATPCMEX             waveFormat;
162     WAVEOUTCAPSW                caps;
163     char                        interface_name[32];
164
165     DWORD                       dwSleepTime;            /* Num of milliseconds to sleep between filling the dsp buffers */
166
167     /* esd information */
168     int                         esd_fd;         /* the socket fd we get from esd when opening a stream for playing */
169     int                         bytes_per_frame;
170     DWORD                       dwBufferSize;           /* size of whole buffer in bytes */
171
172     char*                       sound_buffer;
173     long                        buffer_size;
174
175     DWORD                       volume_left;            /* volume control information */
176     DWORD                       volume_right;
177
178     LPWAVEHDR                   lpQueuePtr;             /* start of queued WAVEHDRs (waiting to be notified) */
179     LPWAVEHDR                   lpPlayPtr;              /* start of not yet fully played buffers */
180     DWORD                       dwPartialOffset;        /* Offset of not yet written bytes in lpPlayPtr */
181
182     LPWAVEHDR                   lpLoopPtr;              /* pointer of first buffer in loop, if any */
183     DWORD                       dwLoops;                /* private copy of loop counter */
184
185     DWORD                       dwPlayedTotal;          /* number of bytes actually played since opening */
186     DWORD                       dwWrittenTotal;         /* number of bytes written to the audio device since opening */
187
188     /* synchronization stuff */
189     HANDLE                      hStartUpEvent;
190     HANDLE                      hThread;
191     DWORD                       dwThreadID;
192     ESD_MSG_RING                msgRing;
193 } WINE_WAVEOUT;
194
195 typedef struct {
196     volatile int                state;                  /* one of the WINE_WS_ manifest constants */
197     WAVEOPENDESC                waveDesc;
198     WORD                        wFlags;
199     WAVEFORMATPCMEX             waveFormat;
200     WAVEINCAPSW                 caps;
201     char                        interface_name[32];
202
203     /* esd information */
204     int                         esd_fd;         /* the socket fd we get from esd when opening a stream for recording */
205     int                         bytes_per_frame;
206
207     LPWAVEHDR                   lpQueuePtr;
208     DWORD                       dwRecordedTotal;
209
210     /* synchronization stuff */
211     HANDLE                      hStartUpEvent;
212     HANDLE                      hThread;
213     DWORD                       dwThreadID;
214     ESD_MSG_RING                msgRing;
215 } WINE_WAVEIN;
216
217 static char* esd_host;  /* the esd host */
218
219 static WINE_WAVEOUT     WOutDev   [MAX_WAVEOUTDRV];
220 static WINE_WAVEIN      WInDev    [MAX_WAVEINDRV];
221
222 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
223 static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);
224
225 /* These strings used only for tracing */
226 static const char *wodPlayerCmdString[] = {
227     "WINE_WM_PAUSING",
228     "WINE_WM_RESTARTING",
229     "WINE_WM_RESETTING",
230     "WINE_WM_HEADER",
231     "WINE_WM_UPDATE",
232     "WINE_WM_BREAKLOOP",
233     "WINE_WM_CLOSING",
234     "WINE_WM_STARTING",
235     "WINE_WM_STOPPING",
236 };
237
238 /*======================================================================*
239  *                  Low level WAVE implementation                       *
240  *======================================================================*/
241
242 /* Volume functions derived from Alsaplayer source */
243 /* length is the number of 16 bit samples */
244 void volume_effect16(void *bufin, void* bufout, int length, int left,
245                 int right, int  nChannels)
246 {
247   short *d_out = (short *)bufout;
248   short *d_in = (short *)bufin;
249   int i, v;
250
251 /*
252   TRACE("length == %d, nChannels == %d\n", length, nChannels);
253 */
254
255   if (right == -1) right = left;
256
257   for(i = 0; i < length; i+=(nChannels))
258   {
259     v = (int) ((*(d_in++) * left) / 100);
260     *(d_out++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
261     if(nChannels == 2)
262     {
263       v = (int) ((*(d_in++) * right) / 100);
264       *(d_out++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
265     }
266   }
267 }
268
269 /* length is the number of 8 bit samples */
270 void volume_effect8(void *bufin, void* bufout, int length, int left,
271                 int right, int  nChannels)
272 {
273   BYTE *d_out = (BYTE *)bufout;
274   BYTE *d_in = (BYTE *)bufin;
275   int i, v;
276
277 /*
278   TRACE("length == %d, nChannels == %d\n", length, nChannels);
279 */
280
281   if (right == -1) right = left;
282
283   for(i = 0; i < length; i+=(nChannels))
284   {
285     v = (BYTE) ((*(d_in++) * left) / 100);
286     *(d_out++) = (v>255) ? 255 : ((v<0) ? 0 : v);
287     if(nChannels == 2)
288     {
289       v = (BYTE) ((*(d_in++) * right) / 100);
290       *(d_out++) = (v>255) ? 255 : ((v<0) ? 0 : v);
291     }
292   }
293 }
294
295 static DWORD bytes_to_mmtime(LPMMTIME lpTime, DWORD position,
296                              WAVEFORMATPCMEX* format)
297 {
298     TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%u nChannels=%u nAvgBytesPerSec=%u\n",
299           lpTime->wType, format->Format.wBitsPerSample, format->Format.nSamplesPerSec,
300           format->Format.nChannels, format->Format.nAvgBytesPerSec);
301     TRACE("Position in bytes=%u\n", position);
302
303     switch (lpTime->wType) {
304     case TIME_SAMPLES:
305         lpTime->u.sample = position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels);
306         TRACE("TIME_SAMPLES=%u\n", lpTime->u.sample);
307         break;
308     case TIME_MS:
309         lpTime->u.ms = 1000.0 * position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels * format->Format.nSamplesPerSec);
310         TRACE("TIME_MS=%u\n", lpTime->u.ms);
311         break;
312     case TIME_SMPTE:
313         lpTime->u.smpte.fps = 30;
314         position = position / (format->Format.wBitsPerSample / 8 * format->Format.nChannels);
315         position += (format->Format.nSamplesPerSec / lpTime->u.smpte.fps) - 1; /* round up */
316         lpTime->u.smpte.sec = position / format->Format.nSamplesPerSec;
317         position -= lpTime->u.smpte.sec * format->Format.nSamplesPerSec;
318         lpTime->u.smpte.min = lpTime->u.smpte.sec / 60;
319         lpTime->u.smpte.sec -= 60 * lpTime->u.smpte.min;
320         lpTime->u.smpte.hour = lpTime->u.smpte.min / 60;
321         lpTime->u.smpte.min -= 60 * lpTime->u.smpte.hour;
322         lpTime->u.smpte.fps = 30;
323         lpTime->u.smpte.frame = position * lpTime->u.smpte.fps / format->Format.nSamplesPerSec;
324         TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
325               lpTime->u.smpte.hour, lpTime->u.smpte.min,
326               lpTime->u.smpte.sec, lpTime->u.smpte.frame);
327         break;
328     default:
329         WARN("Format %d not supported, using TIME_BYTES !\n", lpTime->wType);
330         lpTime->wType = TIME_BYTES;
331         /* fall through */
332     case TIME_BYTES:
333         lpTime->u.cb = position;
334         TRACE("TIME_BYTES=%u\n", lpTime->u.cb);
335         break;
336     }
337     return MMSYSERR_NOERROR;
338 }
339
340 static BOOL supportedFormat(LPWAVEFORMATEX wf)
341 {
342     TRACE("(%p)\n",wf);
343                                                                                 
344     if (wf->nSamplesPerSec<DSBFREQUENCY_MIN||wf->nSamplesPerSec>DSBFREQUENCY_MAX)
345         return FALSE;
346                                                                                 
347     if (wf->wFormatTag == WAVE_FORMAT_PCM) {
348         if (wf->nChannels >= 1 && wf->nChannels <= MAX_CHANNELS) {
349             if (wf->wBitsPerSample==8||wf->wBitsPerSample==16)
350                 return TRUE;
351         }
352     } else if (wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
353         WAVEFORMATEXTENSIBLE * wfex = (WAVEFORMATEXTENSIBLE *)wf;
354                                                                                 
355         if (wf->cbSize == 22 && IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
356             if (wf->nChannels >=1 && wf->nChannels <= MAX_CHANNELS) {
357                 if (wf->wBitsPerSample==wfex->Samples.wValidBitsPerSample) {
358                     if (wf->wBitsPerSample==8||wf->wBitsPerSample==16)
359                         return TRUE;
360                 } else
361                     WARN("wBitsPerSample != wValidBitsPerSample not supported yet\n");
362             }
363         } else
364             WARN("only KSDATAFORMAT_SUBTYPE_PCM supported\n");
365     } else
366         WARN("only WAVE_FORMAT_PCM and WAVE_FORMAT_EXTENSIBLE supported\n");
367                                                                                 
368     return FALSE;
369 }
370
371 void copy_format(LPWAVEFORMATEX wf1, LPWAVEFORMATPCMEX wf2)
372 {
373     ZeroMemory(wf2, sizeof(wf2));
374     if (wf1->wFormatTag == WAVE_FORMAT_PCM)
375         memcpy(wf2, wf1, sizeof(PCMWAVEFORMAT));
376     else if (wf1->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
377         memcpy(wf2, wf1, sizeof(WAVEFORMATPCMEX));
378     else
379         memcpy(wf2, wf1, sizeof(WAVEFORMATEX) + wf1->cbSize);
380 }
381
382 /******************************************************************
383  *              ESD_CloseWaveOutDevice
384  *
385  */
386 void            ESD_CloseWaveOutDevice(WINE_WAVEOUT* wwo)
387 {
388         esd_close(wwo->esd_fd);         /* close the esd socket fd */
389         wwo->esd_fd = -1;
390
391   /* free up the buffer we use for volume and reset the size */
392   HeapFree(GetProcessHeap(), 0, wwo->sound_buffer);
393   wwo->sound_buffer = NULL;
394   wwo->buffer_size = 0;
395 }
396
397 /******************************************************************
398  *              ESD_CloseWaveInDevice
399  *
400  */
401 void            ESD_CloseWaveInDevice(WINE_WAVEIN* wwi)
402 {
403         esd_close(wwi->esd_fd);         /* close the esd socket fd */
404         wwi->esd_fd = -1;
405 }
406
407 /******************************************************************
408  *              ESD_WaveClose
409  */
410 LONG            ESD_WaveClose(void)
411 {
412     int iDevice;
413
414     /* close all open devices */
415     for(iDevice = 0; iDevice < MAX_WAVEOUTDRV; iDevice++)
416     {
417       if(WOutDev[iDevice].esd_fd != -1)
418       {
419         ESD_CloseWaveOutDevice(&WOutDev[iDevice]);
420       }
421     }
422
423     for(iDevice = 0; iDevice < MAX_WAVEINDRV; iDevice++)
424     {
425       if(WInDev[iDevice].esd_fd != -1)
426       {
427         ESD_CloseWaveInDevice(&WInDev[iDevice]);
428       }
429     }
430
431     return 1;
432 }
433
434 /******************************************************************
435  *              ESD_WaveInit
436  *
437  * Initialize internal structures from ESD server info
438  */
439 LONG ESD_WaveInit(void)
440 {
441     int         i;
442         int     fd;
443
444     TRACE("called\n");
445
446     /* FIXME: Maybe usefully to set the esd host. */
447     esd_host = NULL;
448
449     /* Testing whether the esd host is alive. */
450     if ((fd = esd_open_sound(esd_host)) < 0)
451     {
452         WARN("esd_open_sound() failed (%d)\n", errno);
453         return -1;
454     }
455     esd_close(fd);
456
457     /* initialize all device handles to -1 */
458     for (i = 0; i < MAX_WAVEOUTDRV; ++i)
459     {
460         static const WCHAR ini[] = {'E','s','o','u','n','D',' ','W','a','v','e','O','u','t','D','r','i','v','e','r',0};
461
462         WOutDev[i].esd_fd = -1;
463         memset(&WOutDev[i].caps, 0, sizeof(WOutDev[i].caps)); /* zero out
464                                                         caps values */
465         WOutDev[i].caps.wMid = 0x00FF;  /* Manufac ID */
466         WOutDev[i].caps.wPid = 0x0001;  /* Product ID */
467         lstrcpyW(WOutDev[i].caps.szPname, ini);
468         snprintf(WOutDev[i].interface_name, sizeof(WOutDev[i].interface_name), "wineesd: %d", i);
469
470         WOutDev[i].caps.vDriverVersion = 0x0100;
471         WOutDev[i].caps.dwFormats = 0x00000000;
472         WOutDev[i].caps.dwSupport = WAVECAPS_VOLUME;
473
474         WOutDev[i].caps.wChannels = 2;
475         WOutDev[i].caps.dwSupport |= WAVECAPS_LRVOLUME;
476
477         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
478         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S08;
479         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
480         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
481         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
482         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S08;
483         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
484         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
485         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
486         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;
487         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
488         WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
489     }
490
491     for (i = 0; i < MAX_WAVEINDRV; ++i)
492     {
493         static const WCHAR ini[] = {'E','s','o','u','n','D',' ','W','a','v','e','I','n','D','r','i','v','e','r',0};
494
495         WInDev[i].esd_fd = -1;
496         memset(&WInDev[i].caps, 0, sizeof(WInDev[i].caps)); /* zero out
497                                                         caps values */
498         WInDev[i].caps.wMid = 0x00FF;
499         WInDev[i].caps.wPid = 0x0001;
500         lstrcpyW(WInDev[i].caps.szPname, ini);
501         snprintf(WInDev[i].interface_name, sizeof(WInDev[i].interface_name), "wineesd: %d", i);
502
503         WInDev[i].caps.vDriverVersion = 0x0100;
504         WInDev[i].caps.dwFormats = 0x00000000;
505
506         WInDev[i].caps.wChannels = 2;
507
508         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
509         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S08;
510         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
511         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
512         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
513         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S08;
514         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
515         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
516         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
517         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;
518         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
519         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
520
521         WInDev[i].caps.wReserved1 = 0;
522     }
523     return 0;
524 }
525
526 /******************************************************************
527  *              ESD_InitRingMessage
528  *
529  * Initialize the ring of messages for passing between driver's caller and playback/record
530  * thread
531  */
532 static int ESD_InitRingMessage(ESD_MSG_RING* mr)
533 {
534     mr->msg_toget = 0;
535     mr->msg_tosave = 0;
536 #ifdef USE_PIPE_SYNC
537     if (pipe(mr->msg_pipe) < 0) {
538         mr->msg_pipe[0] = -1;
539         mr->msg_pipe[1] = -1;
540         ERR("could not create pipe, error=%s\n", strerror(errno));
541     }
542 #else
543     mr->msg_event = CreateEventW(NULL, FALSE, FALSE, NULL);
544 #endif
545     mr->ring_buffer_size = ESD_RING_BUFFER_INCREMENT;
546     mr->messages = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,mr->ring_buffer_size * sizeof(RING_MSG));
547     InitializeCriticalSection(&mr->msg_crst);
548     mr->msg_crst.DebugInfo->Spare[0] = (DWORD_PTR)"WINEESD_msg_crst";
549     return 0;
550 }
551
552 /******************************************************************
553  *              ESD_DestroyRingMessage
554  *
555  */
556 static int ESD_DestroyRingMessage(ESD_MSG_RING* mr)
557 {
558 #ifdef USE_PIPE_SYNC
559     close(mr->msg_pipe[0]);
560     close(mr->msg_pipe[1]);
561 #else
562     CloseHandle(mr->msg_event);
563 #endif
564     HeapFree(GetProcessHeap(),0,mr->messages);
565     mr->messages=NULL;
566     DeleteCriticalSection(&mr->msg_crst);
567     return 0;
568 }
569
570 /******************************************************************
571  *              ESD_AddRingMessage
572  *
573  * Inserts a new message into the ring (should be called from DriverProc derivated routines)
574  */
575 static int ESD_AddRingMessage(ESD_MSG_RING* mr, enum win_wm_message msg, DWORD param, BOOL wait)
576 {
577     HANDLE      hEvent = INVALID_HANDLE_VALUE;
578
579     EnterCriticalSection(&mr->msg_crst);
580     if ((mr->msg_toget == ((mr->msg_tosave + 1) % mr->ring_buffer_size)))
581     {
582         int old_ring_buffer_size = mr->ring_buffer_size;
583         mr->ring_buffer_size += ESD_RING_BUFFER_INCREMENT;
584         TRACE("mr->ring_buffer_size=%d\n",mr->ring_buffer_size);
585         mr->messages = HeapReAlloc(GetProcessHeap(),0,mr->messages, mr->ring_buffer_size * sizeof(RING_MSG));
586         /* Now we need to rearrange the ring buffer so that the new
587            buffers just allocated are in between mr->msg_tosave and
588            mr->msg_toget.
589         */
590         if (mr->msg_tosave < mr->msg_toget)
591         {
592             memmove(&(mr->messages[mr->msg_toget + ESD_RING_BUFFER_INCREMENT]),
593                     &(mr->messages[mr->msg_toget]),
594                     sizeof(RING_MSG)*(old_ring_buffer_size - mr->msg_toget)
595                     );
596             mr->msg_toget += ESD_RING_BUFFER_INCREMENT;
597         }
598     }
599     if (wait)
600     {
601         hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
602         if (hEvent == INVALID_HANDLE_VALUE)
603         {
604             ERR("can't create event !?\n");
605             LeaveCriticalSection(&mr->msg_crst);
606             return 0;
607         }
608         if (mr->msg_toget != mr->msg_tosave && mr->messages[mr->msg_toget].msg != WINE_WM_HEADER)
609             FIXME("two fast messages in the queue!!!!\n");
610
611         /* fast messages have to be added at the start of the queue */
612         mr->msg_toget = (mr->msg_toget + mr->ring_buffer_size - 1) % mr->ring_buffer_size;
613
614         mr->messages[mr->msg_toget].msg = msg;
615         mr->messages[mr->msg_toget].param = param;
616         mr->messages[mr->msg_toget].hEvent = hEvent;
617     }
618     else
619     {
620         mr->messages[mr->msg_tosave].msg = msg;
621         mr->messages[mr->msg_tosave].param = param;
622         mr->messages[mr->msg_tosave].hEvent = INVALID_HANDLE_VALUE;
623         mr->msg_tosave = (mr->msg_tosave + 1) % mr->ring_buffer_size;
624     }
625
626     LeaveCriticalSection(&mr->msg_crst);
627
628     /* signal a new message */
629     SIGNAL_OMR(mr);
630     if (wait)
631     {
632         /* wait for playback/record thread to have processed the message */
633         WaitForSingleObject(hEvent, INFINITE);
634         CloseHandle(hEvent);
635     }
636
637     return 1;
638 }
639
640 /******************************************************************
641  *              ESD_RetrieveRingMessage
642  *
643  * Get a message from the ring. Should be called by the playback/record thread.
644  */
645 static int ESD_RetrieveRingMessage(ESD_MSG_RING* mr,
646                                    enum win_wm_message *msg, DWORD *param, HANDLE *hEvent)
647 {
648     EnterCriticalSection(&mr->msg_crst);
649
650     if (mr->msg_toget == mr->msg_tosave) /* buffer empty ? */
651     {
652         LeaveCriticalSection(&mr->msg_crst);
653         return 0;
654     }
655
656     *msg = mr->messages[mr->msg_toget].msg;
657     mr->messages[mr->msg_toget].msg = 0;
658     *param = mr->messages[mr->msg_toget].param;
659     *hEvent = mr->messages[mr->msg_toget].hEvent;
660     mr->msg_toget = (mr->msg_toget + 1) % mr->ring_buffer_size;
661     CLEAR_OMR(mr);
662     LeaveCriticalSection(&mr->msg_crst);
663     return 1;
664 }
665
666 /*======================================================================*
667  *                  Low level WAVE OUT implementation                   *
668  *======================================================================*/
669
670 /**************************************************************************
671  *                      wodNotifyClient                 [internal]
672  */
673 static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
674 {
675     TRACE("wMsg = 0x%04x dwParm1 = %04X dwParam2 = %04X\n", wMsg, dwParam1, dwParam2);
676
677     switch (wMsg) {
678     case WOM_OPEN:
679     case WOM_CLOSE:
680     case WOM_DONE:
681         if (wwo->wFlags != DCB_NULL &&
682             !DriverCallback(wwo->waveDesc.dwCallback, wwo->wFlags, (HDRVR)wwo->waveDesc.hWave,
683                             wMsg, wwo->waveDesc.dwInstance, dwParam1, dwParam2)) {
684             WARN("can't notify client !\n");
685             return MMSYSERR_ERROR;
686         }
687         break;
688     default:
689         FIXME("Unknown callback message %u\n", wMsg);
690         return MMSYSERR_INVALPARAM;
691     }
692     return MMSYSERR_NOERROR;
693 }
694
695 /**************************************************************************
696  *                              wodUpdatePlayedTotal    [internal]
697  *
698  */
699 static BOOL wodUpdatePlayedTotal(WINE_WAVEOUT* wwo)
700 {
701     /* total played is the bytes written less the bytes to write ;-) */
702     wwo->dwPlayedTotal = wwo->dwWrittenTotal;
703
704     return TRUE;
705 }
706
707 /**************************************************************************
708  *                              wodPlayer_BeginWaveHdr          [internal]
709  *
710  * Makes the specified lpWaveHdr the currently playing wave header.
711  * If the specified wave header is a begin loop and we're not already in
712  * a loop, setup the loop.
713  */
714 static void wodPlayer_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
715 {
716     wwo->lpPlayPtr = lpWaveHdr;
717
718     if (!lpWaveHdr) return;
719
720     if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP) {
721         if (wwo->lpLoopPtr) {
722             WARN("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
723             TRACE("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
724         } else {
725             TRACE("Starting loop (%dx) with %p\n", lpWaveHdr->dwLoops, lpWaveHdr);
726             wwo->lpLoopPtr = lpWaveHdr;
727             /* Windows does not touch WAVEHDR.dwLoops,
728              * so we need to make an internal copy */
729             wwo->dwLoops = lpWaveHdr->dwLoops;
730         }
731     }
732     wwo->dwPartialOffset = 0;
733 }
734
735 /**************************************************************************
736  *                              wodPlayer_PlayPtrNext           [internal]
737  *
738  * Advance the play pointer to the next waveheader, looping if required.
739  */
740 static LPWAVEHDR wodPlayer_PlayPtrNext(WINE_WAVEOUT* wwo)
741 {
742     LPWAVEHDR lpWaveHdr = wwo->lpPlayPtr;
743
744     wwo->dwPartialOffset = 0;
745     if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr) {
746         /* We're at the end of a loop, loop if required */
747         if (--wwo->dwLoops > 0) {
748             wwo->lpPlayPtr = wwo->lpLoopPtr;
749         } else {
750             /* Handle overlapping loops correctly */
751             if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) {
752                 FIXME("Correctly handled case ? (ending loop buffer also starts a new loop)\n");
753                 /* shall we consider the END flag for the closing loop or for
754                  * the opening one or for both ???
755                  * code assumes for closing loop only
756                  */
757             } else {
758                 lpWaveHdr = lpWaveHdr->lpNext;
759             }
760             wwo->lpLoopPtr = NULL;
761             wodPlayer_BeginWaveHdr(wwo, lpWaveHdr);
762         }
763     } else {
764         /* We're not in a loop.  Advance to the next wave header */
765         wodPlayer_BeginWaveHdr(wwo, lpWaveHdr = lpWaveHdr->lpNext);
766     }
767
768     return lpWaveHdr;
769 }
770
771 /**************************************************************************
772  *                           wodPlayer_NotifyWait               [internal]
773  * Returns the number of milliseconds to wait before attempting to notify
774  * completion of the specified wavehdr.
775  * This is based on the number of bytes remaining to be written in the
776  * wave.
777  */
778 static DWORD wodPlayer_NotifyWait(const WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
779 {
780     DWORD dwMillis;
781
782     if(lpWaveHdr->reserved < wwo->dwPlayedTotal)
783     {
784         dwMillis = 1;
785     }
786     else
787     {
788         dwMillis = (lpWaveHdr->reserved - wwo->dwPlayedTotal) * 1000 / wwo->waveFormat.Format.nAvgBytesPerSec;
789         if(!dwMillis) dwMillis = 1;
790     }
791
792     TRACE("dwMillis = %d\n", dwMillis);
793
794     return dwMillis;
795 }
796
797
798 /**************************************************************************
799  *                           wodPlayer_WriteMaxFrags            [internal]
800  * Writes the maximum number of bytes possible to the DSP and returns
801  * the number of bytes written.
802  */
803 static int wodPlayer_WriteMaxFrags(WINE_WAVEOUT* wwo, DWORD* bytes)
804 {
805     /* Only attempt to write to free bytes */
806     DWORD dwLength = wwo->lpPlayPtr->dwBufferLength - wwo->dwPartialOffset;
807     int toWrite = min(dwLength, *bytes);
808     int written;
809
810     TRACE("Writing wavehdr %p.%u[%u]\n",
811           wwo->lpPlayPtr, wwo->dwPartialOffset, wwo->lpPlayPtr->dwBufferLength);
812
813     /* see if our buffer isn't large enough for the data we are writing */
814     if(wwo->buffer_size < toWrite)
815     {
816       if(wwo->sound_buffer)
817       {
818         wwo->sound_buffer = HeapReAlloc(GetProcessHeap(), 0, wwo->sound_buffer, toWrite);
819         wwo->buffer_size = toWrite;
820       }
821     }
822
823     /* if we don't have a buffer then get one */
824     if(!wwo->sound_buffer)
825     {
826       /* allocate some memory for the buffer */
827       wwo->sound_buffer = HeapAlloc(GetProcessHeap(), 0, toWrite);
828       wwo->buffer_size = toWrite;
829     }
830
831     /* if we don't have a buffer then error out */
832     if(!wwo->sound_buffer)
833     {
834       ERR("error allocating sound_buffer memory\n");
835       return 0;
836     }
837
838     TRACE("toWrite == %d\n", toWrite);
839
840     /* apply volume to the bits */
841     /* for single channel audio streams we only use the LEFT volume */
842     if(wwo->waveFormat.Format.wBitsPerSample == 16)
843     {
844       /* apply volume to the buffer we are about to send */
845       /* divide toWrite(bytes) by 2 as volume processes by 16 bits */
846       volume_effect16(wwo->lpPlayPtr->lpData + wwo->dwPartialOffset,
847                 wwo->sound_buffer, toWrite>>1, wwo->volume_left,
848                 wwo->volume_right, wwo->waveFormat.Format.nChannels);
849     } else if(wwo->waveFormat.Format.wBitsPerSample == 8)
850     {
851       /* apply volume to the buffer we are about to send */
852       volume_effect8(wwo->lpPlayPtr->lpData + wwo->dwPartialOffset,
853                 wwo->sound_buffer, toWrite, wwo->volume_left,
854                 wwo->volume_right, wwo->waveFormat.Format.nChannels);
855     } else
856     {
857       FIXME("unsupported wwo->format.wBitsPerSample of %d\n",
858         wwo->waveFormat.Format.wBitsPerSample);
859     }
860
861     /* send the audio data to esd for playing */
862     written = write(wwo->esd_fd, wwo->sound_buffer, toWrite);
863
864     TRACE("written = %d\n", written);
865
866     if (written <= 0) 
867     {
868       *bytes = 0; /* apparently esd is actually full */
869       return written; /* if we wrote nothing just return */
870     }
871
872     if (written >= dwLength)
873         wodPlayer_PlayPtrNext(wwo);   /* If we wrote all current wavehdr, skip to the next one */
874     else
875         wwo->dwPartialOffset += written;    /* Remove the amount written */
876
877     if (written < toWrite)
878         *bytes = 0;
879     else
880         *bytes -= written;
881
882     wwo->dwWrittenTotal += written; /* update stats on this wave device */
883
884     return written; /* return the number of bytes written */
885 }
886
887
888 /**************************************************************************
889  *                              wodPlayer_NotifyCompletions     [internal]
890  *
891  * Notifies and remove from queue all wavehdrs which have been played to
892  * the speaker (ie. they have cleared the audio device).  If force is true,
893  * we notify all wavehdrs and remove them all from the queue even if they
894  * are unplayed or part of a loop.
895  */
896 static DWORD wodPlayer_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force)
897 {
898     LPWAVEHDR           lpWaveHdr;
899
900     if (wwo->lpQueuePtr) {
901         TRACE("lpWaveHdr=(%p), lpPlayPtr=(%p), lpLoopPtr=(%p), reserved=(%d), dwWrittenTotal=(%d), force=(%d)\n",
902               wwo->lpQueuePtr,
903               wwo->lpPlayPtr,
904               wwo->lpLoopPtr,
905               wwo->lpQueuePtr->reserved,
906               wwo->dwWrittenTotal,
907               force);
908     } else {
909         TRACE("lpWaveHdr=(%p), lpPlayPtr=(%p), lpLoopPtr=(%p),  dwWrittenTotal=(%d), force=(%d)\n",
910               wwo->lpQueuePtr,
911               wwo->lpPlayPtr,
912               wwo->lpLoopPtr,
913               wwo->dwWrittenTotal,
914               force);
915     }
916
917     /* Start from lpQueuePtr and keep notifying until:
918      * - we hit an unwritten wavehdr
919      * - we hit the beginning of a running loop
920      * - we hit a wavehdr which hasn't finished playing
921      */
922     while ((lpWaveHdr = wwo->lpQueuePtr) &&
923            (force ||
924             (lpWaveHdr != wwo->lpPlayPtr &&
925              lpWaveHdr != wwo->lpLoopPtr &&
926              lpWaveHdr->reserved <= wwo->dwWrittenTotal))) {
927
928         wwo->lpQueuePtr = lpWaveHdr->lpNext;
929
930         lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
931         lpWaveHdr->dwFlags |= WHDR_DONE;
932
933         wodNotifyClient(wwo, WOM_DONE, (DWORD)lpWaveHdr, 0);
934     }
935     return  (lpWaveHdr && lpWaveHdr != wwo->lpPlayPtr && lpWaveHdr != wwo->lpLoopPtr) ?
936         wodPlayer_NotifyWait(wwo, lpWaveHdr) : INFINITE;
937 }
938
939 /**************************************************************************
940  *                              wodPlayer_Reset                 [internal]
941  *
942  * wodPlayer helper. Resets current output stream.
943  */
944 static  void    wodPlayer_Reset(WINE_WAVEOUT* wwo, BOOL reset)
945 {
946     wodUpdatePlayedTotal(wwo);
947
948     wodPlayer_NotifyCompletions(wwo, FALSE); /* updates current notify list */
949
950     /* we aren't able to flush any data that has already been written */
951     /* to esd, otherwise we would do the flushing here */
952
953     if (reset) {
954         enum win_wm_message     msg;
955         DWORD                   param;
956         HANDLE                  ev;
957
958         /* remove any buffer */
959         wodPlayer_NotifyCompletions(wwo, TRUE);
960
961         wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL;
962         wwo->state = WINE_WS_STOPPED;
963         wwo->dwPlayedTotal = wwo->dwWrittenTotal = 0;
964
965         wwo->dwPartialOffset = 0;        /* Clear partial wavehdr */
966
967         /* remove any existing message in the ring */
968         EnterCriticalSection(&wwo->msgRing.msg_crst);
969
970         /* return all pending headers in queue */
971         while (ESD_RetrieveRingMessage(&wwo->msgRing, &msg, &param, &ev))
972         {
973             TRACE("flushing msg\n");
974             if (msg != WINE_WM_HEADER)
975             {
976                 FIXME("shouldn't have headers left\n");
977                 SetEvent(ev);
978                 continue;
979             }
980             ((LPWAVEHDR)param)->dwFlags &= ~WHDR_INQUEUE;
981             ((LPWAVEHDR)param)->dwFlags |= WHDR_DONE;
982
983             wodNotifyClient(wwo, WOM_DONE, param, 0);
984         }
985         RESET_OMR(&wwo->msgRing);
986         LeaveCriticalSection(&wwo->msgRing.msg_crst);
987     } else {
988         if (wwo->lpLoopPtr) {
989             /* complicated case, not handled yet (could imply modifying the loop counter */
990             FIXME("Pausing while in loop isn't correctly handled yet, except strange results\n");
991             wwo->lpPlayPtr = wwo->lpLoopPtr;
992             wwo->dwPartialOffset = 0;
993             wwo->dwWrittenTotal = wwo->dwPlayedTotal; /* this is wrong !!! */
994         } else {
995             /* the data already written is going to be played, so take */
996             /* this fact into account here */
997             wwo->dwPlayedTotal = wwo->dwWrittenTotal;
998         }
999         wwo->state = WINE_WS_PAUSED;
1000     }
1001 }
1002
1003 /**************************************************************************
1004  *                    wodPlayer_ProcessMessages                 [internal]
1005  */
1006 static void wodPlayer_ProcessMessages(WINE_WAVEOUT* wwo)
1007 {
1008     LPWAVEHDR           lpWaveHdr;
1009     enum win_wm_message msg;
1010     DWORD               param;
1011     HANDLE              ev;
1012
1013     while (ESD_RetrieveRingMessage(&wwo->msgRing, &msg, &param, &ev)) {
1014         TRACE("Received %s %x\n", wodPlayerCmdString[msg - WM_USER - 1], param);
1015         switch (msg) {
1016         case WINE_WM_PAUSING:
1017             wodPlayer_Reset(wwo, FALSE);
1018             SetEvent(ev);
1019             break;
1020         case WINE_WM_RESTARTING:
1021             wwo->state = WINE_WS_PLAYING;
1022             SetEvent(ev);
1023             break;
1024         case WINE_WM_HEADER:
1025             lpWaveHdr = (LPWAVEHDR)param;
1026
1027             /* insert buffer at the end of queue */
1028             {
1029                 LPWAVEHDR*      wh;
1030                 for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
1031                 *wh = lpWaveHdr;
1032             }
1033             if (!wwo->lpPlayPtr)
1034                 wodPlayer_BeginWaveHdr(wwo,lpWaveHdr);
1035             if (wwo->state == WINE_WS_STOPPED)
1036                 wwo->state = WINE_WS_PLAYING;
1037             break;
1038         case WINE_WM_RESETTING:
1039             wodPlayer_Reset(wwo, TRUE);
1040             SetEvent(ev);
1041             break;
1042         case WINE_WM_UPDATE:
1043             wodUpdatePlayedTotal(wwo);
1044             SetEvent(ev);
1045             break;
1046         case WINE_WM_BREAKLOOP:
1047             if (wwo->state == WINE_WS_PLAYING && wwo->lpLoopPtr != NULL) {
1048                 /* ensure exit at end of current loop */
1049                 wwo->dwLoops = 1;
1050             }
1051             SetEvent(ev);
1052             break;
1053         case WINE_WM_CLOSING:
1054             /* sanity check: this should not happen since the device must have been reset before */
1055             if (wwo->lpQueuePtr || wwo->lpPlayPtr) ERR("out of sync\n");
1056             wwo->hThread = 0;
1057             wwo->state = WINE_WS_CLOSED;
1058             SetEvent(ev);
1059             ExitThread(0);
1060             /* shouldn't go here */
1061         default:
1062             FIXME("unknown message %d\n", msg);
1063             break;
1064         }
1065     }
1066 }
1067
1068 /**************************************************************************
1069  *                           wodPlayer_FeedDSP                  [internal]
1070  * Feed as much sound data as we can into the DSP and return the number of
1071  * milliseconds before it will be necessary to feed the DSP again.
1072  */
1073 static DWORD wodPlayer_FeedDSP(WINE_WAVEOUT* wwo)
1074 {
1075     DWORD       availInQ;
1076
1077     wodUpdatePlayedTotal(wwo);
1078     /* better way to set availInQ? */
1079     availInQ = ESD_BUF_SIZE;
1080     TRACE("availInQ = %d\n", availInQ);
1081
1082     /* input queue empty */
1083     if (!wwo->lpPlayPtr) {
1084         TRACE("Run out of wavehdr:s... flushing\n");
1085         return INFINITE;
1086     }
1087
1088 #if 0
1089     /* no more room... no need to try to feed */
1090     if(!availInQ)
1091     {
1092         TRACE("no more room, no need to try to feed\n");
1093         return wwo->dwSleepTime;
1094     }
1095 #endif
1096
1097     /* Feed from partial wavehdr */
1098     if (wwo->lpPlayPtr && wwo->dwPartialOffset != 0)
1099     {
1100         TRACE("feeding from partial wavehdr\n");
1101         wodPlayer_WriteMaxFrags(wwo, &availInQ);
1102     }
1103
1104     /* Feed wavehdrs until we run out of wavehdrs or DSP space */
1105     if (!wwo->dwPartialOffset)
1106     {
1107         while(wwo->lpPlayPtr && availInQ)
1108         {
1109             TRACE("feeding waveheaders until we run out of space\n");
1110             /* note the value that dwPlayedTotal will return when this wave finishes playing */
1111             wwo->lpPlayPtr->reserved = wwo->dwWrittenTotal + wwo->lpPlayPtr->dwBufferLength;
1112             TRACE("reserved=(%d) dwWrittenTotal=(%d) dwBufferLength=(%d)\n",
1113                   wwo->lpPlayPtr->reserved,
1114                   wwo->dwWrittenTotal,
1115                   wwo->lpPlayPtr->dwBufferLength
1116                 );
1117             wodPlayer_WriteMaxFrags(wwo, &availInQ);
1118         }
1119     }
1120
1121     if (!wwo->lpPlayPtr) {
1122         TRACE("Ran out of wavehdrs\n");
1123         return INFINITE;
1124     }
1125
1126     return wwo->dwSleepTime;
1127 }
1128
1129
1130 /**************************************************************************
1131  *                              wodPlayer                       [internal]
1132  */
1133 static  DWORD   CALLBACK        wodPlayer(LPVOID pmt)
1134 {
1135     WORD          uDevID = (DWORD)pmt;
1136     WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)&WOutDev[uDevID];
1137     DWORD         dwNextFeedTime = INFINITE;   /* Time before DSP needs feeding */
1138     DWORD         dwNextNotifyTime = INFINITE; /* Time before next wave completion */
1139     DWORD         dwSleepTime;
1140
1141     wwo->state = WINE_WS_STOPPED;
1142     SetEvent(wwo->hStartUpEvent);
1143
1144     for (;;) {
1145         /** Wait for the shortest time before an action is required.  If there
1146          *  are no pending actions, wait forever for a command.
1147          */
1148         dwSleepTime = min(dwNextFeedTime, dwNextNotifyTime);
1149         TRACE("waiting %ums (%u,%u)\n", dwSleepTime, dwNextFeedTime, dwNextNotifyTime);
1150         WAIT_OMR(&wwo->msgRing, dwSleepTime);
1151         wodPlayer_ProcessMessages(wwo);
1152         if (wwo->state == WINE_WS_PLAYING) {
1153             dwNextFeedTime = wodPlayer_FeedDSP(wwo);
1154             dwNextNotifyTime = wodPlayer_NotifyCompletions(wwo, FALSE);
1155         } else {
1156             dwNextFeedTime = dwNextNotifyTime = INFINITE;
1157         }
1158     }
1159 }
1160
1161 /**************************************************************************
1162  *                      wodGetDevCaps                           [internal]
1163  */
1164 static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPSW lpCaps, DWORD dwSize)
1165 {
1166     TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize);
1167
1168     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1169
1170     if (wDevID >= MAX_WAVEOUTDRV) {
1171         TRACE("MAX_WAVOUTDRV reached !\n");
1172         return MMSYSERR_BADDEVICEID;
1173     }
1174
1175     memcpy(lpCaps, &WOutDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
1176     return MMSYSERR_NOERROR;
1177 }
1178
1179 /**************************************************************************
1180  *                              wodOpen                         [internal]
1181  */
1182 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1183 {
1184     WINE_WAVEOUT*       wwo;
1185     /* output to esound... */
1186     int                 out_bits = ESD_BITS8, out_channels = ESD_MONO, out_rate;
1187     int                 out_mode = ESD_STREAM, out_func = ESD_PLAY;
1188     esd_format_t        out_format;
1189
1190     TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags);
1191     if (lpDesc == NULL) {
1192         WARN("Invalid Parameter !\n");
1193         return MMSYSERR_INVALPARAM;
1194     }
1195     if (wDevID >= MAX_WAVEOUTDRV) {
1196         TRACE("MAX_WAVOUTDRV reached !\n");
1197         return MMSYSERR_BADDEVICEID;
1198     }
1199
1200     /* if this device is already open tell the app that it is allocated */
1201     if(WOutDev[wDevID].esd_fd != -1)
1202     {
1203       TRACE("device already allocated\n");
1204       return MMSYSERR_ALLOCATED;
1205     }
1206
1207     /* only PCM format is supported so far... */
1208     if (!supportedFormat(lpDesc->lpFormat)) {
1209         WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
1210              lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1211              lpDesc->lpFormat->nSamplesPerSec);
1212         return WAVERR_BADFORMAT;
1213     }
1214
1215     if (dwFlags & WAVE_FORMAT_QUERY) {
1216         TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
1217              lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1218              lpDesc->lpFormat->nSamplesPerSec);
1219         return MMSYSERR_NOERROR;
1220     }
1221
1222     wwo = &WOutDev[wDevID];
1223
1224     /* direct sound not supported, ignore the flag */
1225     dwFlags &= ~WAVE_DIRECTSOUND;
1226
1227     wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1228
1229     memcpy(&wwo->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1230     copy_format(lpDesc->lpFormat, &wwo->waveFormat);
1231
1232     if (wwo->waveFormat.Format.wBitsPerSample == 0) {
1233         WARN("Resetting zeroed wBitsPerSample\n");
1234         wwo->waveFormat.Format.wBitsPerSample = 8 *
1235             (wwo->waveFormat.Format.nAvgBytesPerSec /
1236              wwo->waveFormat.Format.nSamplesPerSec) /
1237             wwo->waveFormat.Format.nChannels;
1238     }
1239
1240     if (wwo->waveFormat.Format.wBitsPerSample == 8)
1241         out_bits = ESD_BITS8;
1242     else if (wwo->waveFormat.Format.wBitsPerSample == 16)
1243         out_bits = ESD_BITS16;
1244
1245     wwo->bytes_per_frame = (wwo->waveFormat.Format.wBitsPerSample * wwo->waveFormat.Format.nChannels) / 8;
1246
1247     if (wwo->waveFormat.Format.nChannels == 1)
1248         out_channels = ESD_MONO;
1249     else if (wwo->waveFormat.Format.nChannels == 2)
1250         out_channels = ESD_STEREO;
1251
1252     out_format = out_bits | out_channels | out_mode | out_func;
1253     out_rate = (int) wwo->waveFormat.Format.nSamplesPerSec;
1254         TRACE("esd output format = 0x%08x, rate = %d\n", out_format, out_rate);
1255
1256     wwo->esd_fd = esd_play_stream(out_format, out_rate, esd_host, "wineesd");
1257
1258     /* clear these so we don't have any confusion ;-) */
1259     wwo->sound_buffer = 0;
1260     wwo->buffer_size = 0;
1261
1262     if(wwo->esd_fd < 0) return MMSYSERR_ALLOCATED;
1263
1264     wwo->dwBufferSize = ESD_BUF_SIZE;
1265     TRACE("Buffer size is now (%d)\n",wwo->dwBufferSize);
1266
1267     wwo->dwPlayedTotal = 0;
1268     wwo->dwWrittenTotal = 0;
1269
1270     wwo->dwSleepTime = (1024 * 1000 * BUFFER_REFILL_THRESHOLD) / wwo->waveFormat.Format.nAvgBytesPerSec;
1271
1272     /* Initialize volume to full level */
1273     wwo->volume_left = 100;
1274     wwo->volume_right = 100;
1275
1276     ESD_InitRingMessage(&wwo->msgRing);
1277
1278     /* create player thread */
1279     if (!(dwFlags & WAVE_DIRECTSOUND)) {
1280         wwo->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1281         wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD)wDevID, 0, &(wwo->dwThreadID));
1282         WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
1283         CloseHandle(wwo->hStartUpEvent);
1284     } else {
1285         wwo->hThread = INVALID_HANDLE_VALUE;
1286         wwo->dwThreadID = 0;
1287     }
1288     wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
1289
1290     TRACE("esd=0x%lx, dwBufferSize=%d\n",
1291           (long)wwo->esd_fd, wwo->dwBufferSize);
1292
1293     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%u, nSamplesPerSec=%u, nChannels=%u nBlockAlign=%u!\n",
1294           wwo->waveFormat.Format.wBitsPerSample, wwo->waveFormat.Format.nAvgBytesPerSec,
1295           wwo->waveFormat.Format.nSamplesPerSec, wwo->waveFormat.Format.nChannels,
1296           wwo->waveFormat.Format.nBlockAlign);
1297
1298     return wodNotifyClient(wwo, WOM_OPEN, 0L, 0L);
1299 }
1300
1301 /**************************************************************************
1302  *                              wodClose                        [internal]
1303  */
1304 static DWORD wodClose(WORD wDevID)
1305 {
1306     DWORD               ret = MMSYSERR_NOERROR;
1307     WINE_WAVEOUT*       wwo;
1308
1309     TRACE("(%u);\n", wDevID);
1310
1311     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1312         WARN("bad device ID !\n");
1313         return MMSYSERR_BADDEVICEID;
1314     }
1315
1316     wwo = &WOutDev[wDevID];
1317     if (wwo->lpQueuePtr) {
1318         WARN("buffers still playing !\n");
1319         ret = WAVERR_STILLPLAYING;
1320     } else {
1321         TRACE("imhere[3-close]\n");
1322         if (wwo->hThread != INVALID_HANDLE_VALUE) {
1323             ESD_AddRingMessage(&wwo->msgRing, WINE_WM_CLOSING, 0, TRUE);
1324         }
1325
1326         ESD_DestroyRingMessage(&wwo->msgRing);
1327
1328         ESD_CloseWaveOutDevice(wwo);    /* close the stream and clean things up */
1329
1330         ret = wodNotifyClient(wwo, WOM_CLOSE, 0L, 0L);
1331     }
1332     return ret;
1333 }
1334
1335 /**************************************************************************
1336  *                              wodWrite                        [internal]
1337  *
1338  */
1339 static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1340 {
1341     TRACE("(%u, %p, %08X);\n", wDevID, lpWaveHdr, dwSize);
1342
1343     /* first, do the sanity checks... */
1344     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1345         WARN("bad dev ID !\n");
1346         return MMSYSERR_BADDEVICEID;
1347     }
1348
1349     if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED))
1350     {
1351         TRACE("unprepared\n");
1352         return WAVERR_UNPREPARED;
1353     }
1354
1355     if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
1356     {
1357         TRACE("still playing\n");
1358         return WAVERR_STILLPLAYING;
1359     }
1360
1361     lpWaveHdr->dwFlags &= ~WHDR_DONE;
1362     lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1363     lpWaveHdr->lpNext = 0;
1364
1365     TRACE("adding ring message\n");
1366     ESD_AddRingMessage(&WOutDev[wDevID].msgRing, WINE_WM_HEADER, (DWORD)lpWaveHdr, FALSE);
1367
1368     return MMSYSERR_NOERROR;
1369 }
1370
1371 /**************************************************************************
1372  *                      wodPause                                [internal]
1373  */
1374 static DWORD wodPause(WORD wDevID)
1375 {
1376     TRACE("(%u);!\n", wDevID);
1377
1378     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1379         WARN("bad device ID !\n");
1380         return MMSYSERR_BADDEVICEID;
1381     }
1382
1383     TRACE("imhere[3-PAUSING]\n");
1384     ESD_AddRingMessage(&WOutDev[wDevID].msgRing, WINE_WM_PAUSING, 0, TRUE);
1385
1386     return MMSYSERR_NOERROR;
1387 }
1388
1389 /**************************************************************************
1390  *                      wodRestart                              [internal]
1391  */
1392 static DWORD wodRestart(WORD wDevID)
1393 {
1394     TRACE("(%u);\n", wDevID);
1395
1396     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1397         WARN("bad device ID !\n");
1398         return MMSYSERR_BADDEVICEID;
1399     }
1400
1401     if (WOutDev[wDevID].state == WINE_WS_PAUSED) {
1402         TRACE("imhere[3-RESTARTING]\n");
1403         ESD_AddRingMessage(&WOutDev[wDevID].msgRing, WINE_WM_RESTARTING, 0, TRUE);
1404     }
1405
1406     /* FIXME: is NotifyClient with WOM_DONE right ? (Comet Busters 1.3.3 needs this notification) */
1407     /* FIXME: Myst crashes with this ... hmm -MM
1408        return wodNotifyClient(wwo, WOM_DONE, 0L, 0L);
1409     */
1410
1411     return MMSYSERR_NOERROR;
1412 }
1413
1414 /**************************************************************************
1415  *                      wodReset                                [internal]
1416  */
1417 static DWORD wodReset(WORD wDevID)
1418 {
1419     TRACE("(%u);\n", wDevID);
1420
1421     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1422         WARN("bad device ID !\n");
1423         return MMSYSERR_BADDEVICEID;
1424     }
1425
1426     TRACE("imhere[3-RESET]\n");
1427     ESD_AddRingMessage(&WOutDev[wDevID].msgRing, WINE_WM_RESETTING, 0, TRUE);
1428
1429     return MMSYSERR_NOERROR;
1430 }
1431
1432 /**************************************************************************
1433  *                              wodGetPosition                  [internal]
1434  */
1435 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1436 {
1437     WINE_WAVEOUT*       wwo;
1438
1439     TRACE("(%u, %p, %u);\n", wDevID, lpTime, uSize);
1440
1441     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1442         WARN("bad device ID !\n");
1443         return MMSYSERR_BADDEVICEID;
1444     }
1445
1446     if (lpTime == NULL) {
1447         WARN("invalid parameter: lpTime == NULL\n");
1448         return MMSYSERR_INVALPARAM;
1449     }
1450
1451     wwo = &WOutDev[wDevID];
1452     ESD_AddRingMessage(&wwo->msgRing, WINE_WM_UPDATE, 0, TRUE);
1453
1454     return bytes_to_mmtime(lpTime, wwo->dwPlayedTotal, &wwo->waveFormat);
1455 }
1456
1457 /**************************************************************************
1458  *                              wodBreakLoop                    [internal]
1459  */
1460 static DWORD wodBreakLoop(WORD wDevID)
1461 {
1462     TRACE("(%u);\n", wDevID);
1463
1464     if (wDevID >= MAX_WAVEOUTDRV || WOutDev[wDevID].esd_fd == -1) {
1465         WARN("bad device ID !\n");
1466         return MMSYSERR_BADDEVICEID;
1467     }
1468     ESD_AddRingMessage(&WOutDev[wDevID].msgRing, WINE_WM_BREAKLOOP, 0, TRUE);
1469     return MMSYSERR_NOERROR;
1470 }
1471
1472 /**************************************************************************
1473  *                              wodGetVolume                    [internal]
1474  */
1475 static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
1476 {
1477     DWORD left, right;
1478
1479     left = WOutDev[wDevID].volume_left;
1480     right = WOutDev[wDevID].volume_right;
1481
1482     TRACE("(%u, %p);\n", wDevID, lpdwVol);
1483
1484     *lpdwVol = ((left * 0xFFFFl) / 100) + (((right * 0xFFFFl) / 100) <<
1485                 16);
1486
1487     return MMSYSERR_NOERROR;
1488 }
1489
1490 /**************************************************************************
1491  *                              wodSetVolume                    [internal]
1492  */
1493 static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1494 {
1495     DWORD left, right;
1496
1497     left  = (LOWORD(dwParam) * 100) / 0xFFFFl;
1498     right = (HIWORD(dwParam) * 100) / 0xFFFFl;
1499
1500     TRACE("(%u, %08X);\n", wDevID, dwParam);
1501
1502     WOutDev[wDevID].volume_left = left;
1503     WOutDev[wDevID].volume_right = right;
1504
1505     return MMSYSERR_NOERROR;
1506 }
1507
1508 /**************************************************************************
1509  *                              wodGetNumDevs                   [internal]
1510  */
1511 static  DWORD   wodGetNumDevs(void)
1512 {
1513     return MAX_WAVEOUTDRV;
1514 }
1515
1516 /**************************************************************************
1517  *                              wodDevInterfaceSize             [internal]
1518  */
1519 static DWORD wodDevInterfaceSize(UINT wDevID, LPDWORD dwParam1)
1520 {
1521     TRACE("(%u, %p)\n", wDevID, dwParam1);
1522  
1523     *dwParam1 = MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
1524                                     NULL, 0 ) * sizeof(WCHAR);
1525     return MMSYSERR_NOERROR;
1526 }
1527  
1528 /**************************************************************************
1529  *                              wodDevInterface                 [internal]
1530  */
1531 static DWORD wodDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2)
1532 {
1533     if (dwParam2 >= MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
1534                                         NULL, 0 ) * sizeof(WCHAR))
1535     {
1536         MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1,
1537                             dwParam1, dwParam2 / sizeof(WCHAR));
1538         return MMSYSERR_NOERROR;
1539     }
1540     return MMSYSERR_INVALPARAM;
1541 }
1542  
1543 /**************************************************************************
1544  *                              wodMessage (WINEESD.@)
1545  */
1546 DWORD WINAPI ESD_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
1547                             DWORD dwParam1, DWORD dwParam2)
1548 {
1549     TRACE("(%u, %04X, %08X, %08X, %08X);\n",
1550           wDevID, wMsg, dwUser, dwParam1, dwParam2);
1551
1552     switch (wMsg) {
1553     case DRVM_INIT:
1554     case DRVM_EXIT:
1555     case DRVM_ENABLE:
1556     case DRVM_DISABLE:
1557         /* FIXME: Pretend this is supported */
1558         return 0;
1559     case WODM_OPEN:             return wodOpen          (wDevID, (LPWAVEOPENDESC)dwParam1,      dwParam2);
1560     case WODM_CLOSE:            return wodClose         (wDevID);
1561     case WODM_WRITE:            return wodWrite         (wDevID, (LPWAVEHDR)dwParam1,           dwParam2);
1562     case WODM_PAUSE:            return wodPause         (wDevID);
1563     case WODM_GETPOS:           return wodGetPosition   (wDevID, (LPMMTIME)dwParam1,            dwParam2);
1564     case WODM_BREAKLOOP:        return wodBreakLoop     (wDevID);
1565     case WODM_PREPARE:          return MMSYSERR_NOTSUPPORTED;
1566     case WODM_UNPREPARE:        return MMSYSERR_NOTSUPPORTED;
1567     case WODM_GETDEVCAPS:       return wodGetDevCaps    (wDevID, (LPWAVEOUTCAPSW)dwParam1,      dwParam2);
1568     case WODM_GETNUMDEVS:       return wodGetNumDevs    ();
1569     case WODM_GETPITCH:         return MMSYSERR_NOTSUPPORTED;
1570     case WODM_SETPITCH:         return MMSYSERR_NOTSUPPORTED;
1571     case WODM_GETPLAYBACKRATE:  return MMSYSERR_NOTSUPPORTED;
1572     case WODM_SETPLAYBACKRATE:  return MMSYSERR_NOTSUPPORTED;
1573     case WODM_GETVOLUME:        return wodGetVolume     (wDevID, (LPDWORD)dwParam1);
1574     case WODM_SETVOLUME:        return wodSetVolume     (wDevID, dwParam1);
1575     case WODM_RESTART:          return wodRestart       (wDevID);
1576     case WODM_RESET:            return wodReset         (wDevID);
1577
1578     case DRV_QUERYDEVICEINTERFACESIZE: return wodDevInterfaceSize       (wDevID, (LPDWORD)dwParam1);
1579     case DRV_QUERYDEVICEINTERFACE:     return wodDevInterface           (wDevID, (PWCHAR)dwParam1, dwParam2);
1580     case DRV_QUERYDSOUNDIFACE:  return wodDsCreate      (wDevID, (PIDSDRIVER*)dwParam1);
1581     case DRV_QUERYDSOUNDDESC:   return wodDsDesc        (wDevID, (PDSDRIVERDESC)dwParam1);
1582     default:
1583         FIXME("unknown message %d!\n", wMsg);
1584     }
1585     return MMSYSERR_NOTSUPPORTED;
1586 }
1587
1588 /*======================================================================*
1589  *                  Low level WAVE IN implementation                    *
1590  *======================================================================*/
1591
1592 /**************************************************************************
1593  *                              widGetNumDevs                   [internal]
1594  */
1595 static  DWORD   widGetNumDevs(void)
1596 {
1597     TRACE("%d\n", MAX_WAVEINDRV);
1598     return MAX_WAVEINDRV;
1599 }
1600
1601 /**************************************************************************
1602  *                              widDevInterfaceSize             [internal]
1603  */
1604 static DWORD widDevInterfaceSize(UINT wDevID, LPDWORD dwParam1)
1605 {
1606     TRACE("(%u, %p)\n", wDevID, dwParam1);
1607  
1608  
1609     *dwParam1 = MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
1610                                     NULL, 0 ) * sizeof(WCHAR);
1611     return MMSYSERR_NOERROR;
1612 }
1613
1614 /**************************************************************************
1615  *                              widDevInterface                 [internal]
1616  */
1617 static DWORD widDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2)
1618 {
1619     if (dwParam2 >= MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
1620                                         NULL, 0 ) * sizeof(WCHAR))
1621     {
1622         MultiByteToWideChar(CP_ACP, 0, WInDev[wDevID].interface_name, -1,
1623                             dwParam1, dwParam2 / sizeof(WCHAR));
1624         return MMSYSERR_NOERROR;
1625     }
1626     return MMSYSERR_INVALPARAM;
1627 }
1628
1629 /**************************************************************************
1630  *                      widNotifyClient                 [internal]
1631  */
1632 static DWORD widNotifyClient(WINE_WAVEIN* wwi, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
1633 {
1634     TRACE("wMsg = 0x%04x dwParm1 = %04X dwParam2 = %04X\n", wMsg, dwParam1, dwParam2);
1635
1636     switch (wMsg) {
1637     case WIM_OPEN:
1638     case WIM_CLOSE:
1639     case WIM_DATA:
1640         if (wwi->wFlags != DCB_NULL &&
1641             !DriverCallback(wwi->waveDesc.dwCallback, wwi->wFlags,
1642                             (HDRVR)wwi->waveDesc.hWave, wMsg,
1643                             wwi->waveDesc.dwInstance, dwParam1, dwParam2)) {
1644             WARN("can't notify client !\n");
1645             return MMSYSERR_ERROR;
1646         }
1647         break;
1648     default:
1649         FIXME("Unknown callback message %u\n", wMsg);
1650         return MMSYSERR_INVALPARAM;
1651     }
1652     return MMSYSERR_NOERROR;
1653 }
1654
1655 /**************************************************************************
1656  *                      widGetDevCaps                           [internal]
1657  */
1658 static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSW lpCaps, DWORD dwSize)
1659 {
1660     TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize);
1661
1662     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1663
1664     if (wDevID >= MAX_WAVEINDRV) {
1665         TRACE("MAX_WAVINDRV reached !\n");
1666         return MMSYSERR_BADDEVICEID;
1667     }
1668
1669     memcpy(lpCaps, &WInDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
1670     return MMSYSERR_NOERROR;
1671 }
1672
1673 /**************************************************************************
1674  *                              widRecorder                     [internal]
1675  */
1676 static  DWORD   CALLBACK        widRecorder(LPVOID pmt)
1677 {
1678     WORD                uDevID = (DWORD)pmt;
1679     WINE_WAVEIN*        wwi = (WINE_WAVEIN*)&WInDev[uDevID];
1680     WAVEHDR*            lpWaveHdr;
1681     DWORD               dwSleepTime;
1682     DWORD               bytesRead;
1683     enum win_wm_message msg;
1684     DWORD               param;
1685     HANDLE              ev;
1686
1687     SetEvent(wwi->hStartUpEvent);
1688
1689     /* make sleep time to be # of ms to record one packet */
1690     dwSleepTime = (1024 * 1000) / wwi->waveFormat.Format.nAvgBytesPerSec;
1691     TRACE("sleeptime=%d ms\n", dwSleepTime);
1692
1693     for(;;) {
1694         TRACE("wwi->lpQueuePtr=(%p), wwi->state=(%d)\n",wwi->lpQueuePtr,wwi->state);
1695
1696         /* read all data is esd input buffer. */
1697         if ((wwi->lpQueuePtr != NULL) && (wwi->state == WINE_WS_PLAYING))
1698         {
1699             lpWaveHdr = wwi->lpQueuePtr;
1700  
1701             TRACE("read as much as we can\n");
1702             while(wwi->lpQueuePtr)
1703             {
1704                 TRACE("attempt to read %d bytes\n",lpWaveHdr->dwBufferLength - lpWaveHdr->dwBytesRecorded);
1705                 bytesRead = read(wwi->esd_fd,
1706                               lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded,
1707                               lpWaveHdr->dwBufferLength - lpWaveHdr->dwBytesRecorded);
1708                 TRACE("bytesRead=%d\n",bytesRead);
1709                 if (bytesRead == -1 && errno == EAGAIN)
1710                         bytesRead = 0;
1711                 if (bytesRead==0) break; /* So we can stop recording smoothly */
1712                 if (bytesRead < 0)
1713                         bytesRead = 0;
1714  
1715                 lpWaveHdr->dwBytesRecorded      += bytesRead;
1716                 wwi->dwRecordedTotal            += bytesRead;
1717
1718                 /* buffer full. notify client */
1719                 if (lpWaveHdr->dwBytesRecorded >= lpWaveHdr->dwBufferLength)
1720                 {
1721                     /* must copy the value of next waveHdr, because we have no idea of what
1722                      * will be done with the content of lpWaveHdr in callback
1723                      */
1724                     LPWAVEHDR   lpNext = lpWaveHdr->lpNext;
1725
1726                     TRACE("waveHdr full.\n");
1727  
1728                     lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1729                     lpWaveHdr->dwFlags |=  WHDR_DONE;
1730  
1731                     widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
1732                     lpWaveHdr = wwi->lpQueuePtr = lpNext;
1733                 }
1734             }
1735         }
1736
1737         /* wait for dwSleepTime or an event in thread's queue */
1738         WAIT_OMR(&wwi->msgRing, dwSleepTime);
1739
1740         while (ESD_RetrieveRingMessage(&wwi->msgRing, &msg, &param, &ev))
1741         {
1742             TRACE("msg=%s param=0x%x\n",wodPlayerCmdString[msg - WM_USER - 1], param);
1743             switch(msg) {
1744             case WINE_WM_PAUSING:
1745                 wwi->state = WINE_WS_PAUSED;
1746
1747                 /* Put code here to "pause" esd recording
1748                  */
1749
1750                 SetEvent(ev);
1751                 break;
1752             case WINE_WM_STARTING:
1753                 wwi->state = WINE_WS_PLAYING;
1754
1755                 /* Put code here to "start" esd recording
1756                  */
1757
1758                 SetEvent(ev);
1759                 break;
1760             case WINE_WM_HEADER:
1761                 lpWaveHdr = (LPWAVEHDR)param;
1762                 /* insert buffer at end of queue */
1763                 {
1764                     LPWAVEHDR* wh;
1765                     int num_headers = 0;
1766                     for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext))
1767                     {
1768                         num_headers++;
1769
1770                     }
1771                     *wh=lpWaveHdr;
1772                 }
1773                 break;
1774             case WINE_WM_STOPPING:
1775                 if (wwi->state != WINE_WS_STOPPED)
1776                 {
1777
1778                     /* Put code here to "stop" esd recording
1779                      */
1780
1781                     /* return current buffer to app */
1782                     lpWaveHdr = wwi->lpQueuePtr;
1783                     if (lpWaveHdr)
1784                     {
1785                         LPWAVEHDR lpNext = lpWaveHdr->lpNext;
1786                         TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
1787                         lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1788                         lpWaveHdr->dwFlags |= WHDR_DONE;
1789                         widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
1790                         wwi->lpQueuePtr = lpNext;
1791                     }
1792                 }
1793                 wwi->state = WINE_WS_STOPPED;
1794                 SetEvent(ev);
1795                 break;
1796             case WINE_WM_RESETTING:
1797                 wwi->state = WINE_WS_STOPPED;
1798                 wwi->dwRecordedTotal = 0;
1799
1800                 /* return all buffers to the app */
1801                 for (lpWaveHdr = wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) {
1802                     TRACE("reset %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
1803                     lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1804                     lpWaveHdr->dwFlags |= WHDR_DONE;
1805
1806                     widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
1807                 }
1808                 wwi->lpQueuePtr = NULL; 
1809                 SetEvent(ev);
1810                 break;
1811             case WINE_WM_CLOSING:
1812                 wwi->hThread = 0;
1813                 wwi->state = WINE_WS_CLOSED;
1814                 SetEvent(ev);
1815                 ExitThread(0);
1816                 /* shouldn't go here */
1817             default:
1818                 FIXME("unknown message %d\n", msg);
1819                 break;
1820             }
1821         }
1822     }
1823     ExitThread(0);
1824     /* just for not generating compilation warnings... should never be executed */
1825     return 0;
1826 }
1827
1828 /**************************************************************************
1829  *                              widOpen                         [internal]
1830  */
1831 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1832 {
1833     WINE_WAVEIN*        wwi;
1834     /* input esound... */
1835     int                 in_bits = ESD_BITS16, in_channels = ESD_STEREO, in_rate;
1836 #ifdef WID_USE_ESDMON
1837     int                 in_mode = ESD_STREAM, in_func = ESD_PLAY;
1838 #else
1839     int                 in_mode = ESD_STREAM, in_func = ESD_RECORD;
1840 #endif
1841     esd_format_t        in_format;
1842     int                 mode;
1843
1844     TRACE("(%u, %p %08X);\n",wDevID, lpDesc, dwFlags);
1845     if (lpDesc == NULL) {
1846         WARN("Invalid Parametr (lpDesc == NULL)!\n");
1847         return MMSYSERR_INVALPARAM;
1848     }
1849
1850     if (wDevID >= MAX_WAVEINDRV) {
1851         TRACE ("MAX_WAVEINDRV reached !\n");
1852         return MMSYSERR_BADDEVICEID;
1853     }
1854
1855     /* if this device is already open tell the app that it is allocated */
1856     if(WInDev[wDevID].esd_fd != -1)
1857     {
1858         TRACE("device already allocated\n");
1859         return MMSYSERR_ALLOCATED;
1860     }
1861
1862     /* only PCM format is support so far... */
1863     if (!supportedFormat(lpDesc->lpFormat)) {
1864         WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
1865              lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1866              lpDesc->lpFormat->nSamplesPerSec);
1867         return WAVERR_BADFORMAT;
1868     }
1869
1870     if (dwFlags & WAVE_FORMAT_QUERY) {
1871         TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n",
1872              lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1873              lpDesc->lpFormat->nSamplesPerSec);
1874         return MMSYSERR_NOERROR;
1875     }
1876
1877     wwi = &WInDev[wDevID];
1878
1879     /* direct sound not supported, ignore the flag */
1880     dwFlags &= ~WAVE_DIRECTSOUND;
1881
1882     wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1883  
1884     memcpy(&wwi->waveDesc, lpDesc, sizeof(WAVEOPENDESC));
1885     copy_format(lpDesc->lpFormat, &wwi->waveFormat);
1886
1887     if (wwi->waveFormat.Format.wBitsPerSample == 0) {
1888         WARN("Resetting zerod wBitsPerSample\n");
1889         wwi->waveFormat.Format.wBitsPerSample = 8 *
1890             (wwi->waveFormat.Format.nAvgBytesPerSec /
1891              wwi->waveFormat.Format.nSamplesPerSec) /
1892             wwi->waveFormat.Format.nChannels;
1893     }
1894
1895     if (wwi->waveFormat.Format.wBitsPerSample == 8)
1896         in_bits = ESD_BITS8;
1897     else if (wwi->waveFormat.Format.wBitsPerSample == 16)
1898         in_bits = ESD_BITS16;
1899
1900     wwi->bytes_per_frame = (wwi->waveFormat.Format.wBitsPerSample * wwi->waveFormat.Format.nChannels) / 8;
1901
1902     if (wwi->waveFormat.Format.nChannels == 1)
1903         in_channels = ESD_MONO;
1904     else if (wwi->waveFormat.Format.nChannels == 2)
1905         in_channels = ESD_STEREO;
1906
1907     in_format = in_bits | in_channels | in_mode | in_func;
1908     in_rate = (int) wwi->waveFormat.Format.nSamplesPerSec;
1909         TRACE("esd input format = 0x%08x, rate = %d\n", in_format, in_rate);
1910
1911 #ifdef WID_USE_ESDMON
1912     wwi->esd_fd = esd_monitor_stream(in_format, in_rate, esd_host, "wineesd");
1913 #else
1914     wwi->esd_fd = esd_record_stream(in_format, in_rate, esd_host, "wineesd");
1915 #endif
1916     TRACE("(wwi->esd_fd=%d)\n",wwi->esd_fd);
1917     wwi->state = WINE_WS_STOPPED;
1918
1919     if (wwi->lpQueuePtr) {
1920         WARN("Should have an empty queue (%p)\n", wwi->lpQueuePtr);
1921         wwi->lpQueuePtr = NULL;
1922     }
1923
1924     if(wwi->esd_fd < 0) return MMSYSERR_ALLOCATED;
1925
1926     /* Set the esd socket O_NONBLOCK, so we can stop recording smoothly */
1927     mode = fcntl(wwi->esd_fd, F_GETFL);
1928     mode |= O_NONBLOCK;
1929     fcntl(wwi->esd_fd, F_SETFL, mode);
1930
1931     wwi->dwRecordedTotal = 0;
1932     wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1933
1934     ESD_InitRingMessage(&wwi->msgRing);
1935
1936     /* create recorder thread */
1937     if (!(dwFlags & WAVE_DIRECTSOUND)) {
1938         wwi->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1939         wwi->hThread = CreateThread(NULL, 0, widRecorder, (LPVOID)(DWORD)wDevID, 0, &(wwi->dwThreadID));
1940         WaitForSingleObject(wwi->hStartUpEvent, INFINITE);
1941         CloseHandle(wwi->hStartUpEvent);
1942     } else {
1943         wwi->hThread = INVALID_HANDLE_VALUE;
1944         wwi->dwThreadID = 0;
1945     }
1946     wwi->hStartUpEvent = INVALID_HANDLE_VALUE;
1947
1948     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%u, nSamplesPerSec=%u, nChannels=%u nBlockAlign=%u!\n",
1949           wwi->waveFormat.Format.wBitsPerSample, wwi->waveFormat.Format.nAvgBytesPerSec,
1950           wwi->waveFormat.Format.nSamplesPerSec, wwi->waveFormat.Format.nChannels,
1951           wwi->waveFormat.Format.nBlockAlign);
1952     return widNotifyClient(wwi, WIM_OPEN, 0L, 0L);
1953 }
1954
1955 /**************************************************************************
1956  *                              widClose                        [internal]
1957  */
1958 static DWORD widClose(WORD wDevID)
1959 {
1960     WINE_WAVEIN*        wwi;
1961
1962     TRACE("(%u);\n", wDevID);
1963     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
1964         WARN("can't close !\n");
1965         return MMSYSERR_INVALHANDLE;
1966     }
1967
1968     wwi = &WInDev[wDevID];
1969
1970     if (wwi->lpQueuePtr != NULL) {
1971         WARN("still buffers open !\n");
1972         return WAVERR_STILLPLAYING;
1973     }
1974
1975     ESD_AddRingMessage(&wwi->msgRing, WINE_WM_CLOSING, 0, TRUE);
1976     ESD_CloseWaveInDevice(wwi);
1977     wwi->state = WINE_WS_CLOSED;
1978     ESD_DestroyRingMessage(&wwi->msgRing);
1979     return widNotifyClient(wwi, WIM_CLOSE, 0L, 0L);
1980 }
1981
1982 /**************************************************************************
1983  *                              widAddBuffer            [internal]
1984  */
1985 static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1986 {
1987     TRACE("(%u, %p, %08X);\n", wDevID, lpWaveHdr, dwSize);
1988
1989     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
1990         WARN("can't do it !\n");
1991         return MMSYSERR_INVALHANDLE;
1992     }
1993     if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
1994         TRACE("never been prepared !\n");
1995         return WAVERR_UNPREPARED;
1996     }
1997     if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
1998         TRACE("header already in use !\n");
1999         return WAVERR_STILLPLAYING;
2000     }
2001
2002     lpWaveHdr->dwFlags |= WHDR_INQUEUE;
2003     lpWaveHdr->dwFlags &= ~WHDR_DONE;
2004     lpWaveHdr->dwBytesRecorded = 0;
2005     lpWaveHdr->lpNext = NULL;
2006
2007     ESD_AddRingMessage(&WInDev[wDevID].msgRing, WINE_WM_HEADER, (DWORD)lpWaveHdr, FALSE);
2008     return MMSYSERR_NOERROR;
2009 }
2010
2011 /**************************************************************************
2012  *                      widStart                                [internal]
2013  */
2014 static DWORD widStart(WORD wDevID)
2015 {
2016     TRACE("(%u);\n", wDevID);
2017     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2018         WARN("can't start recording !\n");
2019         return MMSYSERR_INVALHANDLE;
2020     }
2021
2022     ESD_AddRingMessage(&WInDev[wDevID].msgRing, WINE_WM_STARTING, 0, TRUE);
2023     return MMSYSERR_NOERROR;
2024 }
2025
2026 /**************************************************************************
2027  *                      widStop                                 [internal]
2028  */
2029 static DWORD widStop(WORD wDevID)
2030 {
2031     TRACE("(%u);\n", wDevID);
2032     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2033         WARN("can't stop !\n");
2034         return MMSYSERR_INVALHANDLE;
2035     }
2036
2037     ESD_AddRingMessage(&WInDev[wDevID].msgRing, WINE_WM_STOPPING, 0, TRUE);
2038
2039     return MMSYSERR_NOERROR;
2040 }
2041
2042 /**************************************************************************
2043  *                      widReset                                [internal]
2044  */
2045 static DWORD widReset(WORD wDevID)
2046 {
2047     TRACE("(%u);\n", wDevID);
2048     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2049         WARN("can't reset !\n");
2050         return MMSYSERR_INVALHANDLE;
2051     }
2052     ESD_AddRingMessage(&WInDev[wDevID].msgRing, WINE_WM_RESETTING, 0, TRUE);
2053     return MMSYSERR_NOERROR;
2054 }
2055
2056 /**************************************************************************
2057  *                              widMessage (WINEESD.6)
2058  */
2059 DWORD WINAPI ESD_widMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
2060                             DWORD dwParam1, DWORD dwParam2)
2061 {
2062     TRACE("(%u, %04X, %08X, %08X, %08X);\n",
2063           wDevID, wMsg, dwUser, dwParam1, dwParam2);
2064     switch (wMsg) {
2065     case DRVM_INIT:
2066     case DRVM_EXIT:
2067     case DRVM_ENABLE:
2068     case DRVM_DISABLE:
2069         /* FIXME: Pretend this is supported */
2070         return 0;
2071     case WIDM_OPEN:             return widOpen          (wDevID, (LPWAVEOPENDESC)dwParam1,      dwParam2);
2072     case WIDM_CLOSE:            return widClose         (wDevID);
2073     case WIDM_ADDBUFFER:        return widAddBuffer     (wDevID, (LPWAVEHDR)dwParam1, dwParam2);
2074     case WIDM_PREPARE:          return MMSYSERR_NOTSUPPORTED;
2075     case WIDM_UNPREPARE:        return MMSYSERR_NOTSUPPORTED;
2076     case WIDM_GETDEVCAPS:       return widGetDevCaps    (wDevID, (LPWAVEINCAPSW)dwParam1,       dwParam2);
2077     case WIDM_GETNUMDEVS:       return widGetNumDevs    ();
2078     case WIDM_RESET:            return widReset         (wDevID);
2079     case WIDM_START:            return widStart         (wDevID);
2080     case WIDM_STOP:             return widStop          (wDevID);
2081     case DRV_QUERYDEVICEINTERFACESIZE: return widDevInterfaceSize       (wDevID, (LPDWORD)dwParam1);
2082     case DRV_QUERYDEVICEINTERFACE:     return widDevInterface           (wDevID, (PWCHAR)dwParam1, dwParam2);
2083     default:
2084         FIXME("unknown message %d!\n", wMsg);
2085     }
2086     return MMSYSERR_NOTSUPPORTED;
2087 }
2088
2089 /*======================================================================*
2090  *                  Low level DSOUND implementation                     *
2091  *======================================================================*/
2092 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
2093 {
2094     /* we can't perform memory mapping as we don't have a file stream
2095         interface with esd like we do with oss */
2096     MESSAGE("This sound card's driver does not support direct access\n");
2097     MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
2098     return MMSYSERR_NOTSUPPORTED;
2099 }
2100
2101 static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
2102 {
2103     memset(desc, 0, sizeof(*desc));
2104     strcpy(desc->szDesc, "Wine EsounD DirectSound Driver");
2105     strcpy(desc->szDrvname, "wineesd.drv");
2106     return MMSYSERR_NOERROR;
2107 }
2108
2109 #else /* !HAVE_ESD */
2110
2111 /**************************************************************************
2112  *                              wodMessage (WINEESD.@)
2113  */
2114 DWORD WINAPI ESD_wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
2115                             DWORD dwParam1, DWORD dwParam2)
2116 {
2117     FIXME("(%u, %04X, %08X, %08X, %08X):stub\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
2118     return MMSYSERR_NOTENABLED;
2119 }
2120
2121 /**************************************************************************
2122  *                              widMessage (WINEESD.6)
2123  */
2124 DWORD WINAPI ESD_widMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
2125                             DWORD dwParam1, DWORD dwParam2)
2126 {
2127     FIXME("(%u, %04X, %08X, %08X, %08X):stub\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
2128     return MMSYSERR_NOTENABLED;
2129 }
2130
2131 #endif /* HAVE_ESD */