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