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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #ifndef _DSOUND_PRIVATE_H_
23 #define _DSOUND_PRIVATE_H_
24 
25 #include <wine/config.h>
26 
27 #include <assert.h>
28 #include <math.h>
29 #include <stdarg.h>
30 
31 #define WIN32_NO_STATUS
32 #define _INC_WINDOWS
33 #define COM_NO_WINDOWS_H
34 
35 #define COBJMACROS
36 #define NONAMELESSSTRUCT
37 #define NONAMELESSUNION
38 
39 #include <windef.h>
40 #include <winbase.h>
41 #include <winnls.h>
42 #include <wingdi.h>
43 #include <winternl.h>
44 #include <objbase.h>
45 #include <audioclient.h>
46 #include <mmddk.h>
47 #include <dsound.h>
48 #include <dsconf.h>
49 #include <dsdriver.h>
50 #include <vfwmsgs.h>
51 
52 #include <wine/debug.h>
53 #include <wine/list.h>
54 
55 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
56 
57 /* Linux does not support better timing than 10ms */
58 #define DS_TIME_RES 2  /* Resolution of multimedia timer */
59 #define DS_TIME_DEL 10  /* Delay of multimedia timer callback, and duration of HEL fragment */
60 
61 /* direct sound hardware acceleration levels */
62 #define DS_HW_ACCEL_FULL        0	/* default on Windows 98 */
63 #define DS_HW_ACCEL_STANDARD    1	/* default on Windows 2000 */
64 #define DS_HW_ACCEL_BASIC       2
65 #define DS_HW_ACCEL_EMULATION   3
66 
67 extern int ds_emuldriver DECLSPEC_HIDDEN;
68 extern int ds_hel_buflen DECLSPEC_HIDDEN;
69 extern int ds_snd_queue_max DECLSPEC_HIDDEN;
70 extern int ds_snd_queue_min DECLSPEC_HIDDEN;
71 extern int ds_snd_shadow_maxsize DECLSPEC_HIDDEN;
72 extern int ds_hw_accel DECLSPEC_HIDDEN;
73 extern int ds_default_sample_rate DECLSPEC_HIDDEN;
74 extern int ds_default_bits_per_sample DECLSPEC_HIDDEN;
75 
76 /*****************************************************************************
77  * Predeclare the interface implementation structures
78  */
79 typedef struct IDirectSoundImpl              IDirectSoundImpl;
80 typedef struct IDirectSound_IUnknown         IDirectSound_IUnknown;
81 typedef struct IDirectSound_IDirectSound     IDirectSound_IDirectSound;
82 typedef struct IDirectSound8_IUnknown        IDirectSound8_IUnknown;
83 typedef struct IDirectSound8_IDirectSound    IDirectSound8_IDirectSound;
84 typedef struct IDirectSound8_IDirectSound8   IDirectSound8_IDirectSound8;
85 typedef struct IDirectSoundBufferImpl        IDirectSoundBufferImpl;
86 typedef struct IDirectSoundCaptureImpl       IDirectSoundCaptureImpl;
87 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
88 typedef struct IDirectSoundNotifyImpl        IDirectSoundNotifyImpl;
89 typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
90 typedef struct IDirectSound3DListenerImpl    IDirectSound3DListenerImpl;
91 typedef struct IDirectSound3DBufferImpl      IDirectSound3DBufferImpl;
92 typedef struct IKsBufferPropertySetImpl      IKsBufferPropertySetImpl;
93 typedef struct DirectSoundDevice             DirectSoundDevice;
94 typedef struct DirectSoundCaptureDevice      DirectSoundCaptureDevice;
95 
96 /* dsound_convert.h */
97 typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
98 extern const bitsconvertfunc convertbpp[5][4] DECLSPEC_HIDDEN;
99 typedef void (*mixfunc)(const void *, void *, unsigned);
100 extern const mixfunc mixfunctions[4] DECLSPEC_HIDDEN;
101 typedef void (*normfunc)(const void *, void *, unsigned);
102 extern const normfunc normfunctions[4] DECLSPEC_HIDDEN;
103 
104 /*****************************************************************************
105  * IDirectSoundDevice implementation structure
106  */
107 struct DirectSoundDevice
108 {
109     LONG                        ref;
110 
111     GUID                        guid;
112     PIDSDRIVER                  driver;
113     DSDRIVERDESC                drvdesc;
114     DSDRIVERCAPS                drvcaps;
115     DWORD                       priolevel;
116     PWAVEFORMATEX               pwfx;
117     HWAVEOUT                    hwo;
118     LPWAVEHDR                   pwave;
119     UINT                        timerID, pwplay, pwqueue, prebuf, helfrags;
120     DWORD                       fraglen;
121     PIDSDRIVERBUFFER            hwbuf;
122     LPBYTE                      buffer;
123     DWORD                       writelead, buflen, state, playpos, mixpos;
124     int                         nrofbuffers;
125     IDirectSoundBufferImpl**    buffers;
126     RTL_RWLOCK                  buffer_list_lock;
127     CRITICAL_SECTION            mixlock;
128     IDirectSoundBufferImpl     *primary;
129     DWORD                       speaker_config;
130     LPBYTE                      tmp_buffer, mix_buffer;
131     DWORD                       tmp_buffer_len, mix_buffer_len;
132 
133     DSVOLUMEPAN                 volpan;
134 
135     mixfunc mixfunction;
136     normfunc normfunction;
137 
138     /* DirectSound3DListener fields */
139     IDirectSound3DListenerImpl*	listener;
140     DS3DLISTENER                ds3dl;
141     BOOL                        ds3dl_need_recalc;
142 };
143 
144 /* reference counted buffer memory for duplicated buffer memory */
145 typedef struct BufferMemory
146 {
147     LONG                        ref;
148     LPBYTE                      memory;
149     struct list buffers;
150 } BufferMemory;
151 
152 ULONG DirectSoundDevice_Release(DirectSoundDevice * device) DECLSPEC_HIDDEN;
153 HRESULT DirectSoundDevice_Initialize(
154     DirectSoundDevice ** ppDevice,
155     LPCGUID lpcGUID) DECLSPEC_HIDDEN;
156 HRESULT DirectSoundDevice_AddBuffer(
157     DirectSoundDevice * device,
158     IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
159 HRESULT DirectSoundDevice_RemoveBuffer(
160     DirectSoundDevice * device,
161     IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
162 HRESULT DirectSoundDevice_GetCaps(DirectSoundDevice * device, LPDSCAPS lpDSCaps) DECLSPEC_HIDDEN;
163 HRESULT DirectSoundDevice_CreateSoundBuffer(
164     DirectSoundDevice * device,
165     LPCDSBUFFERDESC dsbd,
166     LPLPDIRECTSOUNDBUFFER ppdsb,
167     LPUNKNOWN lpunk,
168     BOOL from8) DECLSPEC_HIDDEN;
169 HRESULT DirectSoundDevice_DuplicateSoundBuffer(
170     DirectSoundDevice * device,
171     LPDIRECTSOUNDBUFFER psb,
172     LPLPDIRECTSOUNDBUFFER ppdsb) DECLSPEC_HIDDEN;
173 HRESULT DirectSoundDevice_SetCooperativeLevel(
174     DirectSoundDevice * devcie,
175     HWND hwnd,
176     DWORD level) DECLSPEC_HIDDEN;
177 HRESULT DirectSoundDevice_Compact(DirectSoundDevice * device) DECLSPEC_HIDDEN;
178 HRESULT DirectSoundDevice_GetSpeakerConfig(
179     DirectSoundDevice * device,
180     LPDWORD lpdwSpeakerConfig) DECLSPEC_HIDDEN;
181 HRESULT DirectSoundDevice_SetSpeakerConfig(
182     DirectSoundDevice * device,
183     DWORD config) DECLSPEC_HIDDEN;
184 HRESULT DirectSoundDevice_VerifyCertification(DirectSoundDevice * device,
185     LPDWORD pdwCertified) DECLSPEC_HIDDEN;
186 
187 /*****************************************************************************
188  * IDirectSoundBuffer implementation structure
189  */
190 struct IDirectSoundBufferImpl
191 {
192     IDirectSoundBuffer8         IDirectSoundBuffer8_iface;
193     LONG                        numIfaces; /* "in use interfaces" refcount */
194     LONG                        ref;
195     /* IDirectSoundBufferImpl fields */
196     DirectSoundDevice*          device;
197     RTL_RWLOCK                  lock;
198     PIDSDRIVERBUFFER            hwbuf;
199     PWAVEFORMATEX               pwfx;
200     BufferMemory*               buffer;
201     LPBYTE                      tmp_buffer;
202     DWORD                       playflags,state,leadin;
203     DWORD                       writelead,buflen;
204     DWORD                       nAvgBytesPerSec;
205     DWORD                       freq, tmp_buffer_len, max_buffer_len;
206     DSVOLUMEPAN                 volpan;
207     DSBUFFERDESC                dsbd;
208     /* used for frequency conversion (PerfectPitch) */
209     ULONG                       freqneeded, freqAdjust, freqAcc, freqAccNext, resampleinmixer;
210     /* used for mixing */
211     DWORD                       primary_mixpos, buf_mixpos, sec_mixpos;
212 
213     /* IDirectSoundNotifyImpl fields */
214     IDirectSoundNotifyImpl*     notify;
215     LPDSBPOSITIONNOTIFY         notifies;
216     int                         nrofnotifies;
217     PIDSDRIVERNOTIFY            hwnotify;
218 
219     /* DirectSound3DBuffer fields */
220     IDirectSound3DBufferImpl*   ds3db;
221     DS3DBUFFER                  ds3db_ds3db;
222     LONG                        ds3db_lVolume;
223     BOOL                        ds3db_need_recalc;
224 
225     /* IKsPropertySet fields */
226     IKsBufferPropertySetImpl*   iks;
227     bitsconvertfunc convert;
228     struct list entry;
229 };
230 
231 HRESULT IDirectSoundBufferImpl_Create(
232     DirectSoundDevice *device,
233     IDirectSoundBufferImpl **ppdsb,
234     LPCDSBUFFERDESC dsbd) DECLSPEC_HIDDEN;
235 HRESULT IDirectSoundBufferImpl_Destroy(
236     IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
237 HRESULT IDirectSoundBufferImpl_Duplicate(
238     DirectSoundDevice *device,
239     IDirectSoundBufferImpl **ppdsb,
240     IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
241 void secondarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
242 
243 /*****************************************************************************
244  * DirectSoundCaptureDevice implementation structure
245  */
246 struct DirectSoundCaptureDevice
247 {
248     /* IDirectSoundCaptureImpl fields */
249     GUID                               guid;
250     LONG                               ref;
251 
252     /* DirectSound driver stuff */
253     PIDSCDRIVER                        driver;
254     DSDRIVERDESC                       drvdesc;
255     DSCDRIVERCAPS                      drvcaps;
256     PIDSCDRIVERBUFFER                  hwbuf;
257 
258     /* wave driver info */
259     HWAVEIN                            hwi;
260 
261     /* more stuff */
262     LPBYTE                             buffer;
263     DWORD                              buflen;
264 
265     PWAVEFORMATEX                      pwfx;
266 
267     IDirectSoundCaptureBufferImpl*     capture_buffer;
268     DWORD                              state;
269     LPWAVEHDR                          pwave;
270     int                                nrofpwaves;
271     int                                index;
272     CRITICAL_SECTION                   lock;
273 };
274 
275 /*****************************************************************************
276  * IDirectSoundCaptureBuffer implementation structure
277  */
278 struct IDirectSoundCaptureBufferImpl
279 {
280     /* IUnknown fields */
281     const IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
282     LONG                                ref;
283 
284     /* IDirectSoundCaptureBufferImpl fields */
285     DirectSoundCaptureDevice*           device;
286     /* FIXME: don't need this */
287     LPDSCBUFFERDESC                     pdscbd;
288     DWORD                               flags;
289 
290     /* IDirectSoundCaptureNotifyImpl fields */
291     IDirectSoundCaptureNotifyImpl*      notify;
292     LPDSBPOSITIONNOTIFY                 notifies;
293     int                                 nrofnotifies;
294     PIDSDRIVERNOTIFY                    hwnotify;
295 };
296 
297 /*****************************************************************************
298  *  IDirectSound3DListener implementation structure
299  */
300 struct IDirectSound3DListenerImpl
301 {
302     /* IUnknown fields */
303     const IDirectSound3DListenerVtbl *lpVtbl;
304     LONG                        ref;
305     /* IDirectSound3DListenerImpl fields */
306     DirectSoundDevice*          device;
307 };
308 
309 HRESULT IDirectSound3DListenerImpl_Create(
310     DirectSoundDevice           *device,
311     IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN;
312 
313 /*****************************************************************************
314  *  IKsBufferPropertySet implementation structure
315  */
316 struct IKsBufferPropertySetImpl
317 {
318     /* IUnknown fields */
319     const IKsPropertySetVtbl   *lpVtbl;
320     LONG 			ref;
321     /* IKsPropertySetImpl fields */
322     IDirectSoundBufferImpl*	dsb;
323 };
324 
325 HRESULT IKsBufferPropertySetImpl_Create(
326     IDirectSoundBufferImpl *dsb,
327     IKsBufferPropertySetImpl **piks) DECLSPEC_HIDDEN;
328 HRESULT IKsBufferPropertySetImpl_Destroy(
329     IKsBufferPropertySetImpl *piks) DECLSPEC_HIDDEN;
330 
331 HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, IKsPropertySet **piks) DECLSPEC_HIDDEN;
332 
333 /*****************************************************************************
334  * IDirectSound3DBuffer implementation structure
335  */
336 struct IDirectSound3DBufferImpl
337 {
338     /* IUnknown fields */
339     const IDirectSound3DBufferVtbl *lpVtbl;
340     LONG                        ref;
341     /* IDirectSound3DBufferImpl fields */
342     IDirectSoundBufferImpl*     dsb;
343 };
344 
345 HRESULT IDirectSound3DBufferImpl_Create(
346     IDirectSoundBufferImpl *dsb,
347     IDirectSound3DBufferImpl **pds3db) DECLSPEC_HIDDEN;
348 HRESULT IDirectSound3DBufferImpl_Destroy(
349     IDirectSound3DBufferImpl *pds3db) DECLSPEC_HIDDEN;
350 
351 /*******************************************************************************
352  */
353 
354 /* dsound.c */
355 
356 HRESULT DSOUND_Create(REFIID riid, LPDIRECTSOUND *ppDS) DECLSPEC_HIDDEN;
357 HRESULT DSOUND_Create8(REFIID riid, LPDIRECTSOUND8 *ppDS) DECLSPEC_HIDDEN;
358 
359 /* primary.c */
360 
361 DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign) DECLSPEC_HIDDEN;
362 HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) DECLSPEC_HIDDEN;
363 HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) DECLSPEC_HIDDEN;
364 HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device) DECLSPEC_HIDDEN;
365 HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) DECLSPEC_HIDDEN;
366 HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos) DECLSPEC_HIDDEN;
367 LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
368 HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN;
369 HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
370     const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
371 void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
372 HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
373 
374 /* duplex.c */
375 
376 HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD) DECLSPEC_HIDDEN;
377 
378 /* mixer.c */
379 DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) DECLSPEC_HIDDEN;
380 void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
381 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
382 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
383 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
384 void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN;
385 DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot) DECLSPEC_HIDDEN;
386 
387 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN;
388 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN;
389 
390 /* sound3d.c */
391 
392 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
393 
394 /* capture.c */
395 
396 HRESULT DSOUND_CaptureCreate(REFIID riid, LPDIRECTSOUNDCAPTURE *ppDSC) DECLSPEC_HIDDEN;
397 HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8) DECLSPEC_HIDDEN;
398 
399 #define STATE_STOPPED   0
400 #define STATE_STARTING  1
401 #define STATE_PLAYING   2
402 #define STATE_CAPTURING 2
403 #define STATE_STOPPING  3
404 
405 #define DSOUND_FREQSHIFT (20)
406 
407 extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
408 extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
409 
410 extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
411 extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
412 
413 HRESULT mmErr(UINT err) DECLSPEC_HIDDEN;
414 void setup_dsound_options(void) DECLSPEC_HIDDEN;
415 const char * dumpCooperativeLevel(DWORD level) DECLSPEC_HIDDEN;
416 
417 #endif /* _DSOUND_PRIVATE_H_ */
418