winejack.drv only supports 16bit sound so we can simplify the sound
[wine] / dlls / winmm / winejack / audio.c
1 /* -*- tab-width: 8; c-basic-offset: 2 -*- */
2 /*
3  * Wine Driver for jack Sound Server
4  *   http://jackit.sourceforge.net
5  *
6  * Copyright 1994 Martin Ayotte
7  * Copyright 1999 Eric Pouech (async playing in waveOut/waveIn)
8  * Copyright 2000 Eric Pouech (loops in waveOut)
9  * Copyright 2002 Chris Morgan (jack version of this file)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 /*
27  * TODO:
28  *  implement audio stream resampling for any arbitrary frequenty
29  *    right now we use the winmm layer to do resampling although it would 
30  *    be nice to have a full set of algorithms to choose from based on cpu 
31  *    time
32  *
33  * FIXME:
34  *  pause in waveOut during loop is not handled correctly
35  */
36
37 #include "config.h"
38
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 #include "windef.h"
48 #include "winbase.h"
49 #include "wingdi.h"
50 #include "winerror.h"
51 #include "wine/winuser16.h"
52 #include "mmddk.h"
53 #include "dsound.h"
54 #include "dsdriver.h"
55 #include "jack.h"
56 #include "wine/debug.h"
57
58 #ifdef HAVE_JACK_JACK_H
59 #include <jack/jack.h>
60 #endif
61
62
63 WINE_DEFAULT_DEBUG_CHANNEL(wave);
64
65 #ifdef HAVE_JACK_JACK_H
66
67 #define MAKE_FUNCPTR(f) static typeof(f) * fp_##f = NULL;
68
69 /* Function pointers for dynamic loading of libjack */
70 /* these are prefixed with "fp_", ie. "fp_jack_client_new" */
71 MAKE_FUNCPTR(jack_activate);
72 MAKE_FUNCPTR(jack_connect);
73 MAKE_FUNCPTR(jack_client_new);
74 MAKE_FUNCPTR(jack_client_close);
75 MAKE_FUNCPTR(jack_deactivate);
76 MAKE_FUNCPTR(jack_set_process_callback);
77 MAKE_FUNCPTR(jack_set_buffer_size_callback);
78 MAKE_FUNCPTR(jack_set_sample_rate_callback);
79 MAKE_FUNCPTR(jack_on_shutdown);
80 MAKE_FUNCPTR(jack_get_sample_rate);
81 MAKE_FUNCPTR(jack_port_register);
82 MAKE_FUNCPTR(jack_port_get_buffer);
83 MAKE_FUNCPTR(jack_get_ports);
84 MAKE_FUNCPTR(jack_port_name);
85 MAKE_FUNCPTR(jack_get_buffer_size);
86 #undef MAKE_FUNCPTR
87
88 /* define the below to work around a bug in jack where closing a port */
89 /* takes a very long time, so to get around this we actually don't */
90 /* close the port when the device is closed but instead mark the */
91 /* corresponding device as unused */
92 #define JACK_CLOSE_HACK    1
93
94 typedef jack_default_audio_sample_t sample_t;
95 typedef jack_nframes_t nframes_t;
96
97 /* only allow 10 output devices through this driver, this ought to be adequate */
98 #define MAX_WAVEOUTDRV  (10)
99 #define MAX_WAVEINDRV   (10)
100
101 /* state diagram for waveOut writing:
102  *
103  * +---------+-------------+---------------+---------------------------------+
104  * |  state  |  function   |     event     |            new state            |
105  * +---------+-------------+---------------+---------------------------------+
106  * |         | open()      |               | STOPPED                         |
107  * | PAUSED  | write()     |               | PAUSED                          |
108  * | STOPPED | write()     | <thrd create> | PLAYING                         |
109  * | PLAYING | write()     | HEADER        | PLAYING                         |
110  * | (other) | write()     | <error>       |                                 |
111  * | (any)   | pause()     | PAUSING       | PAUSED                          |
112  * | PAUSED  | restart()   | RESTARTING    | PLAYING (if no thrd => STOPPED) |
113  * | (any)   | reset()     | RESETTING     | STOPPED                         |
114  * | (any)   | close()     | CLOSING       | CLOSED                          |
115  * +---------+-------------+---------------+---------------------------------+
116  */
117
118 /* states of the playing device */
119 #define WINE_WS_PLAYING   0
120 #define WINE_WS_PAUSED    1
121 #define WINE_WS_STOPPED   2
122 #define WINE_WS_CLOSED    3
123
124 typedef struct {
125     volatile int      state;      /* one of the WINE_WS_ manifest constants */
126     WAVEOPENDESC      waveDesc;
127     WORD              wFlags;
128     PCMWAVEFORMAT     format;
129     WAVEOUTCAPSA      caps;
130     WORD              wDevID;
131
132     jack_port_t*      out_port_l;   /* ports for left and right channels */
133     jack_port_t*      out_port_r;
134     jack_client_t*    client;
135     long              sample_rate;        /* jack server sample rate */
136
137 #if JACK_CLOSE_HACK
138     BOOL              in_use; /* TRUE if this device is in use */
139 #endif
140
141     char*             sound_buffer;
142     unsigned long     buffer_size;
143
144     DWORD             volume_left;
145     DWORD             volume_right;
146
147     LPWAVEHDR         lpQueuePtr;   /* start of queued WAVEHDRs (waiting to be notified) */
148     LPWAVEHDR         lpPlayPtr;    /* start of not yet fully played buffers */
149     DWORD             dwPartialOffset;  /* Offset of not yet written bytes in lpPlayPtr */
150
151     LPWAVEHDR         lpLoopPtr;    /* pointer of first buffer in loop, if any */
152     DWORD             dwLoops;      /* private copy of loop counter */
153     
154     DWORD             dwPlayedTotal;    /* number of bytes actually played since opening */
155     DWORD             dwWrittenTotal;   /* number of bytes written to jack since opening */
156
157     DWORD             bytesInJack; /* bytes that we wrote during the previous JACK_Callback() */
158     DWORD             tickCountMS; /* time in MS of last JACK_Callback() */
159
160     /* synchronization stuff */
161     CRITICAL_SECTION    access_crst;
162 } WINE_WAVEOUT;
163
164 typedef struct {
165     volatile int    state;
166     WAVEOPENDESC    waveDesc;
167     WORD            wFlags;
168     PCMWAVEFORMAT   format;
169     LPWAVEHDR       lpQueuePtr;
170     DWORD           dwTotalRecorded;
171     WAVEINCAPSA     caps;
172     BOOL            bTriggerSupport;
173     WORD              wDevID;
174
175     jack_port_t*      in_port_l;   /* ports for left and right channels */
176     jack_port_t*      in_port_r;
177     jack_client_t*    client;
178     long              sample_rate;        /* jack server sample rate */
179
180 #if JACK_CLOSE_HACK
181     BOOL              in_use; /* TRUE if this device is in use */
182 #endif
183
184     char*             sound_buffer;
185     unsigned long     buffer_size;
186
187     /* synchronization stuff */
188     CRITICAL_SECTION    access_crst;
189 } WINE_WAVEIN;
190
191 static WINE_WAVEOUT WOutDev   [MAX_WAVEOUTDRV];
192 static WINE_WAVEIN  WInDev    [MAX_WAVEINDRV ];
193
194 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
195 static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);
196 static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid);
197
198 static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo);
199 static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force);
200
201 static int JACK_OpenWaveOutDevice(WINE_WAVEOUT* wwo);
202 static int JACK_OpenWaveInDevice(WINE_WAVEIN* wwi, WORD nChannels);
203
204 #if JACK_CLOSE_HACK
205 static void     JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo, BOOL close_client);
206 #else
207 static void     JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo);
208 #endif
209
210 #if JACK_CLOSE_HACK
211 static void     JACK_CloseWaveInDevice(WINE_WAVEIN* wwi, BOOL close_client);
212 #else
213 static void     JACK_CloseWaveInDevice(WINE_WAVEIN* wwi);
214 #endif
215
216
217 /*======================================================================*
218  *                  Low level WAVE implementation                       *
219  *======================================================================*/
220
221 #define SAMPLE_MAX_16BIT  32767.0f
222
223 /* Alsaplayer function that applies volume changes to a buffer */
224 /* (C) Andy Lo A Foe */
225 /* Length is in terms of 32 bit samples */
226 void volume_effect32(void *buffer, int length, int left, int right)
227 {
228         short *data = (short *)buffer;
229         int i, v;
230     
231         if (right == -1) right = left;
232  
233         for(i = 0; i < length; i++) {
234                 v = (int) ((*(data) * left) / 100);
235                 *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
236                 v = (int) ((*(data) * right) / 100);
237                 *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
238         }
239 }
240
241 /* move 16 bit mono/stereo to 16 bit stereo */
242 void sample_move_d16_d16(short *dst, short *src,
243                   unsigned long nsamples, int nChannels)
244 {
245   while(nsamples--)
246   {
247     *dst = *src;
248     dst++;
249
250     if(nChannels == 2) src++;
251
252     *dst = *src;
253     dst++;
254
255     src++;
256   }
257 }
258
259 /* convert from 16 bit to floating point */
260 /* allow for copying of stereo data with alternating left/right */
261 /* channels to a buffer that will hold a single channel stream */
262 /* nsamples is in terms of 16bit samples */
263 /* src_skip is in terms of 16bit samples */
264 void sample_move_d16_s16 (sample_t *dst, short *src,
265                         unsigned long nsamples, unsigned long src_skip)
266 {
267   /* ALERT: signed sign-extension portability !!! */
268   while (nsamples--)
269   {
270     *dst = (*src) / SAMPLE_MAX_16BIT;
271     dst++;
272     src += src_skip;
273   }
274 }       
275
276 /* convert from floating point to 16 bit */
277 /* allow for copying of a buffer that will hold a single channel stream */
278 /* to stereo data with alternating left/right channels */
279 /* nsamples is in terms of float samples */
280 /* dst_skip is in terms of 16bit samples */
281 void sample_move_s16_d16 (short *dst, sample_t *src,
282                         unsigned long nsamples, unsigned long dst_skip)
283 {
284   /* ALERT: signed sign-extension portability !!! */
285   while (nsamples--)
286   {
287       *dst = (*src) * SAMPLE_MAX_16BIT;
288 /*      TRACE("src=(%.8f,%p) dst=(%d,%p)\n",*src,src,*dst,dst); */
289       dst += dst_skip;
290       src++;
291   }
292 }       
293
294
295 /* fill dst buffer with nsamples worth of silence */
296 void sample_silence_dS (sample_t *dst, unsigned long nsamples)
297 {
298   /* ALERT: signed sign-extension portability !!! */
299   while (nsamples--)
300   {
301     *dst = 0;
302     dst++;
303   }
304 }       
305
306 /******************************************************************
307  *    JACK_callback_wwo
308  */
309 /* everytime the jack server wants something from us it calls this 
310 function, so we either deliver it some sound to play or deliver it nothing 
311 to play */
312 int JACK_callback_wwo (nframes_t nframes, void *arg)
313 {
314   sample_t* out_l;
315   sample_t* out_r;
316   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
317
318   TRACE("wDevID: %u, nframes %u state=%u\n", wwo->wDevID, nframes,wwo->state);
319
320   if(!wwo->client)
321     ERR("client is closed, this is weird...\n");
322     
323   out_l = (sample_t *) fp_jack_port_get_buffer(wwo->out_port_l, nframes);
324   out_r = (sample_t *) fp_jack_port_get_buffer(wwo->out_port_r, nframes);
325
326   if(wwo->state == WINE_WS_PLAYING)
327   {
328     DWORD jackFramesAvailable = nframes;
329     DWORD outputFramesAvailable;
330     DWORD numFramesToWrite;
331
332     long written = 0;
333     char* buffer;
334
335 #if JACK_CLOSE_HACK
336     if(wwo->in_use == FALSE)
337     {
338       /* output silence if nothing is being outputted */
339       sample_silence_dS(out_l, nframes);
340       sample_silence_dS(out_r, nframes);
341
342       return 0;
343     }
344 #endif
345
346     TRACE("wwo.state == WINE_WS_PLAYING\n");
347
348     /* see if our sound_buffer is large enough to hold the number of frames jack requested */
349     /* Note: sound_buffer is always filled with 16-bit stereo data, even for mono mode */
350     if(wwo->buffer_size < (nframes * sizeof(short) * 2))
351     {
352       ERR("for some reason JACK_BufSize() didn't allocate enough memory\n");
353       ERR("allocated %ld bytes, need %d bytes\n", wwo->buffer_size, (nframes * sizeof(short) * 2));
354       return 0;
355     }
356
357     /* while we have jackFramesAvailable and a wave header to be played */
358     while(jackFramesAvailable && wwo->lpPlayPtr)
359     {
360       /* find the amount of audio to be played at this time */
361       outputFramesAvailable = (wwo->lpPlayPtr->dwBufferLength - wwo->dwPartialOffset) / wwo->format.wf.nBlockAlign;
362
363       numFramesToWrite = min(jackFramesAvailable, outputFramesAvailable);
364       TRACE("dwBufferLength=(%ld) dwPartialOffset=(%ld)\n",wwo->lpPlayPtr->dwBufferLength,wwo->dwPartialOffset);
365       TRACE("outputFramesAvailable == %ld, jackFramesAvailable == %ld\n", outputFramesAvailable, jackFramesAvailable);
366
367       buffer = wwo->lpPlayPtr->lpData + wwo->dwPartialOffset;
368
369       /* convert from mono to stereo if necessary */
370       /* otherwise just memcpy to the output buffer */
371
372       if(wwo->format.wf.nChannels == 1)
373       {
374         sample_move_d16_d16((short*)wwo->sound_buffer + ((nframes - jackFramesAvailable) * sizeof(short)),
375                             (short*)buffer, numFramesToWrite, wwo->format.wf.nChannels);
376       } else /* just copy the memory over */
377       {
378         memcpy(wwo->sound_buffer + ((nframes - jackFramesAvailable) * wwo->format.wf.nBlockAlign),
379                buffer, numFramesToWrite * wwo->format.wf.nBlockAlign);
380       }
381
382       /* advance to the next wave header if possible, or advance pointer */
383       /* inside of the current header if we haven't completed it */
384       if(numFramesToWrite == outputFramesAvailable)
385       {
386         wodHelper_PlayPtrNext(wwo);            /* we wrote the whole waveheader, skip to the next one*/
387       }
388       else
389       {
390         wwo->dwPartialOffset+=(numFramesToWrite * wwo->format.wf.nBlockAlign); /* else advance by the bytes we took in to write */
391       }
392
393       written+=(numFramesToWrite * wwo->format.wf.nBlockAlign); /* add on what we wrote */
394       jackFramesAvailable-=numFramesToWrite; /* take away what was written in terms of output bytes */
395     }
396
397     wwo->tickCountMS = GetTickCount();    /* record the current time */
398     wwo->dwWrittenTotal+=written; /* update states on wave device */
399     wwo->dwPlayedTotal+=wwo->bytesInJack; /* we must have finished with the last bytes or we wouldn't be back inside of this callback again... */
400     wwo->bytesInJack = written; /* record the bytes inside of jack */
401
402     /* Now that we have finished filling the buffer either until it is full or until */
403     /* we have run out of application sound data to process, apply volume and output */
404     /* the audio to the jack server */
405
406     /* apply volume to the buffer */
407     volume_effect32(wwo->sound_buffer, (nframes - jackFramesAvailable), wwo->volume_left, wwo->volume_right);
408
409     /* convert from stereo 16 bit to single channel 32 bit float */
410     /* for each jack server channel */
411     /* NOTE: we skip over two sample since we want to only get either the left or right channel */
412     sample_move_d16_s16(out_l, (short*)wwo->sound_buffer,     (nframes - jackFramesAvailable), 2);
413     sample_move_d16_s16(out_r, (short*)wwo->sound_buffer + 1, (nframes - jackFramesAvailable), 2);
414
415     /* see if we still have jackBytesLeft here, if we do that means that we
416     ran out of wave data to play and had a buffer underrun, fill in
417     the rest of the space with zero bytes */
418     if(jackFramesAvailable)
419     {
420       ERR("buffer underrun of %ld frames\n", jackFramesAvailable);
421       sample_silence_dS(out_l + (nframes - jackFramesAvailable), jackFramesAvailable);
422       sample_silence_dS(out_r + (nframes - jackFramesAvailable), jackFramesAvailable);
423     }
424   }
425   else if(wwo->state == WINE_WS_PAUSED || 
426     wwo->state == WINE_WS_STOPPED ||
427     wwo->state == WINE_WS_CLOSED)
428   {
429       /* output silence if nothing is being outputted */
430       sample_silence_dS(out_l, nframes);
431       sample_silence_dS(out_r, nframes);
432   }
433
434   /* notify the client of completed wave headers */
435   EnterCriticalSection(&wwo->access_crst);
436   wodHelper_NotifyCompletions(wwo, FALSE);
437   LeaveCriticalSection(&wwo->access_crst);
438
439   return 0;
440 }
441
442 /******************************************************************
443  *              JACK_bufsize_wwo
444  *
445  *              Called whenever the jack server changes the the max number 
446  *              of frames passed to JACK_callback
447  */
448 int JACK_bufsize_wwo (nframes_t nframes, void *arg)
449 {
450   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
451   DWORD buffer_required;
452   TRACE("wDevID=%d\n",wwo->wDevID);
453   TRACE("the maximum buffer size is now %u frames\n", nframes);
454
455   /* make sure the callback routine has adequate memory */
456     /* see if our buffer is large enough for the data we are writing */
457     /* ie. Buffer_size < (bytes we already wrote + bytes we are going to write in this loop) */
458   EnterCriticalSection(&wwo->access_crst);
459
460   /* wwo->sound_buffer is always filled with 16-bit stereo data, even for mono streams */
461   buffer_required = nframes * sizeof(short) * 2;
462   TRACE("wwo->buffer_size (%ld) buffer_required (%ld).\n", wwo->buffer_size,buffer_required);
463   if(wwo->buffer_size < buffer_required)
464   {
465     TRACE("expanding buffer from wwo->buffer_size == %ld, to %ld\n", 
466       wwo->buffer_size, buffer_required);
467     TRACE("GetProcessHeap() == %p\n", GetProcessHeap());
468     wwo->buffer_size = buffer_required;
469
470     if (wwo->sound_buffer)
471       wwo->sound_buffer = HeapReAlloc(GetProcessHeap(), 0, wwo->sound_buffer, wwo->buffer_size);
472     else
473       wwo->sound_buffer = HeapAlloc(GetProcessHeap(), 0, wwo->buffer_size);
474
475     /* if we don't have a buffer then error out */
476     if(!wwo->sound_buffer)
477     {
478         ERR("error allocating sound_buffer memory\n");
479         LeaveCriticalSection(&wwo->access_crst);
480         return 0;
481     }
482   }
483
484   LeaveCriticalSection(&wwo->access_crst);
485
486   TRACE("ending\n");
487
488   return 0;
489 }
490 /******************************************************************
491  *              JACK_bufsize_wwi
492  *
493  *              Called whenever the jack server changes the the max number 
494  *              of frames passed to JACK_callback
495  */
496 int JACK_bufsize_wwi (nframes_t nframes, void *arg)
497 {
498   TRACE("the maximum buffer size is now %u frames\n", nframes);
499   return 0;
500 }
501
502 /******************************************************************
503  *              JACK_srate
504  */
505 int JACK_srate (nframes_t nframes, void *arg)
506 {
507   TRACE("the sample rate is now %u/sec\n", nframes);
508   return 0;
509 }
510
511
512 /******************************************************************
513  *              JACK_shutdown_wwo
514  */
515 /* if this is called then jack shut down... handle this appropriately */
516 void JACK_shutdown_wwo(void* arg)
517 {
518   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
519
520   wwo->client = 0; /* reset client */
521
522   TRACE("trying to reconnect after sleeping for a short while...\n");
523   
524   /* lets see if we can't reestablish the connection */
525   Sleep(750); /* pause for a short period of time */
526   if(!JACK_OpenWaveOutDevice(wwo))
527   {
528     ERR("unable to reconnect with jack...\n");
529   }
530 }
531
532 /******************************************************************
533  *              JACK_shutdown_wwi
534  */
535 /* if this is called then jack shut down... handle this appropriately */
536 void JACK_shutdown_wwi(void* arg)
537 {
538   WINE_WAVEIN* wwi = (WINE_WAVEIN*)arg;
539
540   wwi->client = 0; /* reset client */
541
542   TRACE("trying to reconnect after sleeping for a short while...\n");
543   
544   /* lets see if we can't reestablish the connection */
545   Sleep(750); /* pause for a short period of time */
546   if(!JACK_OpenWaveInDevice(wwi,wwi->format.wf.nChannels))
547   {
548     ERR("unable to reconnect with jack...\n");
549   }
550 }
551
552
553 /******************************************************************
554  *              JACK_OpenWaveOutDevice
555  */
556 static int JACK_OpenWaveOutDevice(WINE_WAVEOUT* wwo)
557 {
558   const char** ports;
559   int i;
560   char client_name[64];
561   jack_port_t* out_port_l;
562   jack_port_t* out_port_r;
563   jack_client_t* client;
564   int failed = 0;
565
566   TRACE("creating jack client and setting up callbacks\n");
567
568 #if JACK_CLOSE_HACK
569   /* see if this device is already open */
570         if(wwo->client)
571         {
572           /* if this device is already in use then it is bad for us to be in here */
573           if(wwo->in_use)
574             return 0;
575
576           TRACE("using existing client\n");
577           wwo->in_use = TRUE;
578           return 1;
579         }
580 #endif
581
582         /* zero out the buffer pointer and the size of the buffer */
583         wwo->sound_buffer = 0;
584         wwo->buffer_size = 0;
585
586         /* try to become a client of the JACK server */
587         snprintf(client_name, sizeof(client_name), "wine_jack_out_%d", wwo->wDevID);
588         TRACE("client name '%s'\n", client_name);
589         if ((client = fp_jack_client_new (client_name)) == 0)
590         {
591                 /* jack has problems with shutting down clients, so lets */
592                 /* wait a short while and try once more before we give up */
593                 Sleep(250);
594                 if ((client = fp_jack_client_new (client_name)) == 0)
595                 {
596                   ERR("jack server not running?\n");
597                   return 0;
598                 }
599         }
600                         
601         /* tell the JACK server to call `JACK_callback_wwo()' whenever
602            there is work to be done. */
603         fp_jack_set_process_callback (client, JACK_callback_wwo, wwo);
604         
605         /* tell the JACK server to call `JACK_bufsize_wwo()' whenever   
606            the maximum number of frames that will be passed
607            to `JACK_Callback()' changes */
608         fp_jack_set_buffer_size_callback (client, JACK_bufsize_wwo, wwo);
609
610         /* tell the JACK server to call `srate()' whenever
611            the sample rate of the system changes. */
612         fp_jack_set_sample_rate_callback (client, JACK_srate, wwo);
613
614         /* tell the JACK server to call `jack_shutdown()' if
615            it ever shuts down, either entirely, or if it
616            just decides to stop calling us. */
617         fp_jack_on_shutdown (client, JACK_shutdown_wwo, wwo);
618         
619         /* display the current sample rate. once the client is activated
620            (see below), you should rely on your own sample rate
621            callback (see above) for this value. */
622         wwo->sample_rate = fp_jack_get_sample_rate(client);
623         TRACE("engine sample rate: %lu\n", wwo->sample_rate);
624           
625         /* create the left and right channel output ports */
626         /* jack's ports are all mono so for stereo you need two */
627         out_port_l = fp_jack_port_register (client, "out_l",
628                          JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
629
630         out_port_r = fp_jack_port_register (client, "out_r",
631                          JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
632
633         TRACE("Created ports. (%p) (%p)\n",out_port_l, out_port_r);
634
635         /* save away important values to the WINE_WAVEOUT struct */
636         wwo->client = client;
637         wwo->out_port_l = out_port_l;
638         wwo->out_port_r = out_port_r;
639
640 #if JACK_CLOSE_HACK
641         wwo->in_use = TRUE; /* mark this device as in use since it now is ;-) */
642 #endif
643
644         /* set initial buffer size */
645         JACK_bufsize_wwo (fp_jack_get_buffer_size(client),wwo);
646
647         /* tell the JACK server that we are ready to roll */
648         if (fp_jack_activate (client))
649         {
650           ERR( "cannot activate client\n");
651           return 0;
652         }
653
654         TRACE("jack activate.\n");
655         /* figure out what the ports that we want to output on are */
656         /* NOTE: we do this instead of using stuff like "alsa_pcm:playback_X" because */
657         /*   this way works if names are changed */
658         ports = fp_jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
659
660         /* display a trace of the output ports we found */
661         for(i = 0; ports[i]; i++)
662         {
663           TRACE("ports[%d] = '%s'\n", i, ports[i]);
664         }
665
666         if(!ports)
667         {
668           ERR("jack_get_ports() failed to find 'JackPortIsPhysical|JackPortIsInput'\n");
669         }
670
671         /* connect the ports. Note: you can't do this before
672            the client is activated (this may change in the future).
673         */ 
674         /* we want to connect to two ports so we have stereo output ;-) */
675
676         if(fp_jack_connect(client, fp_jack_port_name(out_port_l), ports[0]))
677         {
678           ERR ("cannot connect to output port %d('%s')\n", 0, ports[0]);
679           failed = 1;
680         }
681
682         if(fp_jack_connect(client, fp_jack_port_name(out_port_r), ports[1]))
683         {
684           ERR ("cannot connect to output port %d('%s')\n", 1, ports[1]);
685           failed = 1;
686         }
687
688         free(ports); /* free the returned array of ports */
689
690         /* if something failed we need to shut the client down and return 0 */
691         if(failed)
692         {
693 #if JACK_CLOSE_HACK
694           JACK_CloseWaveOutDevice(wwo, TRUE);
695 #else
696           JACK_CloseWaveOutDevice(wwo);
697 #endif
698           return 0;
699         }
700
701         return 1; /* return success */
702 }
703
704 /******************************************************************
705  *              JACK_CloseWaveOutDevice
706  *
707  *      Close the connection to the server cleanly.
708  *  If close_client is TRUE we close the client for this device instead of
709  *    just marking the device as in_use(JACK_CLOSE_HACK only)
710  */
711 #if JACK_CLOSE_HACK
712 static void     JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo, BOOL close_client)
713 #else
714 static void     JACK_CloseWaveOutDevice(WINE_WAVEOUT* wwo)
715 #endif
716 {
717 #if JACK_CLOSE_HACK
718   TRACE("wDevID: %d, close_client (wwo): %d\n", wwo->wDevID, close_client);
719 #else
720   TRACE("wDevID: %d\n", wwo->wDevID);
721 #endif
722
723 #if JACK_CLOSE_HACK
724   if(close_client)
725   {
726 #endif
727     fp_jack_deactivate(wwo->client); /* supposed to help the jack_client_close() to succeed */
728     fp_jack_client_close (wwo->client);
729
730     EnterCriticalSection(&wwo->access_crst);
731     wwo->client = 0; /* reset client */
732     HeapFree(GetProcessHeap(), 0, wwo->sound_buffer); /* free buffer memory */
733     wwo->sound_buffer = 0;
734     wwo->buffer_size = 0; /* zero out size of the buffer */
735     LeaveCriticalSection(&wwo->access_crst);
736 #if JACK_CLOSE_HACK
737   } else
738   {
739     EnterCriticalSection(&wwo->access_crst);
740     TRACE("setting in_use to FALSE\n");
741     wwo->in_use = FALSE;
742     LeaveCriticalSection(&wwo->access_crst);
743   }
744 #endif
745 }
746
747 /******************************************************************
748  *              JACK_CloseWaveInDevice
749  *
750  *      Close the connection to the server cleanly.
751  *  If close_client is TRUE we close the client for this device instead of
752  *    just marking the device as in_use(JACK_CLOSE_HACK only)
753  */
754 #if JACK_CLOSE_HACK
755 static void     JACK_CloseWaveInDevice(WINE_WAVEIN* wwi, BOOL close_client)
756 #else
757 static void     JACK_CloseWaveInDevice(WINE_WAVEIN* wwi)
758 #endif
759 {
760 #if JACK_CLOSE_HACK
761   TRACE("wDevID: %d, close_client (wwi): %d\n", wwi->wDevID, close_client);
762 #else
763   TRACE("wDevID: %d\n", wwi->wDevID);
764 #endif
765
766 #if JACK_CLOSE_HACK
767   if(close_client)
768   {
769 #endif
770     fp_jack_deactivate(wwi->client); /* supposed to help the jack_client_close() to succeed */
771     fp_jack_client_close (wwi->client);
772
773     EnterCriticalSection(&wwi->access_crst);
774     wwi->client = 0; /* reset client */
775     HeapFree(GetProcessHeap(), 0, wwi->sound_buffer); /* free buffer memory */
776     wwi->sound_buffer = 0;
777     wwi->buffer_size = 0; /* zero out size of the buffer */
778     LeaveCriticalSection(&wwi->access_crst);
779 #if JACK_CLOSE_HACK
780   } else
781   {
782     EnterCriticalSection(&wwi->access_crst);
783     TRACE("setting in_use to FALSE\n");
784     wwi->in_use = FALSE;
785     LeaveCriticalSection(&wwi->access_crst);
786   }
787 #endif
788 }
789
790 /******************************************************************
791  *              JACK_WaveRelease
792  *
793  *
794  */
795 LONG    JACK_WaveRelease(void)
796
797   int iDevice;
798
799   TRACE("closing all open waveout devices\n");
800
801   /* close all open output devices */
802   for(iDevice = 0; iDevice < MAX_WAVEOUTDRV; iDevice++)
803   {
804     TRACE("iDevice == %d\n", iDevice);
805     if(WOutDev[iDevice].client)
806     {
807 #if JACK_CLOSE_HACK
808       JACK_CloseWaveOutDevice(&WOutDev[iDevice], TRUE); /* close the device, FORCE the client to close */
809 #else
810       JACK_CloseWaveOutDevice(&WOutDev[iDevice]); /* close the device, FORCE the client to close */
811 #endif
812       DeleteCriticalSection(&(WOutDev[iDevice].access_crst)); /* delete the critical section */
813     }
814   }
815
816   TRACE("closing all open wavein devices\n");
817
818   /* close all open input devices */
819   for(iDevice = 0; iDevice < MAX_WAVEINDRV; iDevice++)
820   {
821     TRACE("iDevice == %d\n", iDevice);
822     if(WInDev[iDevice].client)
823     {
824 #if JACK_CLOSE_HACK
825       JACK_CloseWaveInDevice(&WInDev[iDevice], TRUE); /* close the device, FORCE the client to close */
826 #else
827       JACK_CloseWaveInDevice(&WInDev[iDevice]); /* close the device, FORCE the client to close */
828 #endif
829       DeleteCriticalSection(&(WInDev[iDevice].access_crst)); /* delete the critical section */
830     }
831   }
832
833   TRACE("returning 1\n");
834
835   return 1;
836 }
837
838 /******************************************************************
839  *              JACK_WaveInit
840  *
841  * Initialize internal structures from JACK server info
842  */
843 LONG JACK_WaveInit(void)
844 {
845     int i;
846
847     TRACE("called\n");
848
849     /* setup function pointers */
850 #define LOAD_FUNCPTR(f) if((fp_##f = wine_dlsym(jackhandle, #f, NULL, 0)) == NULL) goto sym_not_found;    
851     LOAD_FUNCPTR(jack_activate);
852     LOAD_FUNCPTR(jack_connect);
853     LOAD_FUNCPTR(jack_client_new);
854     LOAD_FUNCPTR(jack_client_close);
855     LOAD_FUNCPTR(jack_deactivate);
856     LOAD_FUNCPTR(jack_set_process_callback);
857     LOAD_FUNCPTR(jack_set_buffer_size_callback);
858     LOAD_FUNCPTR(jack_set_sample_rate_callback);
859     LOAD_FUNCPTR(jack_on_shutdown);
860     LOAD_FUNCPTR(jack_get_sample_rate);
861     LOAD_FUNCPTR(jack_port_register);
862     LOAD_FUNCPTR(jack_port_get_buffer);
863     LOAD_FUNCPTR(jack_get_ports);
864     LOAD_FUNCPTR(jack_port_name);
865     LOAD_FUNCPTR(jack_get_buffer_size);
866 #undef LOAD_FUNCPTR
867
868     /* start with output device */
869
870     for (i = 0; i < MAX_WAVEOUTDRV; ++i)
871     {
872       WOutDev[i].client = 0; /* initialize the client to 0 */
873
874 #if JACK_CLOSE_HACK
875       WOutDev[i].in_use = FALSE;
876       WInDev[i].in_use  = FALSE;
877 #endif
878
879       memset(&WOutDev[i].caps, 0, sizeof(WOutDev[i].caps));
880
881       /* FIXME: some programs compare this string against the content of the registry
882        * for MM drivers. The names have to match in order for the program to work 
883        * (e.g. MS win9x mplayer.exe)
884        */
885 #ifdef EMULATE_SB16
886       WOutDev[i].caps.wMid = 0x0002;
887       WOutDev[i].caps.wPid = 0x0104;
888       strcpy(WOutDev[i].caps.szPname, "SB16 Wave Out");
889 #else
890       WOutDev[i].caps.wMid = 0x00FF;    /* Manufac ID */
891       WOutDev[i].caps.wPid = 0x0001;    /* Product ID */
892       /*    strcpy(WOutDev[i].caps.szPname, "OpenSoundSystem WAVOUT Driver");*/
893       strcpy(WOutDev[i].caps.szPname, "CS4236/37/38");
894 #endif
895       WOutDev[i].caps.vDriverVersion = 0x0100;
896       WOutDev[i].caps.dwFormats = 0x00000000;
897       WOutDev[i].caps.dwSupport = WAVECAPS_VOLUME;
898     
899       WOutDev[i].caps.wChannels = 2;
900       WOutDev[i].caps.dwSupport |= WAVECAPS_LRVOLUME;
901
902 /* NOTE: we don't support any 8 bit modes so note that */
903 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
904       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S08; */
905       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
906       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
907 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
908       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S08; */
909       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
910       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
911 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
912       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;*/
913       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
914       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
915     }
916
917     /* then do input device */
918     for (i = 0; i < MAX_WAVEINDRV; ++i)
919     {
920       /* TODO: we should initialize read stuff here */
921       memset(&WInDev[0].caps, 0, sizeof(WInDev[0].caps));
922
923     /* FIXME: some programs compare this string against the content of the registry
924      * for MM drivers. The names have to match in order for the program to work
925      * (e.g. MS win9x mplayer.exe)
926      */
927 #ifdef EMULATE_SB16
928         WInDev[i].caps.wMid = 0x0002;
929         WInDev[i].caps.wPid = 0x0104;
930         strcpy(WInDev[i].caps.szPname, "SB16 Wave In");
931 #else
932         WInDev[i].caps.wMid = 0x00FF;
933         WInDev[i].caps.wPid = 0x0001;
934         strcpy(WInDev[i].caps.szPname,"CS4236/37/38");
935 #endif
936         WInDev[i].caps.vDriverVersion = 0x0100;
937
938         WInDev[i].caps.wChannels = 0x2;
939         /* NOTE: we don't support any 8 bit modes so note that */
940 /*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
941         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S08; */
942         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
943         WInDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
944 /*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
945         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S08; */
946         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
947         WInDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
948 /*      WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
949         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;*/
950         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
951         WInDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
952         WInDev[i].caps.wReserved1 = 0;
953     }
954     
955     return 1;           /* return success */
956
957 /* error path for function pointer loading errors */
958 sym_not_found:
959     WINE_MESSAGE(
960       "Wine cannot find certain functions that it needs inside the jack"
961       "library.  To enable Wine to use the jack audio server please "
962       "install libjack\n");
963     wine_dlclose(jackhandle, NULL, 0);
964     jackhandle = NULL;
965     return FALSE;
966 }
967
968 /*======================================================================*
969  *                  Low level WAVE OUT implementation                   *
970  *======================================================================*/
971
972 /**************************************************************************
973  *                      wodNotifyClient                 [internal]
974  */
975 static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
976 {
977     TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2);
978     
979     switch (wMsg) {
980     case WOM_OPEN:
981     case WOM_CLOSE:
982     case WOM_DONE:
983       if (wwo->wFlags != DCB_NULL &&
984         !DriverCallback(wwo->waveDesc.dwCallback, wwo->wFlags,
985           (HDRVR)wwo->waveDesc.hWave, wMsg, wwo->waveDesc.dwInstance,
986           dwParam1, dwParam2))
987       {
988         WARN("can't notify client !\n");
989         return MMSYSERR_ERROR;
990       }
991     break;
992     default:
993       FIXME("Unknown callback message %u\n", wMsg);
994         return MMSYSERR_INVALPARAM;
995     }
996     return MMSYSERR_NOERROR;
997 }
998
999 /**************************************************************************
1000  *                              wodHelper_BeginWaveHdr          [internal]
1001  *
1002  * Makes the specified lpWaveHdr the currently playing wave header.
1003  * If the specified wave header is a begin loop and we're not already in
1004  * a loop, setup the loop.
1005  */
1006 static void wodHelper_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
1007 {
1008     EnterCriticalSection(&wwo->access_crst);
1009
1010     wwo->lpPlayPtr = lpWaveHdr;
1011
1012     if (!lpWaveHdr)
1013     {
1014        LeaveCriticalSection(&wwo->access_crst);
1015        return;
1016     }
1017
1018     if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)
1019     {
1020       if (wwo->lpLoopPtr)
1021       {
1022         WARN("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
1023         TRACE("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
1024       } else
1025       {
1026         TRACE("Starting loop (%ldx) with %p\n", lpWaveHdr->dwLoops, lpWaveHdr);
1027         wwo->lpLoopPtr = lpWaveHdr;
1028         /* Windows does not touch WAVEHDR.dwLoops,
1029          * so we need to make an internal copy */
1030         wwo->dwLoops = lpWaveHdr->dwLoops;
1031       }
1032     }
1033     wwo->dwPartialOffset = 0;
1034
1035     LeaveCriticalSection(&wwo->access_crst);
1036 }
1037
1038
1039 /**************************************************************************
1040  *                              wodHelper_PlayPtrNext           [internal]
1041  *
1042  * Advance the play pointer to the next waveheader, looping if required.
1043  */
1044 static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo)
1045 {
1046   LPWAVEHDR lpWaveHdr;
1047
1048   EnterCriticalSection(&wwo->access_crst);
1049
1050   lpWaveHdr = wwo->lpPlayPtr;
1051
1052   wwo->dwPartialOffset = 0;
1053   if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr)
1054   {
1055     /* We're at the end of a loop, loop if required */
1056     if (--wwo->dwLoops > 0)
1057     {
1058       wwo->lpPlayPtr = wwo->lpLoopPtr;
1059     } else
1060     {
1061       /* Handle overlapping loops correctly */
1062       if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) {
1063         FIXME("Correctly handled case ? (ending loop buffer also starts a new loop)\n");
1064         /* shall we consider the END flag for the closing loop or for
1065          * the opening one or for both ???
1066          * code assumes for closing loop only
1067          */
1068       } else
1069       {
1070         lpWaveHdr = lpWaveHdr->lpNext;
1071       }
1072       wwo->lpLoopPtr = NULL;
1073       wodHelper_BeginWaveHdr(wwo, lpWaveHdr);
1074     }
1075   } else
1076   {
1077      /* We're not in a loop.  Advance to the next wave header */
1078     TRACE("not inside of a loop, advancing to next wave header\n");
1079     wodHelper_BeginWaveHdr(wwo, lpWaveHdr = lpWaveHdr->lpNext);
1080   }
1081
1082   LeaveCriticalSection(&wwo->access_crst);
1083
1084   return lpWaveHdr;
1085 }
1086
1087 /* if force is TRUE then notify the client that all the headers were completed */
1088 static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force)
1089 {
1090   LPWAVEHDR             lpWaveHdr;
1091   DWORD retval;
1092
1093   TRACE("called\n");
1094
1095   EnterCriticalSection(&wwo->access_crst);
1096
1097   /* Start from lpQueuePtr and keep notifying until:
1098    * - we hit an unwritten wavehdr
1099    * - we hit the beginning of a running loop
1100    * - we hit a wavehdr which hasn't finished playing
1101    */
1102   while ((lpWaveHdr = wwo->lpQueuePtr) &&
1103            (force || 
1104             (lpWaveHdr != wwo->lpPlayPtr &&
1105              lpWaveHdr != wwo->lpLoopPtr)))
1106   {
1107     wwo->lpQueuePtr = lpWaveHdr->lpNext;
1108
1109     lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1110     lpWaveHdr->dwFlags |= WHDR_DONE;
1111     TRACE("notifying client: lpWaveHdr=(%p) lpPlayPtr=(%p) dwFlags=(%ld)\n",
1112           lpWaveHdr, wwo->lpPlayPtr, lpWaveHdr->dwFlags);
1113
1114     wodNotifyClient(wwo, WOM_DONE, (DWORD)lpWaveHdr, 0);
1115   }
1116   TRACE("Not notifying client: lpWaveHdr=(%p) lpPlayPtr=(%p) lpLoopPtr=(%p)\n",
1117         lpWaveHdr, wwo->lpPlayPtr, wwo->lpLoopPtr);
1118   retval = (lpWaveHdr && lpWaveHdr != wwo->lpPlayPtr && lpWaveHdr != 
1119               wwo->lpLoopPtr) ? 0 : INFINITE;
1120
1121   LeaveCriticalSection(&wwo->access_crst);
1122
1123   return retval;
1124 }
1125
1126 /**************************************************************************
1127  *                              wodHelper_Reset                 [internal]
1128  *
1129  * Resets current output stream.
1130  */
1131 static  void  wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset)
1132 {
1133     EnterCriticalSection(&wwo->access_crst);
1134  
1135     /* updates current notify list */
1136     wodHelper_NotifyCompletions(wwo, FALSE);
1137
1138     if (reset)
1139     {
1140         /* remove all wave headers and notify client that all headers were completed */
1141         wodHelper_NotifyCompletions(wwo, TRUE);
1142
1143         wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL;
1144         wwo->state = WINE_WS_STOPPED;
1145         wwo->dwPlayedTotal = wwo->dwWrittenTotal = wwo->bytesInJack = 0;
1146
1147         wwo->dwPartialOffset = 0;        /* Clear partial wavehdr */
1148     } else
1149     {
1150         if (wwo->lpLoopPtr)
1151         {
1152             /* complicated case, not handled yet (could imply modifying the loop counter) */
1153             FIXME("Pausing while in loop isn't correctly handled yet, except strange results\n");
1154             wwo->lpPlayPtr = wwo->lpLoopPtr;
1155             wwo->dwPartialOffset = 0;
1156             wwo->dwWrittenTotal = wwo->dwPlayedTotal; /* this is wrong !!! */
1157         } else
1158         {
1159             LPWAVEHDR   ptr;
1160             DWORD       sz = wwo->dwPartialOffset;
1161
1162             /* reset all the data as if we had written only up to lpPlayedTotal bytes */
1163             /* compute the max size playable from lpQueuePtr */
1164             for (ptr = wwo->lpQueuePtr; ptr != wwo->lpPlayPtr; ptr = ptr->lpNext)
1165             {
1166                 sz += ptr->dwBufferLength;
1167             }
1168
1169             /* because the reset lpPlayPtr will be lpQueuePtr */
1170             if (wwo->dwWrittenTotal > wwo->dwPlayedTotal + sz) ERR("doh\n");
1171             wwo->dwPartialOffset = sz - (wwo->dwWrittenTotal - wwo->dwPlayedTotal);
1172             wwo->dwWrittenTotal = wwo->dwPlayedTotal;
1173             wwo->lpPlayPtr = wwo->lpQueuePtr;
1174         }
1175
1176         wwo->state = WINE_WS_PAUSED;
1177     }
1178  
1179     LeaveCriticalSection(&wwo->access_crst);
1180 }
1181
1182 /**************************************************************************
1183  *                      wodGetDevCaps                           [internal]
1184  */
1185 static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPSA lpCaps, DWORD dwSize)
1186 {
1187     TRACE("(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
1188     
1189     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1190     
1191     if (wDevID >= MAX_WAVEOUTDRV)
1192     {
1193       TRACE("MAX_WAVOUTDRV reached !\n");
1194       return MMSYSERR_BADDEVICEID;
1195     }
1196
1197     TRACE("dwSupport=(0x%lx), dwFormats=(0x%lx)\n", WOutDev[wDevID].caps.dwSupport, WOutDev[wDevID].caps.dwFormats);
1198     memcpy(lpCaps, &WOutDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
1199     return MMSYSERR_NOERROR;
1200 }
1201
1202 /**************************************************************************
1203  *                              wodOpen                         [internal]
1204  *
1205  * NOTE: doesn't it seem like there is a race condition if you try to open 
1206  * the same device twice?
1207  */
1208 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1209 {
1210     WINE_WAVEOUT*       wwo;
1211     DWORD retval;
1212
1213     TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1214     if (lpDesc == NULL)
1215     {
1216       WARN("Invalid Parameter !\n");
1217       return MMSYSERR_INVALPARAM;
1218     }
1219     if (wDevID >= MAX_WAVEOUTDRV) {
1220       TRACE("MAX_WAVOUTDRV reached !\n");
1221       return MMSYSERR_BADDEVICEID;
1222     }
1223
1224 #if JACK_CLOSE_HACK
1225     if(WOutDev[wDevID].client && WOutDev[wDevID].in_use)
1226 #else
1227     if(WOutDev[wDevID].client)
1228 #endif
1229     {
1230       TRACE("device %d already allocated\n", wDevID);
1231       return MMSYSERR_ALLOCATED;
1232     }
1233
1234     /* Only the PCM format is supported so far...
1235      * Also we only support 16 bit mode.
1236      */
1237     if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
1238       lpDesc->lpFormat->nChannels == 0 ||
1239       lpDesc->lpFormat->nSamplesPerSec == 0 ||
1240       lpDesc->lpFormat->wBitsPerSample != 16)
1241     {
1242       WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%ld wBitsPerSample=%d !\n",
1243        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1244        lpDesc->lpFormat->nSamplesPerSec, lpDesc->lpFormat->wBitsPerSample);
1245       return WAVERR_BADFORMAT;
1246     }
1247
1248     if (dwFlags & WAVE_FORMAT_QUERY)
1249     {
1250       TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
1251        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1252        lpDesc->lpFormat->nSamplesPerSec);
1253       return MMSYSERR_NOERROR;
1254     }
1255
1256     wwo = &WOutDev[wDevID];
1257     wwo->wDevID = wDevID;
1258
1259     /* Set things up before we call JACK_OpenWaveOutDevice because */
1260     /* we will start getting callbacks before JACK_OpenWaveOutDevice */
1261     /* even returns and we want to be initialized before then */
1262     wwo->state = WINE_WS_STOPPED; /* start in a stopped state */
1263     wwo->dwPlayedTotal = 0; /* zero out these totals */
1264     wwo->dwWrittenTotal = 0;
1265     wwo->bytesInJack = 0;
1266     wwo->tickCountMS = 0;
1267
1268     /* Initialize volume to full level */
1269     wwo->volume_left = 100;
1270     wwo->volume_right = 100;
1271
1272     InitializeCriticalSection(&wwo->access_crst); /* initialize the critical section */
1273     EnterCriticalSection(&wwo->access_crst);
1274
1275     dwFlags &= ~WAVE_DIRECTSOUND;  /* direct sound not supported, ignore the flag */
1276
1277     wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1278     
1279     memcpy(&wwo->waveDesc, lpDesc,           sizeof(WAVEOPENDESC));
1280     memcpy(&wwo->format,   lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
1281
1282     /* open up jack ports for this device */
1283     if (!JACK_OpenWaveOutDevice(&WOutDev[wDevID]))
1284     {
1285       ERR("JACK_OpenWaveOutDevice(%d) failed\n", wDevID);
1286       LeaveCriticalSection(&wwo->access_crst);
1287       DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
1288       return MMSYSERR_ERROR;            /* return unspecified error */
1289     }
1290
1291     LeaveCriticalSection(&wwo->access_crst);
1292
1293     /* display the current wave format */
1294     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n", 
1295     wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
1296     wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
1297     wwo->format.wf.nBlockAlign);
1298
1299     /* make sure that we have the same sample rate in our audio stream */
1300     /* as we do in the jack server */
1301     if(wwo->format.wf.nSamplesPerSec != wwo->sample_rate)
1302     {
1303       TRACE("error: jack server sample rate is '%ld', wave sample rate is '%ld'\n",
1304          wwo->sample_rate, wwo->format.wf.nSamplesPerSec);
1305
1306 #if JACK_CLOSE_HACK
1307       JACK_CloseWaveOutDevice(wwo, FALSE); /* close this device, don't force the client to close */
1308 #else
1309       JACK_CloseWaveOutDevice(wwo); /* close this device */
1310 #endif
1311       DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
1312       return WAVERR_BADFORMAT;
1313     }
1314
1315     /* check for an invalid number of bits per sample */
1316     if (wwo->format.wBitsPerSample == 0)
1317     {
1318       WARN("Resetting zeroed wBitsPerSample\n");
1319       wwo->format.wBitsPerSample = 8 *
1320       (wwo->format.wf.nAvgBytesPerSec /
1321        wwo->format.wf.nSamplesPerSec) /
1322        wwo->format.wf.nChannels;
1323     }
1324
1325     EnterCriticalSection(&wwo->access_crst);
1326     retval = wodNotifyClient(wwo, WOM_OPEN, 0L, 0L);
1327     LeaveCriticalSection(&wwo->access_crst);
1328
1329     return retval;
1330 }
1331
1332 /**************************************************************************
1333  *                              wodClose                        [internal]
1334  */
1335 static DWORD wodClose(WORD wDevID)
1336 {
1337     DWORD               ret = MMSYSERR_NOERROR;
1338     WINE_WAVEOUT*       wwo;
1339
1340     TRACE("(%u);\n", wDevID);
1341
1342     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1343     {
1344       WARN("bad device ID !\n");
1345       return MMSYSERR_BADDEVICEID;
1346     }
1347     
1348     wwo = &WOutDev[wDevID];
1349     if (wwo->lpQueuePtr)
1350     {
1351       WARN("buffers still playing !\n");
1352       ret = WAVERR_STILLPLAYING;
1353     } else
1354     {
1355       /* sanity check: this should not happen since the device must have been reset before */
1356       if (wwo->lpQueuePtr || wwo->lpPlayPtr) ERR("out of sync\n");
1357
1358       wwo->state = WINE_WS_CLOSED; /* mark the device as closed */
1359
1360 #if JACK_CLOSE_HACK
1361       JACK_CloseWaveOutDevice(wwo, FALSE); /* close the jack device, DO NOT force the client to close */
1362 #else
1363       JACK_CloseWaveOutDevice(wwo); /* close the jack device */
1364 #endif
1365       DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
1366
1367       ret = wodNotifyClient(wwo, WOM_CLOSE, 0L, 0L);
1368     }
1369
1370     return ret;
1371 }
1372
1373
1374 /**************************************************************************
1375  *                              wodWrite                        [internal]
1376  * 
1377  */
1378 static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1379 {
1380     LPWAVEHDR*wh;
1381     WINE_WAVEOUT *wwo;
1382
1383     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1384     
1385     /* first, do the sanity checks... */
1386     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1387     {
1388       WARN("bad dev ID !\n");
1389       return MMSYSERR_BADDEVICEID;
1390     }
1391
1392     wwo = &WOutDev[wDevID];
1393
1394     if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED))
1395     {
1396       TRACE("unprepared\n");
1397       return WAVERR_UNPREPARED;
1398     }
1399     
1400     if (lpWaveHdr->dwFlags & WHDR_INQUEUE) 
1401     {
1402       TRACE("still playing\n");
1403       return WAVERR_STILLPLAYING;
1404     }
1405
1406     lpWaveHdr->dwFlags &= ~WHDR_DONE;
1407     lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1408     lpWaveHdr->lpNext = 0;
1409
1410     EnterCriticalSection(&wwo->access_crst);
1411
1412     /* insert buffer at the end of queue */
1413     for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
1414     *wh = lpWaveHdr;
1415
1416     if (!wwo->lpPlayPtr)
1417       wodHelper_BeginWaveHdr(wwo,lpWaveHdr);
1418     if (wwo->state == WINE_WS_STOPPED)
1419       wwo->state = WINE_WS_PLAYING;
1420     LeaveCriticalSection(&wwo->access_crst);
1421
1422     return MMSYSERR_NOERROR;
1423 }
1424
1425 /**************************************************************************
1426  *                              wodPrepare                      [internal]
1427  */
1428 static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1429 {
1430   TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1431     
1432   if (wDevID >= MAX_WAVEOUTDRV)
1433   {
1434     WARN("bad device ID !\n");
1435     return MMSYSERR_BADDEVICEID;
1436   }
1437     
1438   if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
1439     return WAVERR_STILLPLAYING;
1440     
1441   lpWaveHdr->dwFlags |= WHDR_PREPARED;
1442   lpWaveHdr->dwFlags &= ~WHDR_DONE;
1443   return MMSYSERR_NOERROR;
1444 }
1445
1446 /**************************************************************************
1447  *                              wodUnprepare                    [internal]
1448  */
1449 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1450 {
1451   TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1452     
1453   if (wDevID >= MAX_WAVEOUTDRV)
1454   {
1455     WARN("bad device ID !\n");
1456     return MMSYSERR_BADDEVICEID;
1457   }
1458     
1459   if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
1460     return WAVERR_STILLPLAYING;
1461     
1462   lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1463   lpWaveHdr->dwFlags |= WHDR_DONE;
1464     
1465   return MMSYSERR_NOERROR;
1466 }
1467
1468 /**************************************************************************
1469  *                      wodPause                                [internal]
1470  */
1471 static DWORD wodPause(WORD wDevID)
1472 {
1473   TRACE("(%u);!\n", wDevID);
1474     
1475   if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1476   {
1477     WARN("bad device ID !\n");
1478     return MMSYSERR_BADDEVICEID;
1479   }
1480     
1481   TRACE("[3-PAUSING]\n");
1482
1483   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1484   wodHelper_Reset(&WOutDev[wDevID], FALSE);
1485   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1486
1487   return MMSYSERR_NOERROR;
1488 }
1489
1490 /**************************************************************************
1491  *                      wodRestart                              [internal]
1492  */
1493 static DWORD wodRestart(WORD wDevID)
1494 {
1495     TRACE("(%u);\n", wDevID);
1496
1497     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1498     {
1499       WARN("bad device ID !\n");
1500       return MMSYSERR_BADDEVICEID;
1501     }
1502
1503     if (WOutDev[wDevID].state == WINE_WS_PAUSED)
1504     {
1505       EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1506       WOutDev[wDevID].state = WINE_WS_PLAYING;
1507       LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1508     }
1509     
1510     return MMSYSERR_NOERROR;
1511 }
1512
1513 /**************************************************************************
1514  *                      wodReset                                [internal]
1515  */
1516 static DWORD wodReset(WORD wDevID)
1517 {
1518     TRACE("(%u);\n", wDevID);
1519     
1520     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1521     {
1522       WARN("bad device ID !\n");
1523       return MMSYSERR_BADDEVICEID;
1524     }
1525
1526     EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1527     wodHelper_Reset(&WOutDev[wDevID], TRUE);
1528     LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1529
1530     return MMSYSERR_NOERROR;
1531 }
1532
1533 /**************************************************************************
1534  *                              wodGetPosition                  [internal]
1535  */
1536 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1537 {
1538     int                 time;
1539     DWORD               val;
1540     WINE_WAVEOUT*       wwo;
1541     DWORD elapsedMS;
1542
1543     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
1544     
1545     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1546     {
1547       WARN("bad device ID !\n");
1548       return MMSYSERR_BADDEVICEID;
1549     }
1550     
1551     /* if null pointer to time structure return error */
1552     if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1553
1554     wwo = &WOutDev[wDevID];
1555
1556     EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1557     val = wwo->dwPlayedTotal;
1558     elapsedMS = GetTickCount() - wwo->tickCountMS;
1559     LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1560
1561     /* account for the bytes played since the last JACK_Callback() */
1562     val+=((elapsedMS * wwo->format.wf.nAvgBytesPerSec) / 1000);
1563
1564     TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%lu nChannels=%u nAvgBytesPerSec=%lu\n", 
1565       lpTime->wType, wwo->format.wBitsPerSample,
1566       wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
1567       wwo->format.wf.nAvgBytesPerSec);
1568     TRACE("dwPlayedTotal=%lu\n", val);
1569     
1570     switch (lpTime->wType) {
1571     case TIME_BYTES:
1572       lpTime->u.cb = val;
1573       TRACE("TIME_BYTES=%lu\n", lpTime->u.cb);
1574       break;
1575     case TIME_SAMPLES:
1576       lpTime->u.sample = val * 8 / wwo->format.wBitsPerSample /wwo->format.wf.nChannels;
1577       TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
1578       break;
1579     case TIME_SMPTE:
1580       time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
1581       lpTime->u.smpte.hour = time / 108000;
1582       time -= lpTime->u.smpte.hour * 108000;
1583       lpTime->u.smpte.min = time / 1800;
1584       time -= lpTime->u.smpte.min * 1800;
1585       lpTime->u.smpte.sec = time / 30;
1586       time -= lpTime->u.smpte.sec * 30;
1587       lpTime->u.smpte.frame = time;
1588       lpTime->u.smpte.fps = 30;
1589       TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1590         lpTime->u.smpte.hour, lpTime->u.smpte.min,
1591         lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1592       break;
1593     default:
1594       FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
1595       lpTime->wType = TIME_MS;
1596     case TIME_MS:
1597       lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
1598       TRACE("TIME_MS=%lu\n", lpTime->u.ms);
1599       break;
1600     }
1601     return MMSYSERR_NOERROR;
1602 }
1603
1604 /**************************************************************************
1605  *                              wodBreakLoop                    [internal]
1606  */
1607 static DWORD wodBreakLoop(WORD wDevID)
1608 {
1609   TRACE("(%u);\n", wDevID);
1610
1611   if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1612   {
1613     WARN("bad device ID !\n");
1614     return MMSYSERR_BADDEVICEID;
1615   }
1616
1617   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1618
1619   if (WOutDev[wDevID].state == WINE_WS_PLAYING && WOutDev[wDevID].lpLoopPtr != NULL)
1620   {
1621     /* ensure exit at end of current loop */
1622     WOutDev[wDevID].dwLoops = 1;
1623   }
1624
1625   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1626
1627   return MMSYSERR_NOERROR;
1628 }
1629     
1630 /**************************************************************************
1631  *                              wodGetVolume                    [internal]
1632  */
1633 static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
1634 {
1635   DWORD left, right;
1636     
1637   left = WOutDev[wDevID].volume_left;
1638   right = WOutDev[wDevID].volume_right;
1639         
1640   TRACE("(%u, %p);\n", wDevID, lpdwVol);
1641  
1642   *lpdwVol = ((left * 0xFFFFl) / 100) + (((right * 0xFFFFl) / 100) <<
1643               16);
1644     
1645   return MMSYSERR_NOERROR;
1646 }
1647
1648 /**************************************************************************
1649  *                              wodSetVolume                    [internal]
1650  */
1651 static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1652 {
1653   DWORD left, right;
1654  
1655   left  = (LOWORD(dwParam) * 100) / 0xFFFFl;
1656   right = (HIWORD(dwParam) * 100) / 0xFFFFl;
1657  
1658   TRACE("(%u, %08lX);\n", wDevID, dwParam);
1659
1660   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1661
1662   WOutDev[wDevID].volume_left = left;
1663   WOutDev[wDevID].volume_right = right;
1664
1665   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1666
1667   return MMSYSERR_NOERROR;
1668 }
1669
1670 /**************************************************************************
1671  *                              wodGetNumDevs                   [internal]
1672  */
1673 static DWORD wodGetNumDevs(void)
1674 {
1675   return MAX_WAVEOUTDRV;
1676 }
1677
1678 /**************************************************************************
1679  *                              wodMessage (WINEJACK.7)
1680  */
1681 DWORD WINAPI JACK_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser, 
1682                             DWORD dwParam1, DWORD dwParam2)
1683 {
1684   TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
1685   wDevID, wMsg, dwUser, dwParam1, dwParam2);
1686     
1687   switch (wMsg) {
1688   case DRVM_INIT:
1689     TRACE("DRVM_INIT\n");
1690     return JACK_WaveInit();
1691   case DRVM_EXIT:
1692     TRACE("DRVM_EXIT\n");
1693     return JACK_WaveRelease();
1694   case DRVM_ENABLE:
1695   /* FIXME: Pretend this is supported */
1696     TRACE("DRVM_ENABLE\n");
1697     return 0;
1698   case DRVM_DISABLE:
1699   /* FIXME: Pretend this is supported */
1700     TRACE("DRVM_DISABLE\n");
1701     return 0;
1702   case WODM_OPEN:             return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1,  dwParam2);
1703   case WODM_CLOSE:            return wodClose(wDevID);
1704   case WODM_WRITE:            return wodWrite(wDevID, (LPWAVEHDR)dwParam1,              dwParam2);
1705   case WODM_PAUSE:            return wodPause(wDevID);
1706   case WODM_GETPOS:           return wodGetPosition(wDevID, (LPMMTIME)dwParam1,                 dwParam2);
1707   case WODM_BREAKLOOP:        return wodBreakLoop(wDevID);
1708   case WODM_PREPARE:          return wodPrepare(wDevID, (LPWAVEHDR)dwParam1,            dwParam2);
1709   case WODM_UNPREPARE:        return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1,          dwParam2);
1710   case WODM_GETDEVCAPS:       return wodGetDevCaps(wDevID, (LPWAVEOUTCAPSA)dwParam1,    dwParam2);
1711   case WODM_GETNUMDEVS:       return wodGetNumDevs();
1712   case WODM_GETPITCH:         return MMSYSERR_NOTSUPPORTED;
1713   case WODM_SETPITCH:         return MMSYSERR_NOTSUPPORTED;
1714   case WODM_GETPLAYBACKRATE:    return MMSYSERR_NOTSUPPORTED;
1715   case WODM_SETPLAYBACKRATE:    return MMSYSERR_NOTSUPPORTED;
1716   case WODM_GETVOLUME:        return wodGetVolume(wDevID, (LPDWORD)dwParam1);
1717   case WODM_SETVOLUME:        return wodSetVolume(wDevID, dwParam1);
1718   case WODM_RESTART:          return wodRestart(wDevID);
1719   case WODM_RESET:            return wodReset(wDevID);
1720
1721   case DRV_QUERYDSOUNDIFACE:    return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
1722   case DRV_QUERYDSOUNDDESC:     return wodDsDesc(wDevID, (PDSDRIVERDESC)dwParam1);
1723   case DRV_QUERYDSOUNDGUID:     return wodDsGuid(wDevID, (LPGUID)dwParam1);
1724   default:
1725     FIXME("unknown message %d!\n", wMsg);
1726     }
1727     return MMSYSERR_NOTSUPPORTED;
1728 }
1729
1730 /*======================================================================*
1731  *                  Low level DSOUND implementation                     *
1732  *======================================================================*/
1733
1734 typedef struct IDsDriverImpl IDsDriverImpl;
1735 typedef struct IDsDriverBufferImpl IDsDriverBufferImpl;
1736
1737 struct IDsDriverImpl
1738 {
1739     /* IUnknown fields */
1740     ICOM_VFIELD(IDsDriver);
1741     DWORD               ref;
1742     /* IDsDriverImpl fields */
1743     UINT                wDevID;
1744     IDsDriverBufferImpl*primary;
1745 };
1746
1747 struct IDsDriverBufferImpl
1748 {
1749     /* IUnknown fields */
1750     ICOM_VFIELD(IDsDriverBuffer);
1751     DWORD ref;
1752     /* IDsDriverBufferImpl fields */
1753     IDsDriverImpl* drv;
1754     DWORD buflen;
1755 };
1756
1757 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
1758 {
1759     /* we can't perform memory mapping as we don't have a file stream 
1760       interface with jack like we do with oss */
1761     MESSAGE("This sound card's driver does not support direct access\n");
1762     MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
1763     return MMSYSERR_NOTSUPPORTED;
1764 }
1765
1766 static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
1767 {
1768     memset(desc, 0, sizeof(*desc));
1769     strcpy(desc->szDesc, "Wine jack DirectSound Driver");
1770     strcpy(desc->szDrvName, "winejack.drv");
1771     return MMSYSERR_NOERROR;
1772 }
1773
1774 static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid)
1775 {
1776     memcpy(pGuid, &DSDEVID_DefaultPlayback, sizeof(GUID));
1777     return MMSYSERR_NOERROR;
1778 }
1779
1780 /*======================================================================*
1781  *                  Low level WAVE IN implementation                    *
1782  *======================================================================*/
1783
1784 /**************************************************************************
1785  *                      widNotifyClient                 [internal]
1786  */
1787 static DWORD widNotifyClient(WINE_WAVEIN* wwi, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
1788 {
1789     TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2);
1790     
1791     switch (wMsg) {
1792     case WIM_OPEN:
1793     case WIM_CLOSE:
1794     case WIM_DATA:
1795       if (wwi->wFlags != DCB_NULL &&
1796         !DriverCallback(wwi->waveDesc.dwCallback, wwi->wFlags,
1797           (HDRVR)wwi->waveDesc.hWave, wMsg, wwi->waveDesc.dwInstance,
1798           dwParam1, dwParam2))
1799       {
1800         WARN("can't notify client !\n");
1801         return MMSYSERR_ERROR;
1802       }
1803     break;
1804     default:
1805       FIXME("Unknown callback message %u\n", wMsg);
1806         return MMSYSERR_INVALPARAM;
1807     }
1808     return MMSYSERR_NOERROR;
1809 }
1810
1811 /******************************************************************
1812  *    JACK_callback_wwi
1813  */
1814 /* everytime the jack server wants something from us it calls this 
1815    function */
1816 int JACK_callback_wwi (nframes_t nframes, void *arg)
1817 {
1818     sample_t* in_l;
1819     sample_t* in_r = 0;
1820     WINE_WAVEIN* wwi = (WINE_WAVEIN*)arg;
1821
1822     TRACE("wDevID: %u, nframes %u\n", wwi->wDevID, nframes);
1823     
1824     if(!wwi->client)
1825         ERR("client is closed, this is weird...\n");
1826     
1827     in_l = (sample_t *) fp_jack_port_get_buffer(wwi->in_port_l, nframes);
1828
1829     if (wwi->in_port_r)
1830       in_r = (sample_t *) fp_jack_port_get_buffer(wwi->in_port_r, nframes);
1831     
1832     EnterCriticalSection(&wwi->access_crst);
1833     
1834     if((wwi->lpQueuePtr != NULL) && (wwi->state == WINE_WS_PLAYING))
1835     {
1836         LPWAVEHDR lpWaveHdr = wwi->lpQueuePtr;
1837         nframes_t jackFramesLeft = nframes;
1838
1839 #if JACK_CLOSE_HACK
1840         if(wwi->in_use == FALSE)
1841         {
1842           /* do nothing if nothing is being recorded */
1843             return 0;
1844         }
1845 #endif
1846         
1847         TRACE("wwi.state == WINE_WS_PLAYING\n");
1848         
1849         while (lpWaveHdr && jackFramesLeft)
1850         {
1851             DWORD waveHdrFramesLeft = (lpWaveHdr->dwBufferLength - lpWaveHdr->dwBytesRecorded) / (sizeof(short) * wwi->format.wf.nChannels); 
1852             DWORD numFrames = min (jackFramesLeft, waveHdrFramesLeft);
1853             
1854             TRACE ("dwBufferLength=(%lu) dwBytesRecorded=(%ld)\n",   lpWaveHdr->dwBufferLength, lpWaveHdr->dwBytesRecorded);
1855             TRACE ("jackFramesLeft=(%u) waveHdrFramesLeft=(%lu)\n", jackFramesLeft, waveHdrFramesLeft);
1856
1857             if (!in_r) {
1858               /* mono */
1859               sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded), in_l+(nframes-jackFramesLeft), numFrames, 1);
1860             } else {
1861               /* stereo */
1862               sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded), 
1863                                   in_l+(nframes-jackFramesLeft), numFrames, 2);
1864               sample_move_s16_d16((short *)((char *)lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded + sizeof(short)), 
1865                                   in_r+(nframes-jackFramesLeft), numFrames, 2);
1866             }
1867             
1868             lpWaveHdr->dwBytesRecorded += (numFrames * sizeof(short) * wwi->format.wf.nChannels );
1869             jackFramesLeft -= numFrames;
1870
1871             if (lpWaveHdr->dwBytesRecorded >= lpWaveHdr->dwBufferLength)
1872             {
1873                 /* must copy the value of next waveHdr, because we have no idea of what
1874                  * will be done with the content of lpWaveHdr in callback
1875                  */
1876                 LPWAVEHDR       lpNext = lpWaveHdr->lpNext;
1877                                 
1878                 lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
1879                 lpWaveHdr->dwFlags |=  WHDR_DONE;
1880
1881                 TRACE("WaveHdr full. dwBytesRecorded=(%lu) dwFlags=(0x%lx)\n",lpWaveHdr->dwBytesRecorded,lpWaveHdr->dwFlags);
1882
1883                 widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
1884
1885                 lpWaveHdr = wwi->lpQueuePtr = lpNext;
1886             }
1887         }
1888         TRACE ("jackFramesLeft=(%u) lpWaveHdr=(%p)\n", jackFramesLeft, lpWaveHdr);
1889         if (jackFramesLeft > 0) { WARN("Record buffer ran out of WaveHdrs\n"); }
1890     }
1891     
1892     LeaveCriticalSection(&wwi->access_crst);
1893
1894     return 0;
1895 }
1896
1897 /******************************************************************
1898  *              JACK_OpenWaveInDevice
1899  */
1900 static int JACK_OpenWaveInDevice(WINE_WAVEIN* wwi, WORD nChannels)
1901 {
1902   const char** ports;
1903   int i;
1904   char client_name[64];
1905   jack_port_t* in_port_l;
1906   jack_port_t* in_port_r = 0;
1907   jack_client_t* client;
1908   int failed = 0;
1909
1910   TRACE("creating jack client and setting up callbacks\n");
1911
1912   if ((nChannels == 0) || (nChannels > 2)) {
1913     ERR ("nChannels = (%d), but we only support mono or stereo.\n", nChannels);
1914     return 0;
1915   }
1916
1917 #if JACK_CLOSE_HACK
1918   /* see if this device is already open */
1919         if(wwi->client)
1920         {
1921           /* if this device is already in use then it is bad for us to be in here */
1922           if(wwi->in_use)
1923             return 0;
1924
1925           TRACE("using existing client\n");
1926           wwi->in_use = TRUE;
1927           return 1;
1928         }
1929 #endif
1930
1931         /* zero out the buffer pointer and the size of the buffer */
1932         wwi->sound_buffer = 0;
1933         wwi->buffer_size = 0;
1934
1935         /* try to become a client of the JACK server */
1936         snprintf(client_name, sizeof(client_name), "wine_jack_in_%d", wwi->wDevID);
1937         TRACE("client name '%s'\n", client_name);
1938         if ((client = fp_jack_client_new (client_name)) == 0)
1939         {
1940                 /* jack has problems with shutting down clients, so lets */
1941                 /* wait a short while and try once more before we give up */
1942                 Sleep(250);
1943                 if ((client = fp_jack_client_new (client_name)) == 0)
1944                 {
1945                   ERR("jack server not running?\n");
1946                   return 0;
1947                 }
1948         }
1949         wwi->client = client;
1950                 
1951         /* tell the JACK server to call `JACK_wwi_callback()' whenever
1952            there is work to be done. */
1953         fp_jack_set_process_callback (client, JACK_callback_wwi, wwi);
1954         
1955         /* tell the JACK server to call `JACK_bufsize_wwi()' whenever   
1956            the maximum number of frames that will be passed
1957            to `JACK_Callback()' changes */
1958         fp_jack_set_buffer_size_callback (client, JACK_bufsize_wwi, wwi);
1959           
1960         /* tell the JACK server to call `srate()' whenever
1961            the sample rate of the system changes. */
1962         fp_jack_set_sample_rate_callback (client, JACK_srate, wwi);
1963
1964         /* tell the JACK server to call `jack_shutdown()' if
1965            it ever shuts down, either entirely, or if it
1966            just decides to stop calling us. */
1967         fp_jack_on_shutdown (client, JACK_shutdown_wwi, wwi);
1968         
1969         /* display the current sample rate. once the client is activated
1970            (see below), you should rely on your own sample rate
1971            callback (see above) for this value. */
1972         wwi->sample_rate = fp_jack_get_sample_rate(client);
1973         TRACE("engine sample rate: %lu\n", wwi->sample_rate);
1974           
1975         /* create the left and right channel output ports */
1976         /* jack's ports are all mono so for stereo you need two */
1977         in_port_l = fp_jack_port_register (client, "in_l",
1978                          JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
1979         wwi->in_port_l = in_port_l;
1980         TRACE("Created port. (%p)\n", in_port_l);
1981
1982         if (nChannels == 2)
1983         {
1984           in_port_r = fp_jack_port_register (client, "in_r",
1985                            JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); 
1986           TRACE("Created port. (%p)\n", in_port_r);
1987         } 
1988         wwi->in_port_r = in_port_r;
1989
1990 #if JACK_CLOSE_HACK
1991         wwi->in_use = TRUE; /* mark this device as in use since it now is ;-) */
1992 #endif
1993
1994         TRACE("activating client.\n");
1995         /* tell the JACK server that we are ready to roll */
1996         if (fp_jack_activate (client))
1997         {
1998           ERR( "cannot activate client\n");
1999           return 0;
2000         }
2001         TRACE("activated client.\n");
2002         /* figure out what the ports that we want to output on are */
2003         /* NOTE: we do this instead of using stuff like "alsa_pcm:playback_X" because */
2004         /*   this way works if names are changed */
2005         ports = fp_jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
2006
2007         /* display a trace of the output ports we found */
2008         for(i = 0; ports[i]; i++)
2009         {
2010           TRACE("ports[%d] = '%s'\n", i, ports[i]);
2011         }
2012
2013         if(!ports)
2014         {
2015           ERR("jack_get_ports() failed to find 'JackPortIsPhysical|JackPortIsOutput'\n");
2016         }
2017
2018         /* connect the ports. Note: you can't do this before
2019            the client is activated (this may change in the future).
2020         */ 
2021         /* we want to connect to two ports so we have stereo input ;-) */
2022
2023         if(fp_jack_connect(client, ports[0], fp_jack_port_name(in_port_l)))
2024         {
2025           ERR ("cannot connect to input port %d('%s')\n", 0, ports[0]);
2026           failed = 1;
2027         }
2028         TRACE("Connected (%s)<->(%s)\n",ports[0],fp_jack_port_name(in_port_l));
2029
2030         if ((nChannels == 2) && in_port_r) {
2031           if(fp_jack_connect(client, ports[1], fp_jack_port_name(in_port_r)))
2032           {
2033             ERR ("cannot connect to input port %d('%s')\n", 1, ports[1]);
2034             failed = 1;
2035           }
2036           TRACE("Connected (%s)<->(%s)\n",ports[1],fp_jack_port_name(in_port_r));
2037         }
2038         free(ports); /* free the returned array of ports */
2039
2040         /* if something failed we need to shut the client down and return 0 */
2041         if(failed)
2042         {
2043 #if JACK_CLOSE_HACK
2044           JACK_CloseWaveInDevice(wwi, TRUE);
2045 #else
2046           JACK_CloseWaveInDevice(wwi);
2047 #endif
2048           return 0;
2049         }
2050
2051         TRACE("return success.\n");
2052         return 1; /* return success */
2053 }
2054
2055 /**************************************************************************
2056  *                      widGetDevCaps                           [internal]
2057  */
2058 static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSA lpCaps, DWORD dwSize)
2059 {
2060     TRACE("(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
2061
2062     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
2063
2064     if (wDevID >= MAX_WAVEINDRV) {
2065         TRACE("MAX_WAVEINDRV reached !\n");
2066         return MMSYSERR_BADDEVICEID;
2067     }
2068
2069     memcpy(lpCaps, &WInDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
2070     return MMSYSERR_NOERROR;
2071 }
2072
2073 /**************************************************************************
2074  *                              widOpen                         [internal]
2075  */
2076 static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
2077 {
2078     WINE_WAVEIN*        wwi;
2079     DWORD retval;
2080
2081     TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
2082     if (lpDesc == NULL)
2083     {
2084         WARN("Invalid Parameter !\n");
2085         return MMSYSERR_INVALPARAM;
2086     }
2087     if (wDevID >= MAX_WAVEINDRV) {
2088         TRACE ("MAX_WAVEINDRV reached !\n");
2089         return MMSYSERR_BADDEVICEID;
2090     }
2091
2092 #if JACK_CLOSE_HACK
2093     if(WInDev[wDevID].client && WOutDev[wDevID].in_use)
2094 #else
2095     if(WInDev[wDevID].client)
2096 #endif
2097     {
2098       TRACE("device %d already allocated\n", wDevID);
2099       return MMSYSERR_ALLOCATED;
2100     }
2101
2102     /* Only the PCM format is supported so far...
2103      * Also we only support 16 bit mode.
2104      */
2105     if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
2106       lpDesc->lpFormat->nChannels == 0 ||
2107       lpDesc->lpFormat->nSamplesPerSec == 0 ||
2108       lpDesc->lpFormat->wBitsPerSample!=16)
2109     {
2110       WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%ld wBitsPerSample=%d !\n",
2111        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
2112        lpDesc->lpFormat->nSamplesPerSec, lpDesc->lpFormat->wBitsPerSample);
2113       return WAVERR_BADFORMAT;
2114     }
2115
2116     if (dwFlags & WAVE_FORMAT_QUERY)
2117     {
2118       TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
2119        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
2120        lpDesc->lpFormat->nSamplesPerSec);
2121       return MMSYSERR_NOERROR;
2122     }
2123
2124     wwi = &WInDev[wDevID];
2125     wwi->wDevID = wDevID;
2126
2127     /* Set things up before we call JACK_OpenWaveOutDevice because */
2128     /* we will start getting callbacks before JACK_OpenWaveOutDevice */
2129     /* even returns and we want to be initialized before then */
2130     wwi->state = WINE_WS_STOPPED; /* start in a stopped state */
2131
2132     InitializeCriticalSection(&wwi->access_crst); /* initialize the critical section */
2133     EnterCriticalSection(&wwi->access_crst);
2134
2135     /* open up jack ports for this device */
2136     if (!JACK_OpenWaveInDevice(&WInDev[wDevID], lpDesc->lpFormat->nChannels))
2137     {
2138       ERR("JACK_OpenWaveInDevice(%d) failed\n", wDevID);
2139       LeaveCriticalSection(&wwi->access_crst);
2140       DeleteCriticalSection(&wwi->access_crst);
2141       return MMSYSERR_ERROR;            /* return unspecified error */
2142     }
2143
2144     dwFlags &= ~WAVE_DIRECTSOUND;  /* direct sound not supported, ignore the flag */
2145
2146     wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
2147     
2148     memcpy(&wwi->waveDesc, lpDesc,           sizeof(WAVEOPENDESC));
2149     memcpy(&wwi->format,   lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
2150
2151     LeaveCriticalSection(&wwi->access_crst);
2152
2153     /* display the current wave format */
2154     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n", 
2155     wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec,
2156     wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels,
2157     wwi->format.wf.nBlockAlign);
2158
2159     /* make sure that we have the same sample rate in our audio stream */
2160     /* as we do in the jack server */
2161     if(wwi->format.wf.nSamplesPerSec != wwi->sample_rate)
2162     {
2163       TRACE("error: jack server sample rate is '%ld', wave sample rate is '%ld'\n",
2164          wwi->sample_rate, wwi->format.wf.nSamplesPerSec);
2165
2166 #if JACK_CLOSE_HACK
2167       JACK_CloseWaveInDevice(wwi, FALSE); /* close this device, don't force the client to close */
2168 #else
2169       JACK_CloseWaveInDevice(wwi); /* close this device */
2170 #endif
2171       DeleteCriticalSection(&wwi->access_crst);
2172       return WAVERR_BADFORMAT;
2173     }
2174
2175     /* check for an invalid number of bits per sample */
2176     if (wwi->format.wBitsPerSample == 0)
2177     {
2178       WARN("Resetting zeroed wBitsPerSample\n");
2179       wwi->format.wBitsPerSample = 8 *
2180       (wwi->format.wf.nAvgBytesPerSec /
2181        wwi->format.wf.nSamplesPerSec) /
2182        wwi->format.wf.nChannels;
2183     }
2184
2185     TRACE("notify client.\n");
2186     EnterCriticalSection(&wwi->access_crst);
2187     retval = widNotifyClient(wwi, WIM_OPEN, 0L, 0L);
2188     LeaveCriticalSection(&wwi->access_crst);
2189
2190     return retval;
2191 }
2192 /**************************************************************************
2193  *                              widClose                        [internal]
2194  */
2195 static DWORD widClose(WORD wDevID)
2196 {
2197     DWORD               ret = MMSYSERR_NOERROR;
2198     WINE_WAVEIN*        wwi;
2199
2200     TRACE("(%u);\n", wDevID);
2201
2202     if (wDevID >= MAX_WAVEINDRV || !WInDev[wDevID].client)
2203     {
2204       WARN("bad device ID !\n");
2205       return MMSYSERR_BADDEVICEID;
2206     }
2207     
2208     wwi = &WInDev[wDevID];
2209     if (wwi->lpQueuePtr)
2210     {
2211       WARN("buffers still playing !\n");
2212       ret = WAVERR_STILLPLAYING;
2213     } else
2214     {
2215         /* sanity check: this should not happen since the device must have been reset before */
2216         if (wwi->lpQueuePtr) ERR("out of sync\n");
2217         
2218         wwi->state = WINE_WS_CLOSED; /* mark the device as closed */
2219         
2220 #if JACK_CLOSE_HACK
2221         JACK_CloseWaveInDevice(wwi, FALSE); /* close the jack device, DO NOT force the client to close */
2222 #else
2223         JACK_CloseWaveInDevice(wwi); /* close the jack device */
2224 #endif
2225         DeleteCriticalSection(&wwi->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
2226         
2227         ret = widNotifyClient(wwi, WIM_CLOSE, 0L, 0L);
2228     }
2229
2230     return ret;
2231 }
2232
2233 /**************************************************************************
2234  *                              widAddBuffer            [internal]
2235  */
2236 static DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
2237 {
2238     WINE_WAVEIN* wwi = &WInDev[wDevID];
2239
2240     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
2241
2242     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2243                                 WARN("can't do it !\n");
2244                                 return MMSYSERR_INVALHANDLE;
2245     }
2246     if (!(lpWaveHdr->dwFlags & WHDR_PREPARED)) {
2247                                 TRACE("never been prepared !\n");
2248                                 return WAVERR_UNPREPARED;
2249     }
2250     if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
2251                                 TRACE("header already in use !\n");
2252                                 return WAVERR_STILLPLAYING;
2253     }
2254
2255     lpWaveHdr->dwFlags |= WHDR_INQUEUE;
2256     lpWaveHdr->dwFlags &= ~WHDR_DONE;
2257     lpWaveHdr->dwBytesRecorded = 0;
2258     lpWaveHdr->lpNext = NULL;
2259
2260     EnterCriticalSection(&wwi->access_crst);
2261     /* insert buffer at end of queue */
2262     {
2263         LPWAVEHDR* wh;
2264         for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
2265         *wh=lpWaveHdr;
2266     }
2267     LeaveCriticalSection(&wwi->access_crst);
2268
2269     return MMSYSERR_NOERROR;
2270 }
2271
2272 /**************************************************************************
2273  *                              widPrepare                      [internal]
2274  */
2275 static DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
2276 {
2277     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
2278                 
2279     if (wDevID >= MAX_WAVEINDRV) return MMSYSERR_INVALHANDLE;
2280                 
2281     if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
2282                                 return WAVERR_STILLPLAYING;
2283
2284     lpWaveHdr->dwFlags |= WHDR_PREPARED;
2285     lpWaveHdr->dwFlags &= ~WHDR_DONE;
2286     lpWaveHdr->dwBytesRecorded = 0;
2287     lpWaveHdr->lpNext = NULL;
2288
2289     return MMSYSERR_NOERROR;
2290 }
2291
2292 /**************************************************************************
2293  *                              widUnprepare                    [internal]
2294  */
2295 static DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
2296 {
2297     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
2298     if (wDevID >= MAX_WAVEINDRV) {
2299                                 WARN("bad device ID !\n");
2300                                 return MMSYSERR_INVALHANDLE;
2301     }
2302
2303     if (lpWaveHdr->dwFlags & WHDR_INQUEUE) {
2304                                 TRACE("Still playing...\n");
2305                                 return WAVERR_STILLPLAYING;
2306     }
2307
2308     lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
2309     lpWaveHdr->dwFlags |= WHDR_DONE;
2310
2311     return MMSYSERR_NOERROR;
2312 }
2313
2314 /**************************************************************************
2315  *                      widStart                                [internal]
2316  */
2317 static DWORD widStart(WORD wDevID)
2318 {
2319     TRACE("(%u);\n", wDevID);
2320     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2321         WARN("can't start recording !\n");
2322         return MMSYSERR_INVALHANDLE;
2323     }
2324
2325     WInDev[wDevID].state = WINE_WS_PLAYING;
2326     return MMSYSERR_NOERROR;
2327 }
2328
2329 /**************************************************************************
2330  *                      widStop                                 [internal]
2331  */
2332 static DWORD widStop(WORD wDevID)
2333 {
2334     WINE_WAVEIN* wwi = &WInDev[wDevID];
2335
2336     TRACE("(%u);\n", wDevID);
2337     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2338         WARN("can't stop !\n");
2339         return MMSYSERR_INVALHANDLE;
2340     }
2341     
2342     if (wwi->state != WINE_WS_STOPPED)
2343     {
2344         WAVEHDR*                lpWaveHdr;
2345         /* do something here to stop recording ??? */
2346         
2347         /* return current buffer to app */
2348         lpWaveHdr = wwi->lpQueuePtr;
2349         if (lpWaveHdr)
2350         {
2351             LPWAVEHDR   lpNext = lpWaveHdr->lpNext;
2352             TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
2353             lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
2354             lpWaveHdr->dwFlags |= WHDR_DONE;
2355             widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
2356             wwi->lpQueuePtr = lpNext;
2357         }
2358     }
2359     wwi->state = WINE_WS_STOPPED;
2360
2361     return MMSYSERR_NOERROR;
2362 }
2363
2364 /**************************************************************************
2365  *                      widReset                                [internal]
2366  */
2367 static DWORD widReset(WORD wDevID)
2368 {
2369     WINE_WAVEIN* wwi = &WInDev[wDevID];
2370     WAVEHDR*            lpWaveHdr;
2371
2372     TRACE("(%u);\n", wDevID);
2373     if (wDevID >= MAX_WAVEINDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
2374         WARN("can't reset !\n");
2375         return MMSYSERR_INVALHANDLE;
2376     }
2377
2378     wwi->state = WINE_WS_STOPPED;
2379
2380     /* return all buffers to the app */
2381     for (lpWaveHdr = wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) {
2382         TRACE("reset %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
2383         lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
2384         lpWaveHdr->dwFlags |= WHDR_DONE;
2385         
2386         widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
2387     }
2388     wwi->lpQueuePtr = NULL;
2389
2390     return MMSYSERR_NOERROR;
2391 }
2392
2393 /**************************************************************************
2394  *                              widMessage (WINEJACK.6)
2395  */
2396 DWORD WINAPI JACK_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
2397                             DWORD dwParam1, DWORD dwParam2)
2398 {
2399   TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
2400   wDevID, wMsg, dwUser, dwParam1, dwParam2);
2401
2402     switch (wMsg) {
2403     case DRVM_INIT:
2404     case DRVM_EXIT:
2405     case DRVM_ENABLE:
2406     case DRVM_DISABLE:
2407         /* FIXME: Pretend this is supported */
2408         return 0;
2409     case WIDM_OPEN:             return widOpen          (wDevID, (LPWAVEOPENDESC)dwParam1,      dwParam2);
2410     case WIDM_CLOSE:            return widClose         (wDevID);
2411     case WIDM_ADDBUFFER:        return widAddBuffer     (wDevID, (LPWAVEHDR)dwParam1, dwParam2);
2412     case WIDM_PREPARE:          return widPrepare       (wDevID, (LPWAVEHDR)dwParam1, dwParam2);
2413     case WIDM_UNPREPARE:        return widUnprepare     (wDevID, (LPWAVEHDR)dwParam1, dwParam2);
2414     case WIDM_GETDEVCAPS:       return widGetDevCaps    (wDevID, (LPWAVEINCAPSA)dwParam1,       dwParam2);
2415     case WIDM_GETNUMDEVS:       return MAX_WAVEINDRV;
2416     case WIDM_RESET:            return widReset         (wDevID);
2417     case WIDM_START:            return widStart         (wDevID);
2418     case WIDM_STOP:             return widStop          (wDevID);
2419     default:
2420         FIXME("unknown message %d!\n", wMsg);
2421     }
2422
2423   return MMSYSERR_NOTSUPPORTED;
2424 }
2425
2426 #else /* !HAVE_JACK_JACK_H */
2427
2428 /**************************************************************************
2429  *                              widMessage (WINEJACK.6)
2430  */
2431 DWORD WINAPI JACK_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
2432                             DWORD dwParam1, DWORD dwParam2)
2433 {
2434   FIXME("(%u, %04X, %08lX, %08lX, %08lX):jack support not compiled into wine\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
2435   return MMSYSERR_NOTENABLED;
2436 }
2437
2438 /**************************************************************************
2439  *                              wodMessage (WINEJACK.7)
2440  */
2441 DWORD WINAPI JACK_wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
2442                             DWORD dwParam1, DWORD dwParam2)
2443 {
2444   FIXME("(%u, %04X, %08lX, %08lX, %08lX):jack support not compiled into wine\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
2445   return MMSYSERR_NOTENABLED;
2446 }
2447
2448 #endif /* HAVE_JACK_JACK_H */