Always allocate an empty buffer.
[wine] / dlls / dsound / dsound_private.h
1 /*                      DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2001 TransGaming Technologies, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 /* Linux does not support better timing than 10ms */
23 #define DS_TIME_RES 10  /* Resolution of multimedia timer */
24 #define DS_TIME_DEL 10  /* Delay of multimedia timer callback, and duration of HEL fragment */
25
26 #define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
27                          * (changing this won't help you) */
28
29 /* direct sound hardware acceleration levels */
30 #define DS_HW_ACCEL_FULL        0       /* default on Windows 98 */
31 #define DS_HW_ACCEL_STANDARD    1       /* default on Windows 2000 */
32 #define DS_HW_ACCEL_BASIC       2
33 #define DS_HW_ACCEL_EMULATION   3
34
35 extern int ds_emuldriver;
36 extern int ds_hel_margin;
37 extern int ds_hel_queue;
38 extern int ds_snd_queue_max;
39 extern int ds_snd_queue_min;
40 extern int ds_hw_accel;
41 extern int ds_default_playback;
42 extern int ds_default_capture;
43
44 /*****************************************************************************
45  * Predeclare the interface implementation structures
46  */
47 typedef struct IDirectSoundImpl              IDirectSoundImpl;
48 typedef struct IDirectSound_IUnknown         IDirectSound_IUnknown;
49 typedef struct IDirectSound_IDirectSound     IDirectSound_IDirectSound;
50 typedef struct IDirectSound8_IUnknown        IDirectSound8_IUnknown;
51 typedef struct IDirectSound8_IDirectSound    IDirectSound8_IDirectSound;
52 typedef struct IDirectSound8_IDirectSound8   IDirectSound8_IDirectSound8;
53 typedef struct IDirectSoundBufferImpl        IDirectSoundBufferImpl;
54 typedef struct IDirectSoundCaptureImpl       IDirectSoundCaptureImpl;
55 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
56 typedef struct IDirectSoundFullDuplexImpl    IDirectSoundFullDuplexImpl;
57 typedef struct IDirectSoundNotifyImpl        IDirectSoundNotifyImpl;
58 typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
59 typedef struct IDirectSound3DListenerImpl    IDirectSound3DListenerImpl;
60 typedef struct IDirectSound3DBufferImpl      IDirectSound3DBufferImpl;
61 typedef struct IKsBufferPropertySetImpl      IKsBufferPropertySetImpl;
62 typedef struct IKsPrivatePropertySetImpl     IKsPrivatePropertySetImpl;
63 typedef struct PrimaryBufferImpl             PrimaryBufferImpl;
64 typedef struct SecondaryBufferImpl           SecondaryBufferImpl;
65 typedef struct IClassFactoryImpl             IClassFactoryImpl;
66
67 /*****************************************************************************
68  * IDirectSound implementation structure
69  */
70 struct IDirectSoundImpl
71 {
72     /* IUnknown fields */
73     IDirectSound8Vtbl          *lpVtbl;
74     DWORD                       ref;
75     /* IDirectSoundImpl fields */
76     GUID                        guid;
77     PIDSDRIVER                  driver;
78     DSDRIVERDESC                drvdesc;
79     DSDRIVERCAPS                drvcaps;
80     DWORD                       priolevel;
81     PWAVEFORMATEX               pwfx;
82     HWAVEOUT                    hwo;
83     LPWAVEHDR                   pwave[DS_HEL_FRAGS];
84     UINT                        timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
85     DWORD                       fraglen;
86     PIDSDRIVERBUFFER            hwbuf;
87     LPBYTE                      buffer;
88     DWORD                       writelead, buflen, state, playpos, mixpos;
89     BOOL                        need_remix;
90     int                         nrofbuffers;
91     IDirectSoundBufferImpl**    buffers;
92     RTL_RWLOCK                  buffer_list_lock;
93     CRITICAL_SECTION            mixlock;
94     PrimaryBufferImpl*          primary;
95     DSBUFFERDESC                dsbd;
96     DWORD                       speaker_config;
97     BOOL                        initialized;
98     LPBYTE                      tmp_buffer;
99     DWORD                       tmp_buffer_len;
100
101     /* DirectSound3DListener fields */
102     IDirectSound3DListenerImpl* listener;
103     DS3DLISTENER                ds3dl;
104     BOOL                        ds3dl_need_recalc;
105
106     LPUNKNOWN                   pUnknown;
107     LPDIRECTSOUND               pDS;
108     LPDIRECTSOUND8              pDS8;
109 };
110
111 /* reference counted buffer memory for duplicated buffer memory */
112 typedef struct BufferMemory
113 {
114     DWORD                       ref;
115     LPBYTE                      memory;
116 } BufferMemory;
117
118 HRESULT WINAPI IDirectSoundImpl_Create(
119     LPCGUID lpcGUID,
120     LPDIRECTSOUND8 * ppds);
121
122 HRESULT WINAPI DSOUND_Create(
123     LPCGUID lpcGUID,
124     LPDIRECTSOUND *ppDS,
125     IUnknown *pUnkOuter);
126
127 HRESULT WINAPI DSOUND_Create8(
128     LPCGUID lpcGUID,
129     LPDIRECTSOUND8 *ppDS,
130     IUnknown *pUnkOuter);
131
132 /*****************************************************************************
133  * IDirectSound COM components
134  */
135 struct IDirectSound_IUnknown {
136     IUnknownVtbl               *lpVtbl;
137     DWORD                       ref;
138     LPDIRECTSOUND8              pds;
139 };
140
141 HRESULT WINAPI IDirectSound_IUnknown_Create(
142     LPDIRECTSOUND8 pds,
143     LPUNKNOWN * ppunk);
144
145 struct IDirectSound_IDirectSound {
146     IDirectSoundVtbl           *lpVtbl;
147     DWORD                       ref;
148     LPDIRECTSOUND8              pds;
149 };
150
151 HRESULT WINAPI IDirectSound_IDirectSound_Create(
152     LPDIRECTSOUND8 pds,
153     LPDIRECTSOUND * ppds);
154
155 /*****************************************************************************
156  * IDirectSound8 COM components
157  */
158 struct IDirectSound8_IUnknown {
159     IUnknownVtbl               *lpVtbl;
160     DWORD                       ref;
161     LPDIRECTSOUND8              pds;
162 };
163
164 HRESULT WINAPI IDirectSound8_IUnknown_Create(
165     LPDIRECTSOUND8 pds,
166     LPUNKNOWN * ppunk);
167
168 struct IDirectSound8_IDirectSound {
169     IDirectSoundVtbl           *lpVtbl;
170     DWORD                       ref;
171     LPDIRECTSOUND8              pds;
172 };
173
174 HRESULT WINAPI IDirectSound8_IDirectSound_Create(
175     LPDIRECTSOUND8 pds,
176     LPDIRECTSOUND * ppds);
177
178 struct IDirectSound8_IDirectSound8 {
179     IDirectSound8Vtbl          *lpVtbl;
180     DWORD                       ref;
181     LPDIRECTSOUND8              pds;
182 };
183
184 HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
185     LPDIRECTSOUND8 pds,
186     LPDIRECTSOUND8 * ppds);
187
188 /*****************************************************************************
189  * IDirectSoundBuffer implementation structure
190  */
191 struct IDirectSoundBufferImpl
192 {
193     /* FIXME: document */
194     /* IUnknown fields */
195     IDirectSoundBuffer8Vtbl    *lpVtbl;
196     DWORD                       ref;
197     /* IDirectSoundBufferImpl fields */
198     SecondaryBufferImpl*        dsb;
199     IDirectSoundImpl*           dsound;
200     CRITICAL_SECTION            lock;
201     PIDSDRIVERBUFFER            hwbuf;
202     PWAVEFORMATEX               pwfx;
203     BufferMemory*               buffer;
204     DWORD                       playflags,state,leadin;
205     DWORD                       playpos,startpos,writelead,buflen;
206     DWORD                       nAvgBytesPerSec;
207     DWORD                       freq;
208     DSVOLUMEPAN                 volpan, cvolpan;
209     DSBUFFERDESC                dsbd;
210     /* used for frequency conversion (PerfectPitch) */
211     ULONG                       freqAdjust, freqAcc;
212     /* used for intelligent (well, sort of) prebuffering */
213     DWORD                       probably_valid_to, last_playpos;
214     DWORD                       primary_mixpos, buf_mixpos;
215     BOOL                        need_remix;
216
217     /* IDirectSoundNotifyImpl fields */
218     IDirectSoundNotifyImpl*     notify;
219     LPDSBPOSITIONNOTIFY         notifies;
220     int                         nrofnotifies;
221     PIDSDRIVERNOTIFY            hwnotify;
222
223     /* DirectSound3DBuffer fields */
224     IDirectSound3DBufferImpl*   ds3db;
225     DS3DBUFFER                  ds3db_ds3db;
226     LONG                        ds3db_lVolume;
227     BOOL                        ds3db_need_recalc;
228
229     /* IKsPropertySet fields */
230     IKsBufferPropertySetImpl*   iks;
231 };
232
233 HRESULT WINAPI IDirectSoundBufferImpl_Create(
234     IDirectSoundImpl *ds,
235     IDirectSoundBufferImpl **pdsb,
236     LPCDSBUFFERDESC dsbd);
237 HRESULT WINAPI IDirectSoundBufferImpl_Destroy(
238     IDirectSoundBufferImpl *pdsb);
239
240 /*****************************************************************************
241  * SecondaryBuffer implementation structure
242  */
243 struct SecondaryBufferImpl
244 {
245     IDirectSoundBuffer8Vtbl    *lpVtbl;
246     DWORD                       ref;
247     IDirectSoundBufferImpl*     dsb;
248 };
249
250 HRESULT WINAPI SecondaryBufferImpl_Create(
251     IDirectSoundBufferImpl *dsb,
252     SecondaryBufferImpl **pdsb);
253 HRESULT WINAPI SecondaryBufferImpl_Destroy(
254     SecondaryBufferImpl *pdsb);
255
256 /*****************************************************************************
257  * PrimaryBuffer implementation structure
258  */
259 struct PrimaryBufferImpl
260 {
261     IDirectSoundBuffer8Vtbl    *lpVtbl;
262     DWORD                       ref;
263     IDirectSoundImpl*           dsound;
264 };
265
266 HRESULT WINAPI PrimaryBufferImpl_Create(
267     IDirectSoundImpl *ds,
268     PrimaryBufferImpl **pdsb,
269     LPCDSBUFFERDESC dsbd);
270
271 /*****************************************************************************
272  * IDirectSoundCapture implementation structure
273  */
274 struct IDirectSoundCaptureImpl
275 {
276     /* IUnknown fields */
277     IDirectSoundCaptureVtbl           *lpVtbl;
278     DWORD                              ref;
279
280     /* IDirectSoundCaptureImpl fields */
281     GUID                               guid;
282     BOOL                               initialized;
283
284     /* DirectSound driver stuff */
285     PIDSCDRIVER                        driver;
286     DSDRIVERDESC                       drvdesc;
287     DSCDRIVERCAPS                      drvcaps;
288     PIDSCDRIVERBUFFER                  hwbuf;
289
290     /* wave driver info */
291     HWAVEIN                            hwi;
292
293     /* more stuff */
294     LPBYTE                             buffer;
295     DWORD                              buflen;
296     DWORD                              read_position;
297
298     PWAVEFORMATEX                      pwfx;
299
300     IDirectSoundCaptureBufferImpl*     capture_buffer;
301     DWORD                              state;
302     LPWAVEHDR                          pwave;
303     int                                nrofpwaves;
304     int                                index;
305     CRITICAL_SECTION                   lock;
306 };
307
308 /*****************************************************************************
309  * IDirectSoundCaptureBuffer implementation structure
310  */
311 struct IDirectSoundCaptureBufferImpl
312 {
313     /* IUnknown fields */
314     IDirectSoundCaptureBuffer8Vtbl     *lpVtbl;
315     DWORD                               ref;
316
317     /* IDirectSoundCaptureBufferImpl fields */
318     IDirectSoundCaptureImpl*            dsound;
319     /* FIXME: don't need this */
320     LPDSCBUFFERDESC                     pdscbd;
321     DWORD                               flags;
322
323     /* IDirectSoundCaptureNotifyImpl fields */
324     IDirectSoundCaptureNotifyImpl*      notify;
325     LPDSBPOSITIONNOTIFY                 notifies;
326     int                                 nrofnotifies;
327     PIDSDRIVERNOTIFY                    hwnotify;
328 };
329
330 /*****************************************************************************
331  * IDirectSoundFullDuplex implementation structure
332  */
333 struct IDirectSoundFullDuplexImpl
334 {
335     /* IUnknown fields */
336     IDirectSoundFullDuplexVtbl *lpVtbl;
337     DWORD                       ref;
338
339     /* IDirectSoundFullDuplexImpl fields */
340     CRITICAL_SECTION            lock;
341 };
342
343 /*****************************************************************************
344  * IDirectSoundNotify implementation structure
345  */
346 struct IDirectSoundNotifyImpl
347 {
348     /* IUnknown fields */
349     IDirectSoundNotifyVtbl     *lpVtbl;
350     DWORD                       ref;
351     IDirectSoundBufferImpl*     dsb;
352 };
353
354 HRESULT WINAPI IDirectSoundNotifyImpl_Create(
355     IDirectSoundBufferImpl *dsb,
356     IDirectSoundNotifyImpl **pdsn);
357 HRESULT WINAPI IDirectSoundNotifyImpl_Destroy(
358     IDirectSoundNotifyImpl *pdsn);
359
360 /*****************************************************************************
361  * IDirectSoundCaptureNotify implementation structure
362  */
363 struct IDirectSoundCaptureNotifyImpl
364 {
365     /* IUnknown fields */
366     IDirectSoundNotifyVtbl             *lpVtbl;
367     DWORD                               ref;
368     IDirectSoundCaptureBufferImpl*      dscb;
369 };
370
371 HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
372     IDirectSoundCaptureBufferImpl *dscb,
373     IDirectSoundCaptureNotifyImpl ** pdscn);
374
375 /*****************************************************************************
376  *  IDirectSound3DListener implementation structure
377  */
378 struct IDirectSound3DListenerImpl
379 {
380     /* IUnknown fields */
381     IDirectSound3DListenerVtbl *lpVtbl;
382     DWORD                       ref;
383     /* IDirectSound3DListenerImpl fields */
384     IDirectSoundImpl*           dsound;
385 };
386
387 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
388     PrimaryBufferImpl *pb,
389     IDirectSound3DListenerImpl **pdsl);
390
391 /*****************************************************************************
392  *  IKsBufferPropertySet implementation structure
393  */
394 struct IKsBufferPropertySetImpl
395 {
396     /* IUnknown fields */
397     IKsPropertySetVtbl         *lpVtbl;
398     DWORD                       ref;
399     /* IKsPropertySetImpl fields */
400     IDirectSoundBufferImpl*     dsb;
401 };
402
403 HRESULT WINAPI IKsBufferPropertySetImpl_Create(
404     IDirectSoundBufferImpl *dsb,
405     IKsBufferPropertySetImpl **piks);
406 HRESULT WINAPI IKsBufferPropertySetImpl_Destroy(
407     IKsBufferPropertySetImpl *piks);
408
409 /*****************************************************************************
410  *  IKsPrivatePropertySet implementation structure
411  */
412 struct IKsPrivatePropertySetImpl
413 {
414     /* IUnknown fields */
415     IKsPropertySetVtbl         *lpVtbl;
416     DWORD                       ref;
417 };
418
419 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
420     IKsPrivatePropertySetImpl **piks);
421
422 /*****************************************************************************
423  * IDirectSound3DBuffer implementation structure
424  */
425 struct IDirectSound3DBufferImpl
426 {
427     /* IUnknown fields */
428     IDirectSound3DBufferVtbl   *lpVtbl;
429     DWORD                       ref;
430     /* IDirectSound3DBufferImpl fields */
431     IDirectSoundBufferImpl*     dsb;
432 };
433
434 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
435     IDirectSoundBufferImpl *dsb,
436     IDirectSound3DBufferImpl **pds3db);
437 HRESULT WINAPI IDirectSound3DBufferImpl_Destroy(
438     IDirectSound3DBufferImpl *pds3db);
439
440 /*******************************************************************************
441  * DirectSound ClassFactory implementation structure
442  */
443 struct IClassFactoryImpl
444 {
445     /* IUnknown fields */
446     IClassFactoryVtbl          *lpVtbl;
447     DWORD                       ref;
448 };
449
450 extern IClassFactoryImpl DSOUND_CAPTURE_CF;
451 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
452
453 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
454 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
455 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
456
457 /* dsound.c */
458
459 HRESULT DSOUND_AddBuffer(IDirectSoundImpl * pDS, IDirectSoundBufferImpl * pDSB);
460 HRESULT DSOUND_RemoveBuffer(IDirectSoundImpl * pDS, IDirectSoundBufferImpl * pDSB);
461
462 /* primary.c */
463
464 HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
465 HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
466 HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
467 HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
468 HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
469
470 /* buffer.c */
471
472 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
473                               DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
474
475 /* mixer.c */
476
477 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
478 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
479 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
480 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
481 void DSOUND_PerformMix(IDirectSoundImpl *dsound);
482 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
483 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
484
485 /* sound3d.c */
486
487 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
488
489 #define STATE_STOPPED   0
490 #define STATE_STARTING  1
491 #define STATE_PLAYING   2
492 #define STATE_CAPTURING 2
493 #define STATE_STOPPING  3
494
495 #define DSOUND_FREQSHIFT (14)
496
497 extern IDirectSoundImpl* dsound;
498
499 extern GUID renderer_guids[MAXWAVEDRIVERS];
500 extern GUID capture_guids[MAXWAVEDRIVERS];
501
502 extern HRESULT mmErr(UINT err);
503 extern void setup_dsound_options(void);
504 extern const char * get_device_id(LPCGUID pGuid);