Added waveIn tests.
[wine] / dlls / winmm / winejack / audio.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
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  *  implement wave-in support with jack
33  *
34  * FIXME:
35  *  pause in waveOut during loop is not handled correctly
36  */
37
38 #include "config.h"
39
40 #include <stdlib.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 "wingdi.h"
49 #include "winerror.h"
50 #include "wine/winuser16.h"
51 #include "mmddk.h"
52 #include "dsound.h"
53 #include "dsdriver.h"
54 #include "jack.h"
55 #include "wine/debug.h"
56
57 #ifdef HAVE_JACK_JACK_H
58 #include <jack/jack.h>
59 #endif
60
61
62 WINE_DEFAULT_DEBUG_CHANNEL(wave);
63
64 #ifdef HAVE_JACK_JACK_H
65
66 #define MAKE_FUNCPTR(f) static typeof(f) * fp_##f = NULL;
67
68 /* Function pointers for dynamic loading of libjack */
69 /* these are prefixed with "fp_", ie. "fp_jack_client_new" */
70 MAKE_FUNCPTR(jack_activate);
71 MAKE_FUNCPTR(jack_connect);
72 MAKE_FUNCPTR(jack_client_new);
73 MAKE_FUNCPTR(jack_client_close);
74 MAKE_FUNCPTR(jack_deactivate);
75 MAKE_FUNCPTR(jack_set_process_callback);
76 MAKE_FUNCPTR(jack_set_buffer_size_callback);
77 MAKE_FUNCPTR(jack_set_sample_rate_callback);
78 MAKE_FUNCPTR(jack_on_shutdown);
79 MAKE_FUNCPTR(jack_get_sample_rate);
80 MAKE_FUNCPTR(jack_port_register);
81 MAKE_FUNCPTR(jack_port_get_buffer);
82 MAKE_FUNCPTR(jack_get_ports);
83 MAKE_FUNCPTR(jack_port_name);
84 #undef MAKE_FUNCPTR
85
86 /* define the below to work around a bug in jack where closing a port */
87 /* takes a very long time, so to get around this we actually don't */
88 /* close the port when the device is closed but instead mark the */
89 /* corresponding device as unused */
90 #define JACK_CLOSE_HACK    1
91
92 typedef jack_default_audio_sample_t sample_t;
93 typedef jack_nframes_t nframes_t;
94
95 /* only allow 10 output devices through this driver, this ought to be adequate */
96 #define MAX_WAVEOUTDRV  (10)
97 #define MAX_WAVEINDRV   (1)
98
99 /* state diagram for waveOut writing:
100  *
101  * +---------+-------------+---------------+---------------------------------+
102  * |  state  |  function   |     event     |            new state            |
103  * +---------+-------------+---------------+---------------------------------+
104  * |         | open()      |               | STOPPED                         |
105  * | PAUSED  | write()     |               | PAUSED                          |
106  * | STOPPED | write()     | <thrd create> | PLAYING                         |
107  * | PLAYING | write()     | HEADER        | PLAYING                         |
108  * | (other) | write()     | <error>       |                                 |
109  * | (any)   | pause()     | PAUSING       | PAUSED                          |
110  * | PAUSED  | restart()   | RESTARTING    | PLAYING (if no thrd => STOPPED) |
111  * | (any)   | reset()     | RESETTING     | STOPPED                         |
112  * | (any)   | close()     | CLOSING       | CLOSED                          |
113  * +---------+-------------+---------------+---------------------------------+
114  */
115
116 /* states of the playing device */
117 #define WINE_WS_PLAYING   0
118 #define WINE_WS_PAUSED    1
119 #define WINE_WS_STOPPED   2
120 #define WINE_WS_CLOSED    3
121
122 typedef struct {
123     volatile int      state;      /* one of the WINE_WS_ manifest constants */
124     WAVEOPENDESC      waveDesc;
125     WORD              wFlags;
126     PCMWAVEFORMAT     format;
127     WAVEOUTCAPSA      caps;
128     WORD              wDevID;
129
130     jack_port_t*      out_port_l;   /* ports for left and right channels */
131     jack_port_t*      out_port_r;
132     jack_client_t*    client;
133     long              sample_rate;        /* jack server sample rate */
134
135 #if JACK_CLOSE_HACK
136     BOOL              in_use; /* TRUE if this device is in use */
137 #endif
138
139     char*             sound_buffer;
140     unsigned long     buffer_size;
141
142     DWORD             volume_left;
143     DWORD             volume_right;
144
145     LPWAVEHDR         lpQueuePtr;   /* start of queued WAVEHDRs (waiting to be notified) */
146     LPWAVEHDR         lpPlayPtr;    /* start of not yet fully played buffers */
147     DWORD             dwPartialOffset;  /* Offset of not yet written bytes in lpPlayPtr */
148
149     LPWAVEHDR         lpLoopPtr;    /* pointer of first buffer in loop, if any */
150     DWORD             dwLoops;      /* private copy of loop counter */
151     
152     DWORD             dwPlayedTotal;    /* number of bytes actually played since opening */
153     DWORD             dwWrittenTotal;   /* number of bytes written to jack since opening */
154
155     DWORD             bytesInJack; /* bytes that we wrote during the previous JACK_Callback() */
156     DWORD             tickCountMS; /* time in MS of last JACK_Callback() */
157
158     /* synchronization stuff */
159     CRITICAL_SECTION    access_crst;
160 } WINE_WAVEOUT;
161
162 typedef struct {
163     volatile int    state;
164     WAVEOPENDESC    waveDesc;
165     WORD            wFlags;
166     PCMWAVEFORMAT   format;
167     LPWAVEHDR       lpQueuePtr;
168     DWORD           dwTotalRecorded;
169     WAVEINCAPSA     caps;
170     BOOL            bTriggerSupport;
171
172     /* synchronization stuff */
173     CRITICAL_SECTION    access_crst;
174 } WINE_WAVEIN;
175
176 static WINE_WAVEOUT WOutDev   [MAX_WAVEOUTDRV];
177 static WINE_WAVEIN  WInDev    [MAX_WAVEINDRV ];
178
179 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
180 static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo);
181 static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force);
182  
183 static int JACK_OpenDevice(WINE_WAVEOUT* wwo);
184
185 #if JACK_CLOSE_HACK
186 static void     JACK_CloseDevice(WINE_WAVEOUT* wwo, BOOL close_client);
187 #else
188 static void     JACK_CloseDevice(WINE_WAVEOUT* wwo);
189 #endif
190
191
192 /*======================================================================*
193  *                  Low level WAVE implementation                       *
194  *======================================================================*/
195
196 #define SAMPLE_MAX_16BIT  32767.0f
197
198 /* Alsaplayer function that applies volume changes to a buffer */
199 /* (C) Andy Lo A Foe */
200 /* Length is in terms of 32 bit samples */
201 void volume_effect32(void *buffer, int length, int left, int right)
202 {
203         short *data = (short *)buffer;
204         int i, v;
205     
206         if (right == -1) right = left;
207  
208         for(i = 0; i < length; i++) {
209                 v = (int) ((*(data) * left) / 100);
210                 *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
211                 v = (int) ((*(data) * right) / 100);
212                 *(data++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
213         }
214 }
215
216 /* move 16 bit mono/stereo to 16 bit stereo */
217 void sample_move_d16_d16(short *dst, short *src,
218                   unsigned long nsamples, int nChannels)
219 {
220   while(nsamples--)
221   {
222     *dst = *src;
223     dst++;
224
225     if(nChannels == 2) src++;
226
227     *dst = *src;
228     dst++;
229
230     src++;
231   }
232 }
233
234 /* convert from 16 bit to floating point */
235 /* allow for copying of stereo data with alternating left/right */
236 /* channels to a buffer that will hold a single channel stream */
237 /* nsamples is in terms of 16bit samples */
238 /* src_skip is in terms of 16bit samples */
239 void sample_move_d16_s16 (sample_t *dst, short *src,
240                         unsigned long nsamples, unsigned long src_skip)
241 {
242   /* ALERT: signed sign-extension portability !!! */
243   while (nsamples--)
244   {
245     *dst = (*src) / SAMPLE_MAX_16BIT;
246     dst++;
247     src += src_skip;
248   }
249 }       
250
251 /* fill dst buffer with nsamples worth of silence */
252 void sample_silence_dS (sample_t *dst, unsigned long nsamples)
253 {
254   /* ALERT: signed sign-extension portability !!! */
255   while (nsamples--)
256   {
257     *dst = 0;
258     dst++;
259   }
260 }       
261
262 /******************************************************************
263  *    JACK_callback
264  */
265 /* everytime the jack server wants something from us it calls this 
266 function, so we either deliver it some sound to play or deliver it nothing 
267 to play */
268 int JACK_callback (nframes_t nframes, void *arg)
269 {
270   sample_t* out_l;
271   sample_t* out_r;
272   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
273
274   TRACE("wDevID: %d, nframes %ld\n", wwo->wDevID, nframes);
275
276   if(!wwo->client)
277     ERR("client is closed, this is weird...\n");
278     
279   out_l = (sample_t *) fp_jack_port_get_buffer(wwo->out_port_l, 
280       nframes);
281   out_r = (sample_t *) fp_jack_port_get_buffer(wwo->out_port_r, 
282       nframes);
283
284   EnterCriticalSection(&wwo->access_crst);
285
286   if(wwo->state == WINE_WS_PLAYING)
287   {
288     DWORD jackBytesAvailableThisCallback = sizeof(sample_t) * nframes;
289     DWORD jackBytesLeft = sizeof(sample_t) * nframes;
290
291     DWORD inputBytesAvailable; /* number of bytes we have from the app, after conversion to 16bit stereo */
292     DWORD jackBytesToWrite; /* number of bytes we are going to write out, after conversion */
293
294     DWORD bytesInput; /* the number of bytes from the app */
295     DWORD appBytesToWrite; /* number of bytes from the app we are going to write */
296
297     long written = 0;
298     char* buffer;
299
300 #if JACK_CLOSE_HACK
301     if(wwo->in_use == FALSE)
302     {
303       /* output silence if nothing is being outputted */
304       sample_silence_dS(out_l, nframes);
305       sample_silence_dS(out_r, nframes);
306
307       return 0;
308     }
309 #endif
310
311     TRACE("wwo.state == WINE_WS_PLAYING\n");
312
313     /* see if our buffer is large enough for the data we are writing */
314     /* ie. Buffer_size < (bytes we already wrote + bytes we are going to write in this loop) */
315     if(wwo->buffer_size < jackBytesAvailableThisCallback)
316     {
317       ERR("for some reason JACK_BufSize() didn't allocate enough memory\n");
318       ERR("allocated %ld bytes, need %ld bytes\n", wwo->buffer_size, 
319       jackBytesAvailableThisCallback);
320       LeaveCriticalSection(&wwo->access_crst);
321       return 0;
322     }
323
324     /* while we have jackBytesLeft and a wave header to be played */
325     while(jackBytesLeft && wwo->lpPlayPtr)
326     {
327       /* find the amount of audio to be played at this time */
328       bytesInput = wwo->lpPlayPtr->dwBufferLength - wwo->dwPartialOffset;
329       inputBytesAvailable = bytesInput;
330
331       /* calculate inputBytesAvailable based on audio format conversion */
332       if(wwo->format.wf.nChannels == 1)
333         inputBytesAvailable<<=1; /* multiply by two for mono->stereo conversion */
334
335       /* find the minimum of the inputBytesAvailable and the space available */
336       jackBytesToWrite = min(jackBytesLeft, inputBytesAvailable);
337
338       /* calculate appBytesToWrite based on audio format conversion */
339       appBytesToWrite = jackBytesToWrite;
340       if(wwo->format.wf.nChannels == 1)
341         appBytesToWrite>>=1; /* divide by two for stereo->mono conversion */
342
343       TRACE("jackBytesToWrite == %ld, appBytesToWrite == %ld\n", jackBytesToWrite, appBytesToWrite);
344
345       buffer = wwo->lpPlayPtr->lpData + wwo->dwPartialOffset;
346
347       /* convert from mono to stereo if necessary */
348       /* otherwise just memcpy to the output buffer */
349       if(wwo->format.wf.nChannels == 1)
350       {
351         sample_move_d16_d16((short*)wwo->sound_buffer +((jackBytesAvailableThisCallback - jackBytesLeft) / sizeof(short)),
352                  (short*)buffer, jackBytesToWrite, wwo->format.wf.nChannels);
353       } else /* just copy the memory over */
354       {
355         memcpy(wwo->sound_buffer + (jackBytesAvailableThisCallback - jackBytesLeft),
356                   buffer, jackBytesToWrite);
357       }
358
359       /* advance to the next wave header if possible, or advance pointer */
360       /* inside of the current header if we haven't completed it */
361       if(appBytesToWrite == bytesInput)
362       {
363         wodHelper_PlayPtrNext(wwo);            /* we wrote the whole waveheader, skip to the next one*/
364       }
365       else
366       {
367         wwo->dwPartialOffset+=appBytesToWrite; /* else advance by the bytes we took in to write */
368       }
369
370       written+=appBytesToWrite; /* add on what we wrote */
371       jackBytesLeft-=jackBytesToWrite; /* take away what was written in terms of output bytes */
372     }
373
374     wwo->tickCountMS = GetTickCount();    /* record the current time */
375     wwo->dwWrittenTotal+=written; /* update states on wave device */
376     wwo->dwPlayedTotal+=wwo->bytesInJack; /* we must have finished with the last bytes or we wouldn't be back inside of this callback again... */
377     wwo->bytesInJack = written; /* record the bytes inside of jack */
378
379     /* Now that we have finished filling the buffer either until it is full or until */
380     /* we have run out of application sound data to process, apply volume and output */
381     /* the audio to the jack server */
382
383     /* apply volume to the buffer */
384     /* NOTE: buffer_size >> 2 to convert from bytes to 16 bit stereo(32bit) samples */
385     volume_effect32(wwo->sound_buffer, (jackBytesAvailableThisCallback - jackBytesLeft)>>2, wwo->volume_left,
386         wwo->volume_right);
387
388     /* convert from stereo 16 bit to single channel 32 bit float */
389     /* for each jack server channel */
390     /* NOTE: we skip over two sample since we want to only get either the left or right channel */
391     sample_move_d16_s16(out_l, (short*)wwo->sound_buffer, (jackBytesAvailableThisCallback - jackBytesLeft)>>2, 2);
392     sample_move_d16_s16(out_r, (short*)wwo->sound_buffer + 1,
393         (jackBytesAvailableThisCallback - jackBytesLeft)>>2, 2);
394
395     /* see if we still have jackBytesLeft here, if we do that means that we
396     ran out of wave data to play and had a buffer underrun, fill in
397     the rest of the space with zero bytes */
398     if(jackBytesLeft)
399     {
400       ERR("buffer underrun of %ld bytes\n", jackBytesLeft);
401       sample_silence_dS(out_l + ((jackBytesAvailableThisCallback - jackBytesLeft) / sizeof(sample_t)), jackBytesLeft / sizeof(sample_t));
402       sample_silence_dS(out_r + ((jackBytesAvailableThisCallback - jackBytesLeft) / sizeof(sample_t)), jackBytesLeft / sizeof(sample_t));
403     }
404   }
405   else if(wwo->state == WINE_WS_PAUSED || 
406     wwo->state == WINE_WS_STOPPED ||
407     wwo->state == WINE_WS_CLOSED)
408   {
409       /* output silence if nothing is being outputted */
410       sample_silence_dS(out_l, nframes);
411       sample_silence_dS(out_r, nframes);
412   }
413
414   /* notify the client of completed wave headers */
415   wodHelper_NotifyCompletions(wwo, FALSE);
416
417   LeaveCriticalSection(&wwo->access_crst);
418
419   TRACE("ending\n");
420
421   return 0;
422 }
423
424 /******************************************************************
425  *              JACK_bufsize
426  *
427  *              Called whenever the jack server changes the the max number 
428  *              of frames passed to JACK_callback
429  */
430 int JACK_bufsize (nframes_t nframes, void *arg)
431 {
432   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
433   DWORD buffer_required;
434   TRACE("the maximum buffer size is now %lu frames\n", nframes);
435
436   /* make sure the callback routine has adequate memory */
437     /* see if our buffer is large enough for the data we are writing */
438     /* ie. Buffer_size < (bytes we already wrote + bytes we are going to write in this loop) */
439   EnterCriticalSection(&wwo->access_crst);
440
441   buffer_required = sizeof(sample_t) * nframes;
442   if(wwo->buffer_size < buffer_required)
443   {
444     TRACE("expanding buffer from wwo->buffer_size == %ld, to %ld\n", 
445       wwo->buffer_size, buffer_required);
446     TRACE("GetProcessHeap() == %p\n", GetProcessHeap());
447     wwo->buffer_size = buffer_required;
448     wwo->sound_buffer = HeapReAlloc(GetProcessHeap(), 0, wwo->sound_buffer, wwo->buffer_size);
449
450     /* if we don't have a buffer then error out */
451     if(!wwo->sound_buffer)
452     {
453         ERR("error allocating sound_buffer memory\n");
454         LeaveCriticalSection(&wwo->access_crst);
455         return 0;
456     }
457   }
458
459   LeaveCriticalSection(&wwo->access_crst);
460
461   TRACE("called\n");
462
463   return 0;
464 }
465
466 /******************************************************************
467  *              JACK_srate
468  */
469 int JACK_srate (nframes_t nframes, void *arg)
470 {
471   TRACE("the sample rate is now %lu/sec\n", nframes);
472   return 0;
473 }
474
475
476 /******************************************************************
477  *              JACK_shutdown
478  */
479 /* if this is called then jack shut down... handle this appropriately */
480 void JACK_shutdown(void* arg)
481 {
482   WINE_WAVEOUT* wwo = (WINE_WAVEOUT*)arg;
483
484   wwo->client = 0; /* reset client */
485
486   TRACE("trying to reconnect after sleeping for a short while...\n");
487   
488   /* lets see if we can't reestablish the connection */
489   Sleep(750); /* pause for a short period of time */
490   if(!JACK_OpenDevice(wwo))
491   {
492     ERR("unable to reconnect with jack...\n");
493   }
494 }
495
496
497 /******************************************************************
498  *              JACK_OpenDevice
499  */
500 static int JACK_OpenDevice(WINE_WAVEOUT* wwo)
501 {
502   const char** ports;
503   int i;
504   char client_name[64];
505   jack_port_t* out_port_l;
506   jack_port_t* out_port_r;
507   jack_client_t* client;
508   int failed = 0;
509
510   TRACE("creating jack client and setting up callbacks\n");
511
512 #if JACK_CLOSE_HACK
513   /* see if this device is already open */
514         if(wwo->client)
515         {
516           /* if this device is already in use then it is bad for us to be in here */
517           if(wwo->in_use)
518             return 0;
519
520           TRACE("using existing client\n");
521           wwo->in_use = TRUE;
522           return 1;
523         }
524 #endif
525
526         /* zero out the buffer pointer and the size of the buffer */
527         wwo->sound_buffer = 0;
528         wwo->buffer_size = 0;
529
530         /* try to become a client of the JACK server */
531         snprintf(client_name, sizeof(client_name), "wine_jack_client %d", wwo->wDevID);
532         TRACE("client name '%s'\n", client_name);
533         if ((client = fp_jack_client_new (client_name)) == 0)
534         {
535                 /* jack has problems with shutting down clients, so lets */
536                 /* wait a short while and try once more before we give up */
537                 Sleep(250);
538                 if ((client = fp_jack_client_new (client_name)) == 0)
539                 {
540                   ERR("jack server not running?\n");
541                   return 0;
542                 }
543         }
544                 
545         /* tell the JACK server to call `JACK_callback()' whenever
546            there is work to be done. */
547         fp_jack_set_process_callback (client, JACK_callback, wwo);
548         
549         /* tell the JACK server to call `JACK_bufsize()' whenever   
550            the maximum number of frames that will be passed
551            to `JACK_Callback()' changes */
552         fp_jack_set_buffer_size_callback (client, JACK_bufsize, wwo);
553           
554         /* tell the JACK server to call `srate()' whenever
555            the sample rate of the system changes. */
556         fp_jack_set_sample_rate_callback (client, JACK_srate, wwo);
557
558         /* tell the JACK server to call `jack_shutdown()' if
559            it ever shuts down, either entirely, or if it
560            just decides to stop calling us. */
561         fp_jack_on_shutdown (client, JACK_shutdown, wwo);
562         
563         /* display the current sample rate. once the client is activated
564            (see below), you should rely on your own sample rate
565            callback (see above) for this value. */
566         wwo->sample_rate = fp_jack_get_sample_rate(client);
567         TRACE("engine sample rate: %lu\n", wwo->sample_rate);
568           
569         /* create the left and right channel output ports */
570         /* jack's ports are all mono so for stereo you need two */
571         out_port_l = fp_jack_port_register (client, "out_l",
572                          JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
573
574         out_port_r = fp_jack_port_register (client, "out_r",
575                          JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
576
577         /* save away important values to the WINE_WAVEOUT struct */
578         wwo->client = client;
579         wwo->out_port_l = out_port_l;
580         wwo->out_port_r = out_port_r;
581
582 #if JACK_CLOSE_HACK
583         wwo->in_use = TRUE; /* mark this device as in use since it now is ;-) */
584 #endif
585
586         /* tell the JACK server that we are ready to roll */
587         if (fp_jack_activate (client))
588         {
589           ERR( "cannot activate client\n");
590           return 0;
591         }
592
593         /* figure out what the ports that we want to output on are */
594         /* NOTE: we do this instead of using stuff like "alsa_pcm:playback_X" because */
595         /*   this way works if names are changed */
596         ports = fp_jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
597
598         /* display a trace of the output ports we found */
599         for(i = 0; ports[i]; i++)
600         {
601           TRACE("ports[%d] = '%s'\n", i, ports[i]);
602         }
603
604         if(!ports)
605         {
606           ERR("jack_get_ports() failed to find 'JackPortIsPhysical|JackPortIsInput'\n");
607         }
608
609         /* connect the ports. Note: you can't do this before
610            the client is activated (this may change in the future).
611         */ 
612         /* we want to connect to two ports so we have stereo output ;-) */
613
614         if(fp_jack_connect(client, fp_jack_port_name(out_port_l), ports[0]))
615         {
616           ERR ("cannot connect to output port %d('%s')\n", 0, ports[0]);
617           failed = 1;
618         }
619
620         if(fp_jack_connect(client, fp_jack_port_name(out_port_r), ports[1]))
621         {
622           ERR ("cannot connect to output port %d('%s')\n", 1, ports[1]);
623           failed = 1;
624         }
625
626         free(ports); /* free the returned array of ports */
627
628         /* if something failed we need to shut the client down and return 0 */
629         if(failed)
630         {
631           JACK_CloseDevice(wwo, TRUE);
632           return 0;
633         }
634
635         return 1; /* return success */
636 }
637
638 /******************************************************************
639  *              JACK_CloseDevice
640  *
641  *      Close the connection to the server cleanly.
642  *  If close_client is TRUE we close the client for this device instead of
643  *    just marking the device as in_use(JACK_CLOSE_HACK only)
644  */
645 #if JACK_CLOSE_HACK
646 static void     JACK_CloseDevice(WINE_WAVEOUT* wwo, BOOL close_client)
647 #else
648 static void     JACK_CloseDevice(WINE_WAVEOUT* wwo)
649 #endif
650 {
651 #if JACK_CLOSE_HACK
652   TRACE("wDevID: %d, close_client: %d\n", wwo->wDevID, close_client);
653 #else
654   TRACE("wDevID: %d\n", wwo->wDevID);
655 #endif
656
657 #if JACK_CLOSE_HACK
658   if(close_client)
659   {
660 #endif
661     fp_jack_deactivate(wwo->client); /* supposed to help the jack_client_close() to succeed */
662     fp_jack_client_close (wwo->client);
663
664     EnterCriticalSection(&wwo->access_crst);
665     wwo->client = 0; /* reset client */
666     HeapFree(GetProcessHeap(), 0, wwo->sound_buffer); /* free buffer memory */
667     wwo->sound_buffer = 0;
668     wwo->buffer_size = 0; /* zero out size of the buffer */
669     LeaveCriticalSection(&wwo->access_crst);
670 #if JACK_CLOSE_HACK
671   } else
672   {
673     EnterCriticalSection(&wwo->access_crst);
674     TRACE("setting in_use to FALSE\n");
675     wwo->in_use = FALSE;
676     LeaveCriticalSection(&wwo->access_crst);
677   }
678 #endif
679 }
680
681 /******************************************************************
682  *              JACK_WaveRelease
683  *
684  *
685  */
686 LONG    JACK_WaveRelease(void)
687
688   int iDevice;
689
690   TRACE("closing all open devices\n");
691
692   /* close all open devices */
693   for(iDevice = 0; iDevice < MAX_WAVEOUTDRV; iDevice++)
694   {
695     TRACE("iDevice == %d\n", iDevice);
696     if(WOutDev[iDevice].client)
697     {
698 #if JACK_CLOSE_HACK
699       JACK_CloseDevice(&WOutDev[iDevice], TRUE); /* close the device, FORCE the client to close */
700 #else
701       JACK_CloseDevice(&WOutDev[iDevice]); /* close the device, FORCE the client to close */
702 #endif
703       DeleteCriticalSection(&(WOutDev[iDevice].access_crst)); /* delete the critical section */
704     }
705   }
706
707   TRACE("returning 1\n");
708
709   return 1;
710 }
711
712 /******************************************************************
713  *              JACK_WaveInit
714  *
715  * Initialize internal structures from JACK server info
716  */
717 LONG JACK_WaveInit(void)
718 {
719     int i;
720
721     TRACE("called\n");
722
723     /* setup function pointers */
724 #define LOAD_FUNCPTR(f) if((fp_##f = wine_dlsym(jackhandle, #f, NULL, 0)) == NULL) goto sym_not_found;    
725     LOAD_FUNCPTR(jack_activate);
726     LOAD_FUNCPTR(jack_connect);
727     LOAD_FUNCPTR(jack_client_new);
728     LOAD_FUNCPTR(jack_client_close);
729     LOAD_FUNCPTR(jack_deactivate);
730     LOAD_FUNCPTR(jack_set_process_callback);
731     LOAD_FUNCPTR(jack_set_buffer_size_callback);
732     LOAD_FUNCPTR(jack_set_sample_rate_callback);
733     LOAD_FUNCPTR(jack_on_shutdown);
734     LOAD_FUNCPTR(jack_get_sample_rate);
735     LOAD_FUNCPTR(jack_port_register);
736     LOAD_FUNCPTR(jack_port_get_buffer);
737     LOAD_FUNCPTR(jack_get_ports);
738     LOAD_FUNCPTR(jack_port_name);
739 #undef LOAD_FUNCPTR
740
741     /* start with output device */
742
743     for (i = 0; i < MAX_WAVEOUTDRV; ++i)
744     {
745       WOutDev[i].client = 0; /* initialize the client to 0 */
746
747 #if JACK_CLOSE_HACK
748       WOutDev[i].in_use = FALSE;
749 #endif
750
751       memset(&WOutDev[i].caps, 0, sizeof(WOutDev[i].caps));
752
753       /* FIXME: some programs compare this string against the content of the registry
754        * for MM drivers. The names have to match in order for the program to work 
755        * (e.g. MS win9x mplayer.exe)
756        */
757 #ifdef EMULATE_SB16
758       WOutDev[i].caps.wMid = 0x0002;
759       WOutDev[i].caps.wPid = 0x0104;
760       strcpy(WOutDev[i].caps.szPname, "SB16 Wave Out");
761 #else
762       WOutDev[i].caps.wMid = 0x00FF;    /* Manufac ID */
763       WOutDev[i].caps.wPid = 0x0001;    /* Product ID */
764       /*    strcpy(WOutDev[i].caps.szPname, "OpenSoundSystem WAVOUT Driver");*/
765       strcpy(WOutDev[i].caps.szPname, "CS4236/37/38");
766 #endif
767       WOutDev[i].caps.vDriverVersion = 0x0100;
768       WOutDev[i].caps.dwFormats = 0x00000000;
769       WOutDev[i].caps.dwSupport = WAVECAPS_VOLUME;
770     
771       WOutDev[i].caps.wChannels = 2;
772       WOutDev[i].caps.dwSupport |= WAVECAPS_LRVOLUME;
773
774 /* NOTE: we don't support any 8 bit modes so note that */
775 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M08;
776       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S08; */
777       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4S16;
778       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_4M16;
779 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M08;
780       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S08; */
781       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2M16;
782       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_2S16;
783 /*      WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M08;
784       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S08;*/
785       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1M16;
786       WOutDev[i].caps.dwFormats |= WAVE_FORMAT_1S16;
787     }
788
789     /* then do input device */
790     for (i = 0; i < MAX_WAVEINDRV; ++i)
791     {
792       /* TODO: we should initialize read stuff here */
793       memset(&WInDev[0].caps, 0, sizeof(WInDev[0].caps));
794     }
795     
796     return 1;           /* return success */
797
798 /* error path for function pointer loading errors */
799 sym_not_found:
800     WINE_MESSAGE(
801       "Wine cannot find certain functions that it needs inside the jack"
802       "library.  To enable Wine to use the jack audio server please "
803       "install libjack\n");
804     wine_dlclose(jackhandle, NULL, 0);
805     jackhandle = NULL;
806     return FALSE;
807 }
808
809 /*======================================================================*
810  *                  Low level WAVE OUT implementation                   *
811  *======================================================================*/
812
813 /**************************************************************************
814  *                      wodNotifyClient                 [internal]
815  */
816 static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
817 {
818     TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2);
819     
820     switch (wMsg) {
821     case WOM_OPEN:
822     case WOM_CLOSE:
823     case WOM_DONE:
824       if (wwo->wFlags != DCB_NULL &&
825         !DriverCallback(wwo->waveDesc.dwCallback, wwo->wFlags,
826           (HDRVR)wwo->waveDesc.hWave, wMsg, wwo->waveDesc.dwInstance,
827           dwParam1, dwParam2))
828       {
829         WARN("can't notify client !\n");
830         return MMSYSERR_ERROR;
831       }
832     break;
833     default:
834       FIXME("Unknown callback message %u\n", wMsg);
835         return MMSYSERR_INVALPARAM;
836     }
837     return MMSYSERR_NOERROR;
838 }
839
840 /**************************************************************************
841  *                              wodHelper_BeginWaveHdr          [internal]
842  *
843  * Makes the specified lpWaveHdr the currently playing wave header.
844  * If the specified wave header is a begin loop and we're not already in
845  * a loop, setup the loop.
846  */
847 static void wodHelper_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
848 {
849     EnterCriticalSection(&wwo->access_crst);
850
851     wwo->lpPlayPtr = lpWaveHdr;
852
853     if (!lpWaveHdr)
854     {
855        LeaveCriticalSection(&wwo->access_crst);
856        return;
857     }
858
859     if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)
860     {
861       if (wwo->lpLoopPtr)
862       {
863         WARN("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
864         TRACE("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr);
865       } else
866       {
867         TRACE("Starting loop (%ldx) with %p\n", lpWaveHdr->dwLoops, lpWaveHdr);
868         wwo->lpLoopPtr = lpWaveHdr;
869         /* Windows does not touch WAVEHDR.dwLoops,
870          * so we need to make an internal copy */
871         wwo->dwLoops = lpWaveHdr->dwLoops;
872       }
873     }
874     wwo->dwPartialOffset = 0;
875
876     LeaveCriticalSection(&wwo->access_crst);
877 }
878
879
880 /**************************************************************************
881  *                              wodHelper_PlayPtrNext           [internal]
882  *
883  * Advance the play pointer to the next waveheader, looping if required.
884  */
885 static LPWAVEHDR wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo)
886 {
887   LPWAVEHDR lpWaveHdr;
888
889   EnterCriticalSection(&wwo->access_crst);
890
891   lpWaveHdr = wwo->lpPlayPtr;
892
893   wwo->dwPartialOffset = 0;
894   if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr)
895   {
896     /* We're at the end of a loop, loop if required */
897     if (--wwo->dwLoops > 0)
898     {
899       wwo->lpPlayPtr = wwo->lpLoopPtr;
900     } else
901     {
902       /* Handle overlapping loops correctly */
903       if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) {
904         FIXME("Correctly handled case ? (ending loop buffer also starts a new loop)\n");
905         /* shall we consider the END flag for the closing loop or for
906          * the opening one or for both ???
907          * code assumes for closing loop only
908          */
909       } else
910       {
911         lpWaveHdr = lpWaveHdr->lpNext;
912       }
913       wwo->lpLoopPtr = NULL;
914       wodHelper_BeginWaveHdr(wwo, lpWaveHdr);
915     }
916   } else
917   {
918      /* We're not in a loop.  Advance to the next wave header */
919     TRACE("not inside of a loop, advancing to next wave header\n");
920     wodHelper_BeginWaveHdr(wwo, lpWaveHdr = lpWaveHdr->lpNext);
921   }
922
923   LeaveCriticalSection(&wwo->access_crst);
924
925   return lpWaveHdr;
926 }
927
928 /* if force is TRUE then notify the client that all the headers were completed */
929 static DWORD wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force)
930 {
931   LPWAVEHDR             lpWaveHdr;
932   DWORD retval;
933
934   TRACE("called\n");
935
936   EnterCriticalSection(&wwo->access_crst);
937
938   /* Start from lpQueuePtr and keep notifying until:
939    * - we hit an unwritten wavehdr
940    * - we hit the beginning of a running loop
941    * - we hit a wavehdr which hasn't finished playing
942    */
943   while ((lpWaveHdr = wwo->lpQueuePtr) &&
944            (force || 
945             (lpWaveHdr != wwo->lpPlayPtr &&
946              lpWaveHdr != wwo->lpLoopPtr)))
947   {
948     wwo->lpQueuePtr = lpWaveHdr->lpNext;
949
950     lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
951     lpWaveHdr->dwFlags |= WHDR_DONE;
952     TRACE("calling notify client\n");
953
954     wodNotifyClient(wwo, WOM_DONE, (DWORD)lpWaveHdr, 0);
955   }
956
957   retval = (lpWaveHdr && lpWaveHdr != wwo->lpPlayPtr && lpWaveHdr != 
958               wwo->lpLoopPtr) ? 0 : INFINITE;
959
960   LeaveCriticalSection(&wwo->access_crst);
961
962   return retval;
963 }
964
965 /**************************************************************************
966  *                              wodHelper_Reset                 [internal]
967  *
968  * Resets current output stream.
969  */
970 static  void  wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset)
971 {
972     EnterCriticalSection(&wwo->access_crst);
973  
974     /* updates current notify list */
975     wodHelper_NotifyCompletions(wwo, FALSE);
976
977     if (reset)
978     {
979         /* remove all wave headers and notify client that all headers were completed */
980         wodHelper_NotifyCompletions(wwo, TRUE);
981
982         wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL;
983         wwo->state = WINE_WS_STOPPED;
984         wwo->dwPlayedTotal = wwo->dwWrittenTotal = wwo->bytesInJack = 0;
985
986         wwo->dwPartialOffset = 0;        /* Clear partial wavehdr */
987     } else
988     {
989         if (wwo->lpLoopPtr)
990         {
991             /* complicated case, not handled yet (could imply modifying the loop counter) */
992             FIXME("Pausing while in loop isn't correctly handled yet, except strange results\n");
993             wwo->lpPlayPtr = wwo->lpLoopPtr;
994             wwo->dwPartialOffset = 0;
995             wwo->dwWrittenTotal = wwo->dwPlayedTotal; /* this is wrong !!! */
996         } else
997         {
998             LPWAVEHDR   ptr;
999             DWORD       sz = wwo->dwPartialOffset;
1000
1001             /* reset all the data as if we had written only up to lpPlayedTotal bytes */
1002             /* compute the max size playable from lpQueuePtr */
1003             for (ptr = wwo->lpQueuePtr; ptr != wwo->lpPlayPtr; ptr = ptr->lpNext)
1004             {
1005                 sz += ptr->dwBufferLength;
1006             }
1007
1008             /* because the reset lpPlayPtr will be lpQueuePtr */
1009             if (wwo->dwWrittenTotal > wwo->dwPlayedTotal + sz) ERR("doh\n");
1010             wwo->dwPartialOffset = sz - (wwo->dwWrittenTotal - wwo->dwPlayedTotal);
1011             wwo->dwWrittenTotal = wwo->dwPlayedTotal;
1012             wwo->lpPlayPtr = wwo->lpQueuePtr;
1013         }
1014
1015         wwo->state = WINE_WS_PAUSED;
1016     }
1017  
1018     LeaveCriticalSection(&wwo->access_crst);
1019 }
1020
1021 /**************************************************************************
1022  *                      wodGetDevCaps                           [internal]
1023  */
1024 static DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPSA lpCaps, DWORD dwSize)
1025 {
1026     TRACE("(%u, %p, %lu);\n", wDevID, lpCaps, dwSize);
1027     
1028     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
1029     
1030     if (wDevID >= MAX_WAVEOUTDRV)
1031     {
1032       TRACE("MAX_WAVOUTDRV reached !\n");
1033       return MMSYSERR_BADDEVICEID;
1034     }
1035
1036     memcpy(lpCaps, &WOutDev[wDevID].caps, min(dwSize, sizeof(*lpCaps)));
1037     return MMSYSERR_NOERROR;
1038 }
1039
1040 /**************************************************************************
1041  *                              wodOpen                         [internal]
1042  */
1043 static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
1044 {
1045     WINE_WAVEOUT*       wwo;
1046     DWORD retval;
1047
1048     TRACE("(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
1049     if (lpDesc == NULL)
1050     {
1051       WARN("Invalid Parameter !\n");
1052       return MMSYSERR_INVALPARAM;
1053     }
1054     if (wDevID >= MAX_WAVEOUTDRV) {
1055       TRACE("MAX_WAVOUTDRV reached !\n");
1056       return MMSYSERR_BADDEVICEID;
1057     }
1058
1059 #if JACK_CLOSE_HACK
1060     if(WOutDev[wDevID].client && WOutDev[wDevID].in_use)
1061 #else
1062     if(WOutDev[wDevID].client)
1063 #endif
1064     {
1065       TRACE("device %d already allocated\n", wDevID);
1066       return MMSYSERR_ALLOCATED;
1067     }
1068
1069     /* make sure we aren't being opened in 8 bit mode */
1070     if(lpDesc->lpFormat->wBitsPerSample == 8)
1071     {
1072       TRACE("8bits per sample unsupported, returning WAVERR_BADFORMAT\n");
1073       return WAVERR_BADFORMAT;
1074     }
1075
1076     wwo = &WOutDev[wDevID];
1077     wwo->wDevID = wDevID;
1078
1079     /* Set things up before we call JACK_OpenDevice because */
1080     /* we will start getting callbacks before JACK_OpenDevice */
1081     /* even returns and we want to be initialized before then */
1082     wwo->state = WINE_WS_STOPPED; /* start in a stopped state */
1083     wwo->dwPlayedTotal = 0; /* zero out these totals */
1084     wwo->dwWrittenTotal = 0;
1085     wwo->bytesInJack = 0;
1086     wwo->tickCountMS = 0;
1087
1088     InitializeCriticalSection(&wwo->access_crst); /* initialize the critical section */
1089
1090     /* open up jack ports for this device */
1091     if (!JACK_OpenDevice(&WOutDev[wDevID]))
1092     {
1093       ERR("JACK_OpenDevice(%d) failed\n", wDevID);
1094       return MMSYSERR_ERROR;            /* return unspecified error */
1095     }
1096
1097     /* only PCM format is supported so far... */
1098     if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
1099       lpDesc->lpFormat->nChannels == 0 ||
1100       lpDesc->lpFormat->nSamplesPerSec == 0)
1101     {
1102       WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
1103        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1104        lpDesc->lpFormat->nSamplesPerSec);
1105       return WAVERR_BADFORMAT;
1106     }
1107
1108     if (dwFlags & WAVE_FORMAT_QUERY)
1109     {
1110       TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%ld !\n",
1111        lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels,
1112        lpDesc->lpFormat->nSamplesPerSec);
1113       return MMSYSERR_NOERROR;
1114     }
1115
1116     dwFlags &= ~WAVE_DIRECTSOUND;  /* direct sound not supported, ignore the flag */
1117
1118     EnterCriticalSection(&wwo->access_crst);
1119
1120     wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
1121     
1122     memcpy(&wwo->waveDesc, lpDesc,           sizeof(WAVEOPENDESC));
1123     memcpy(&wwo->format,   lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
1124
1125     LeaveCriticalSection(&wwo->access_crst);
1126
1127     /* display the current wave format */
1128     TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n", 
1129     wwo->format.wBitsPerSample, wwo->format.wf.nAvgBytesPerSec,
1130     wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
1131     wwo->format.wf.nBlockAlign);
1132
1133     /* make sure that we have the same sample rate in our audio stream */
1134     /* as we do in the jack server */
1135     if(wwo->format.wf.nSamplesPerSec != wwo->sample_rate)
1136     {
1137       TRACE("error: jack server sample rate is '%ld', wave sample rate is '%ld'\n",
1138          wwo->sample_rate, wwo->format.wf.nSamplesPerSec);
1139
1140 #if JACK_CLOSE_HACK
1141       JACK_CloseDevice(wwo, FALSE); /* close this device, don't force the client to close */
1142 #else
1143       JACK_CloseDevice(wwo); /* close this device */
1144 #endif
1145       return WAVERR_BADFORMAT;
1146     }
1147
1148     /* check for an invalid number of bits per sample */
1149     if (wwo->format.wBitsPerSample == 0)
1150     {
1151       WARN("Resetting zeroed wBitsPerSample to 16\n");
1152       wwo->format.wBitsPerSample = 16 *
1153       (wwo->format.wf.nAvgBytesPerSec /
1154        wwo->format.wf.nSamplesPerSec) /
1155        wwo->format.wf.nChannels;
1156     }
1157
1158     EnterCriticalSection(&wwo->access_crst);
1159     retval = wodNotifyClient(wwo, WOM_OPEN, 0L, 0L);
1160     LeaveCriticalSection(&wwo->access_crst);
1161
1162     return retval;
1163 }
1164
1165 /**************************************************************************
1166  *                              wodClose                        [internal]
1167  */
1168 static DWORD wodClose(WORD wDevID)
1169 {
1170     DWORD               ret = MMSYSERR_NOERROR;
1171     WINE_WAVEOUT*       wwo;
1172
1173     TRACE("(%u);\n", wDevID);
1174
1175     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1176     {
1177       WARN("bad device ID !\n");
1178       return MMSYSERR_BADDEVICEID;
1179     }
1180     
1181     wwo = &WOutDev[wDevID];
1182     if (wwo->lpQueuePtr)
1183     {
1184       WARN("buffers still playing !\n");
1185       ret = WAVERR_STILLPLAYING;
1186     } else
1187     {
1188       /* sanity check: this should not happen since the device must have been reset before */
1189       if (wwo->lpQueuePtr || wwo->lpPlayPtr) ERR("out of sync\n");
1190
1191       wwo->state = WINE_WS_CLOSED; /* mark the device as closed */
1192
1193 #if JACK_CLOSE_HACK
1194       JACK_CloseDevice(wwo, FALSE); /* close the jack device, DO NOT force the client to close */
1195 #else
1196       JACK_CloseDevice(wwo); /* close the jack device */
1197       DeleteCriticalSection(&wwo->access_crst); /* delete the critical section so we can initialize it again from wodOpen() */
1198 #endif
1199
1200       ret = wodNotifyClient(wwo, WOM_CLOSE, 0L, 0L);
1201     }
1202
1203     return ret;
1204 }
1205
1206 /**************************************************************************
1207  *                              wodWrite                        [internal]
1208  * 
1209  */
1210 static DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1211 {
1212     LPWAVEHDR*wh;
1213     WINE_WAVEOUT *wwo;
1214
1215     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1216     
1217     /* first, do the sanity checks... */
1218     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1219     {
1220       WARN("bad dev ID !\n");
1221       return MMSYSERR_BADDEVICEID;
1222     }
1223
1224     wwo = &WOutDev[wDevID];
1225
1226     if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED))
1227     {
1228       TRACE("unprepared\n");
1229       return WAVERR_UNPREPARED;
1230     }
1231     
1232     if (lpWaveHdr->dwFlags & WHDR_INQUEUE) 
1233     {
1234       TRACE("still playing\n");
1235       return WAVERR_STILLPLAYING;
1236     }
1237
1238     lpWaveHdr->dwFlags &= ~WHDR_DONE;
1239     lpWaveHdr->dwFlags |= WHDR_INQUEUE;
1240     lpWaveHdr->lpNext = 0;
1241
1242     EnterCriticalSection(&wwo->access_crst);
1243
1244     /* insert buffer at the end of queue */
1245     for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
1246     *wh = lpWaveHdr;
1247
1248     LeaveCriticalSection(&wwo->access_crst);
1249
1250     EnterCriticalSection(&wwo->access_crst);
1251     if (!wwo->lpPlayPtr)
1252       wodHelper_BeginWaveHdr(wwo,lpWaveHdr);
1253     if (wwo->state == WINE_WS_STOPPED)
1254       wwo->state = WINE_WS_PLAYING;
1255     LeaveCriticalSection(&wwo->access_crst);
1256
1257     return MMSYSERR_NOERROR;
1258 }
1259
1260 /**************************************************************************
1261  *                              wodPrepare                      [internal]
1262  */
1263 static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1264 {
1265   TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1266     
1267   if (wDevID >= MAX_WAVEOUTDRV)
1268   {
1269     WARN("bad device ID !\n");
1270     return MMSYSERR_BADDEVICEID;
1271   }
1272     
1273   if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
1274     return WAVERR_STILLPLAYING;
1275     
1276   lpWaveHdr->dwFlags |= WHDR_PREPARED;
1277   lpWaveHdr->dwFlags &= ~WHDR_DONE;
1278   return MMSYSERR_NOERROR;
1279 }
1280
1281 /**************************************************************************
1282  *                              wodUnprepare                    [internal]
1283  */
1284 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
1285 {
1286   TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
1287     
1288   if (wDevID >= MAX_WAVEOUTDRV)
1289   {
1290     WARN("bad device ID !\n");
1291     return MMSYSERR_BADDEVICEID;
1292   }
1293     
1294   if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
1295     return WAVERR_STILLPLAYING;
1296     
1297   lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
1298   lpWaveHdr->dwFlags |= WHDR_DONE;
1299     
1300   return MMSYSERR_NOERROR;
1301 }
1302
1303 /**************************************************************************
1304  *                      wodPause                                [internal]
1305  */
1306 static DWORD wodPause(WORD wDevID)
1307 {
1308   TRACE("(%u);!\n", wDevID);
1309     
1310   if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1311   {
1312     WARN("bad device ID !\n");
1313     return MMSYSERR_BADDEVICEID;
1314   }
1315     
1316   TRACE("[3-PAUSING]\n");
1317
1318   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1319   wodHelper_Reset(&WOutDev[wDevID], FALSE);
1320   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1321
1322   return MMSYSERR_NOERROR;
1323 }
1324
1325 /**************************************************************************
1326  *                      wodRestart                              [internal]
1327  */
1328 static DWORD wodRestart(WORD wDevID)
1329 {
1330     TRACE("(%u);\n", wDevID);
1331
1332     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1333     {
1334       WARN("bad device ID !\n");
1335       return MMSYSERR_BADDEVICEID;
1336     }
1337
1338     if (WOutDev[wDevID].state == WINE_WS_PAUSED)
1339     {
1340       EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1341       WOutDev[wDevID].state = WINE_WS_PLAYING;
1342       LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1343     }
1344     
1345     return MMSYSERR_NOERROR;
1346 }
1347
1348 /**************************************************************************
1349  *                      wodReset                                [internal]
1350  */
1351 static DWORD wodReset(WORD wDevID)
1352 {
1353     TRACE("(%u);\n", wDevID);
1354     
1355     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1356     {
1357       WARN("bad device ID !\n");
1358       return MMSYSERR_BADDEVICEID;
1359     }
1360
1361     EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1362     wodHelper_Reset(&WOutDev[wDevID], TRUE);
1363     LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1364
1365     return MMSYSERR_NOERROR;
1366 }
1367
1368 /**************************************************************************
1369  *                              wodGetPosition                  [internal]
1370  */
1371 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
1372 {
1373     int                 time;
1374     DWORD               val;
1375     WINE_WAVEOUT*       wwo;
1376     DWORD elapsedMS;
1377
1378     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
1379     
1380     if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1381     {
1382       WARN("bad device ID !\n");
1383       return MMSYSERR_BADDEVICEID;
1384     }
1385     
1386     /* if null pointer to time structure return error */
1387     if (lpTime == NULL) return MMSYSERR_INVALPARAM;
1388
1389     wwo = &WOutDev[wDevID];
1390
1391     EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1392     val = wwo->dwPlayedTotal;
1393     elapsedMS = GetTickCount() - wwo->tickCountMS;
1394     LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1395
1396     /* account for the bytes played since the last JACK_Callback() */
1397     val+=((elapsedMS * wwo->format.wf.nAvgBytesPerSec) / 1000);
1398
1399     TRACE("wType=%04X wBitsPerSample=%u nSamplesPerSec=%lu nChannels=%u nAvgBytesPerSec=%lu\n", 
1400       lpTime->wType, wwo->format.wBitsPerSample,
1401       wwo->format.wf.nSamplesPerSec, wwo->format.wf.nChannels,
1402       wwo->format.wf.nAvgBytesPerSec);
1403     TRACE("dwPlayedTotal=%lu\n", val);
1404     
1405     switch (lpTime->wType) {
1406     case TIME_BYTES:
1407       lpTime->u.cb = val;
1408       TRACE("TIME_BYTES=%lu\n", lpTime->u.cb);
1409       break;
1410     case TIME_SAMPLES:
1411       lpTime->u.sample = val * 8 / wwo->format.wBitsPerSample /wwo->format.wf.nChannels;
1412       TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
1413       break;
1414     case TIME_SMPTE:
1415       time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
1416       lpTime->u.smpte.hour = time / 108000;
1417       time -= lpTime->u.smpte.hour * 108000;
1418       lpTime->u.smpte.min = time / 1800;
1419       time -= lpTime->u.smpte.min * 1800;
1420       lpTime->u.smpte.sec = time / 30;
1421       time -= lpTime->u.smpte.sec * 30;
1422       lpTime->u.smpte.frame = time;
1423       lpTime->u.smpte.fps = 30;
1424       TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
1425         lpTime->u.smpte.hour, lpTime->u.smpte.min,
1426         lpTime->u.smpte.sec, lpTime->u.smpte.frame);
1427       break;
1428     default:
1429       FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
1430       lpTime->wType = TIME_MS;
1431     case TIME_MS:
1432       lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
1433       TRACE("TIME_MS=%lu\n", lpTime->u.ms);
1434       break;
1435     }
1436     return MMSYSERR_NOERROR;
1437 }
1438
1439 /**************************************************************************
1440  *                              wodBreakLoop                    [internal]
1441  */
1442 static DWORD wodBreakLoop(WORD wDevID)
1443 {
1444   TRACE("(%u);\n", wDevID);
1445
1446   if (wDevID >= MAX_WAVEOUTDRV || !WOutDev[wDevID].client)
1447   {
1448     WARN("bad device ID !\n");
1449     return MMSYSERR_BADDEVICEID;
1450   }
1451
1452   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1453
1454   if (WOutDev[wDevID].state == WINE_WS_PLAYING && WOutDev[wDevID].lpLoopPtr != NULL)
1455   {
1456     /* ensure exit at end of current loop */
1457     WOutDev[wDevID].dwLoops = 1;
1458   }
1459
1460   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1461
1462   return MMSYSERR_NOERROR;
1463 }
1464     
1465 /**************************************************************************
1466  *                              wodGetVolume                    [internal]
1467  */
1468 static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
1469 {
1470   DWORD left, right;
1471     
1472   left = WOutDev[wDevID].volume_left;
1473   right = WOutDev[wDevID].volume_right;
1474         
1475   TRACE("(%u, %p);\n", wDevID, lpdwVol);
1476  
1477   *lpdwVol = ((left * 0xFFFFl) / 100) + (((right * 0xFFFFl) / 100) <<
1478               16);
1479     
1480   return MMSYSERR_NOERROR;
1481 }
1482
1483 /**************************************************************************
1484  *                              wodSetVolume                    [internal]
1485  */
1486 static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
1487 {
1488   DWORD left, right;
1489  
1490   left  = (LOWORD(dwParam) * 100) / 0xFFFFl;
1491   right = (HIWORD(dwParam) * 100) / 0xFFFFl;
1492  
1493   TRACE("(%u, %08lX);\n", wDevID, dwParam);
1494
1495   EnterCriticalSection(&(WOutDev[wDevID].access_crst));
1496
1497   WOutDev[wDevID].volume_left = left;
1498   WOutDev[wDevID].volume_right = right;
1499
1500   LeaveCriticalSection(&(WOutDev[wDevID].access_crst));
1501
1502   return MMSYSERR_NOERROR;
1503 }
1504
1505 /**************************************************************************
1506  *                              wodGetNumDevs                   [internal]
1507  */
1508 static DWORD wodGetNumDevs(void)
1509 {
1510   return MAX_WAVEOUTDRV;
1511 }
1512
1513 /**************************************************************************
1514  *                              wodMessage (WINEJACK.7)
1515  */
1516 DWORD WINAPI JACK_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser, 
1517                             DWORD dwParam1, DWORD dwParam2)
1518 {
1519   TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
1520   wDevID, wMsg, dwUser, dwParam1, dwParam2);
1521     
1522   switch (wMsg) {
1523   case DRVM_INIT:
1524     TRACE("DRVM_INIT\n");
1525     return JACK_WaveInit();
1526   case DRVM_EXIT:
1527     TRACE("DRVM_EXIT\n");
1528     return JACK_WaveRelease();
1529   case DRVM_ENABLE:
1530   /* FIXME: Pretend this is supported */
1531     TRACE("DRVM_ENABLE\n");
1532     return 0;
1533   case DRVM_DISABLE:
1534   /* FIXME: Pretend this is supported */
1535     TRACE("DRVM_DISABLE\n");
1536     return 0;
1537   case WODM_OPEN:             return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1,  dwParam2);
1538   case WODM_CLOSE:            return wodClose(wDevID);
1539   case WODM_WRITE:            return wodWrite(wDevID, (LPWAVEHDR)dwParam1,              dwParam2);
1540   case WODM_PAUSE:            return wodPause(wDevID);
1541   case WODM_GETPOS:           return wodGetPosition(wDevID, (LPMMTIME)dwParam1,                 dwParam2);
1542   case WODM_BREAKLOOP:        return wodBreakLoop(wDevID);
1543   case WODM_PREPARE:          return wodPrepare(wDevID, (LPWAVEHDR)dwParam1,            dwParam2);
1544   case WODM_UNPREPARE:        return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1,          dwParam2);
1545   case WODM_GETDEVCAPS:       return wodGetDevCaps(wDevID, (LPWAVEOUTCAPSA)dwParam1,    dwParam2);
1546   case WODM_GETNUMDEVS:       return wodGetNumDevs();
1547   case WODM_GETPITCH:         return MMSYSERR_NOTSUPPORTED;
1548   case WODM_SETPITCH:         return MMSYSERR_NOTSUPPORTED;
1549   case WODM_GETPLAYBACKRATE:    return MMSYSERR_NOTSUPPORTED;
1550   case WODM_SETPLAYBACKRATE:    return MMSYSERR_NOTSUPPORTED;
1551   case WODM_GETVOLUME:        return wodGetVolume(wDevID, (LPDWORD)dwParam1);
1552   case WODM_SETVOLUME:        return wodSetVolume(wDevID, dwParam1);
1553   case WODM_RESTART:          return wodRestart(wDevID);
1554   case WODM_RESET:            return wodReset(wDevID);
1555
1556   case DRV_QUERYDSOUNDIFACE:    return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
1557   default:
1558     FIXME("unknown message %d!\n", wMsg);
1559     }
1560     return MMSYSERR_NOTSUPPORTED;
1561 }
1562
1563 /*======================================================================*
1564  *                  Low level DSOUND implementation                     *
1565  *======================================================================*/
1566
1567 typedef struct IDsDriverImpl IDsDriverImpl;
1568 typedef struct IDsDriverBufferImpl IDsDriverBufferImpl;
1569
1570 struct IDsDriverImpl
1571 {
1572     /* IUnknown fields */
1573     ICOM_VFIELD(IDsDriver);
1574     DWORD               ref;
1575     /* IDsDriverImpl fields */
1576     UINT                wDevID;
1577     IDsDriverBufferImpl*primary;
1578 };
1579
1580 struct IDsDriverBufferImpl
1581 {
1582     /* IUnknown fields */
1583     ICOM_VFIELD(IDsDriverBuffer);
1584     DWORD ref;
1585     /* IDsDriverBufferImpl fields */
1586     IDsDriverImpl* drv;
1587     DWORD buflen;
1588 };
1589
1590 static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
1591 {
1592     /* we can't perform memory mapping as we don't have a file stream 
1593       interface with jack like we do with oss */
1594     MESSAGE("This sound card's driver does not support direct access\n");
1595     MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
1596     return MMSYSERR_NOTSUPPORTED;
1597 }
1598
1599 /*======================================================================*
1600  *                  Low level WAVE IN implementation                    *
1601  *======================================================================*/
1602
1603 /**************************************************************************
1604  *                              widMessage (WINEJACK.6)
1605  */
1606 DWORD WINAPI JACK_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
1607                             DWORD dwParam1, DWORD dwParam2)
1608 {
1609   TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
1610   wDevID, wMsg, dwUser, dwParam1, dwParam2);
1611
1612   return MMSYSERR_NOTSUPPORTED;
1613 }
1614
1615 #else /* !HAVE_JACK_JACK_H */
1616
1617 /**************************************************************************
1618  *                              wodMessage (WINEJACK.7)
1619  */
1620 DWORD WINAPI JACK_wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
1621                             DWORD dwParam1, DWORD dwParam2)
1622 {
1623   FIXME("(%u, %04X, %08lX, %08lX, %08lX):jack support not compiled into wine\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
1624   return MMSYSERR_NOTENABLED;
1625 }
1626
1627 #endif /* HAVE_JACK_JACK_H */