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