3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
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.
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.
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
22 /* Linux does not support better timing than 10ms */
23 #define DS_TIME_RES 2 /* Resolution of multimedia timer */
24 #define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
27 #include "mmdeviceapi.h"
28 #include "audioclient.h"
31 #include "wine/list.h"
33 extern int ds_emuldriver DECLSPEC_HIDDEN
;
34 extern int ds_hel_buflen DECLSPEC_HIDDEN
;
35 extern int ds_snd_queue_max DECLSPEC_HIDDEN
;
36 extern int ds_snd_shadow_maxsize DECLSPEC_HIDDEN
;
37 extern int ds_default_sample_rate DECLSPEC_HIDDEN
;
38 extern int ds_default_bits_per_sample DECLSPEC_HIDDEN
;
40 /*****************************************************************************
41 * Predeclare the interface implementation structures
43 typedef struct IDirectSoundImpl IDirectSoundImpl
;
44 typedef struct IDirectSound_IUnknown IDirectSound_IUnknown
;
45 typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound
;
46 typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown
;
47 typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound
;
48 typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8
;
49 typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl
;
50 typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl
;
51 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl
;
52 typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl
;
53 typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl
;
54 typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl
;
55 typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl
;
56 typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl
;
57 typedef struct DirectSoundDevice DirectSoundDevice
;
58 typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice
;
60 /* dsound_convert.h */
61 typedef void (*bitsconvertfunc
)(const void *, void *, UINT
, UINT
, INT
, UINT
, UINT
);
62 extern const bitsconvertfunc convertbpp
[5][4] DECLSPEC_HIDDEN
;
63 typedef void (*mixfunc
)(const void *, void *, unsigned);
64 extern const mixfunc mixfunctions
[4] DECLSPEC_HIDDEN
;
65 typedef void (*normfunc
)(const void *, void *, unsigned);
66 extern const normfunc normfunctions
[4] DECLSPEC_HIDDEN
;
68 typedef struct _DSDRIVERDESC
78 LPVOID pvDirectDrawHeap
;
79 DWORD dwMemStartAddress
;
80 DWORD dwMemEndAddress
;
81 DWORD dwMemAllocExtra
;
84 } DSDRIVERDESC
,*PDSDRIVERDESC
;
86 typedef struct _DSDRIVERCAPS
89 DWORD dwMinSecondarySampleRate
;
90 DWORD dwMaxSecondarySampleRate
;
91 DWORD dwPrimaryBuffers
;
92 DWORD dwMaxHwMixingAllBuffers
;
93 DWORD dwMaxHwMixingStaticBuffers
;
94 DWORD dwMaxHwMixingStreamingBuffers
;
95 DWORD dwFreeHwMixingAllBuffers
;
96 DWORD dwFreeHwMixingStaticBuffers
;
97 DWORD dwFreeHwMixingStreamingBuffers
;
98 DWORD dwMaxHw3DAllBuffers
;
99 DWORD dwMaxHw3DStaticBuffers
;
100 DWORD dwMaxHw3DStreamingBuffers
;
101 DWORD dwFreeHw3DAllBuffers
;
102 DWORD dwFreeHw3DStaticBuffers
;
103 DWORD dwFreeHw3DStreamingBuffers
;
104 DWORD dwTotalHwMemBytes
;
105 DWORD dwFreeHwMemBytes
;
106 DWORD dwMaxContigFreeHwMemBytes
;
107 } DSDRIVERCAPS
,*PDSDRIVERCAPS
;
109 typedef struct _DSVOLUMEPAN
111 DWORD dwTotalLeftAmpFactor
;
112 DWORD dwTotalRightAmpFactor
;
114 DWORD dwVolAmpFactor
;
116 DWORD dwPanLeftAmpFactor
;
117 DWORD dwPanRightAmpFactor
;
118 } DSVOLUMEPAN
,*PDSVOLUMEPAN
;
120 typedef struct _DSCDRIVERCAPS
126 } DSCDRIVERCAPS
,*PDSCDRIVERCAPS
;
128 /*****************************************************************************
129 * IDirectSoundDevice implementation structure
131 struct DirectSoundDevice
136 DSDRIVERDESC drvdesc
;
137 DSDRIVERCAPS drvcaps
;
140 UINT timerID
, pwplay
, pwqueue
, prebuf
, helfrags
;
141 UINT64 last_pos_bytes
;
144 DWORD writelead
, buflen
, state
, playpos
, mixpos
;
146 IDirectSoundBufferImpl
** buffers
;
147 RTL_RWLOCK buffer_list_lock
;
148 CRITICAL_SECTION mixlock
;
149 IDirectSoundBufferImpl
*primary
;
150 DWORD speaker_config
;
151 LPBYTE tmp_buffer
, mix_buffer
;
152 DWORD tmp_buffer_len
, mix_buffer_len
;
157 normfunc normfunction
;
159 /* DirectSound3DListener fields */
160 IDirectSound3DListenerImpl
* listener
;
162 BOOL ds3dl_need_recalc
;
165 IAudioClient
*client
;
167 IAudioStreamVolume
*volume
;
168 IAudioRenderClient
*render
;
173 /* reference counted buffer memory for duplicated buffer memory */
174 typedef struct BufferMemory
181 ULONG
DirectSoundDevice_Release(DirectSoundDevice
* device
) DECLSPEC_HIDDEN
;
182 HRESULT
DirectSoundDevice_Initialize(
183 DirectSoundDevice
** ppDevice
,
184 LPCGUID lpcGUID
) DECLSPEC_HIDDEN
;
185 HRESULT
DirectSoundDevice_AddBuffer(
186 DirectSoundDevice
* device
,
187 IDirectSoundBufferImpl
* pDSB
) DECLSPEC_HIDDEN
;
188 HRESULT
DirectSoundDevice_RemoveBuffer(
189 DirectSoundDevice
* device
,
190 IDirectSoundBufferImpl
* pDSB
) DECLSPEC_HIDDEN
;
191 HRESULT
DirectSoundDevice_GetCaps(DirectSoundDevice
* device
, LPDSCAPS lpDSCaps
) DECLSPEC_HIDDEN
;
192 HRESULT
DirectSoundDevice_CreateSoundBuffer(
193 DirectSoundDevice
* device
,
194 LPCDSBUFFERDESC dsbd
,
195 LPLPDIRECTSOUNDBUFFER ppdsb
,
197 BOOL from8
) DECLSPEC_HIDDEN
;
198 HRESULT
DirectSoundDevice_DuplicateSoundBuffer(
199 DirectSoundDevice
* device
,
200 LPDIRECTSOUNDBUFFER psb
,
201 LPLPDIRECTSOUNDBUFFER ppdsb
) DECLSPEC_HIDDEN
;
202 HRESULT
DirectSoundDevice_SetCooperativeLevel(
203 DirectSoundDevice
* devcie
,
205 DWORD level
) DECLSPEC_HIDDEN
;
206 HRESULT
DirectSoundDevice_Compact(DirectSoundDevice
* device
) DECLSPEC_HIDDEN
;
207 HRESULT
DirectSoundDevice_GetSpeakerConfig(
208 DirectSoundDevice
* device
,
209 LPDWORD lpdwSpeakerConfig
) DECLSPEC_HIDDEN
;
210 HRESULT
DirectSoundDevice_SetSpeakerConfig(
211 DirectSoundDevice
* device
,
212 DWORD config
) DECLSPEC_HIDDEN
;
213 HRESULT
DirectSoundDevice_VerifyCertification(DirectSoundDevice
* device
,
214 LPDWORD pdwCertified
) DECLSPEC_HIDDEN
;
216 /*****************************************************************************
217 * IDirectSoundBuffer implementation structure
219 struct IDirectSoundBufferImpl
221 IDirectSoundBuffer8 IDirectSoundBuffer8_iface
;
222 LONG numIfaces
; /* "in use interfaces" refcount */
224 /* IDirectSoundBufferImpl fields */
225 DirectSoundDevice
* device
;
228 BufferMemory
* buffer
;
230 DWORD playflags
,state
,leadin
;
231 DWORD writelead
,buflen
;
232 DWORD nAvgBytesPerSec
;
233 DWORD freq
, tmp_buffer_len
, max_buffer_len
;
236 /* used for frequency conversion (PerfectPitch) */
237 ULONG freqneeded
, freqAdjust
, freqAcc
, freqAccNext
, resampleinmixer
;
238 /* used for mixing */
239 DWORD primary_mixpos
, buf_mixpos
, sec_mixpos
;
241 /* IDirectSoundNotifyImpl fields */
242 IDirectSoundNotifyImpl
* notify
;
243 LPDSBPOSITIONNOTIFY notifies
;
246 /* DirectSound3DBuffer fields */
247 IDirectSound3DBufferImpl
* ds3db
;
248 DS3DBUFFER ds3db_ds3db
;
250 BOOL ds3db_need_recalc
;
252 /* IKsPropertySet fields */
253 IKsBufferPropertySetImpl
* iks
;
254 bitsconvertfunc convert
;
258 HRESULT
IDirectSoundBufferImpl_Create(
259 DirectSoundDevice
*device
,
260 IDirectSoundBufferImpl
**ppdsb
,
261 LPCDSBUFFERDESC dsbd
) DECLSPEC_HIDDEN
;
262 HRESULT
IDirectSoundBufferImpl_Destroy(
263 IDirectSoundBufferImpl
*pdsb
) DECLSPEC_HIDDEN
;
264 HRESULT
IDirectSoundBufferImpl_Duplicate(
265 DirectSoundDevice
*device
,
266 IDirectSoundBufferImpl
**ppdsb
,
267 IDirectSoundBufferImpl
*pdsb
) DECLSPEC_HIDDEN
;
268 void secondarybuffer_destroy(IDirectSoundBufferImpl
*This
) DECLSPEC_HIDDEN
;
270 /*****************************************************************************
271 * DirectSoundCaptureDevice implementation structure
273 struct DirectSoundCaptureDevice
275 /* IDirectSoundCaptureImpl fields */
279 /* DirectSound driver stuff */
280 DSDRIVERDESC drvdesc
;
281 DSCDRIVERCAPS drvcaps
;
283 /* wave driver info */
292 IDirectSoundCaptureBufferImpl
* capture_buffer
;
297 CRITICAL_SECTION lock
;
300 /*****************************************************************************
301 * IDirectSoundCaptureBuffer implementation structure
303 struct IDirectSoundCaptureBufferImpl
305 /* IUnknown fields */
306 const IDirectSoundCaptureBuffer8Vtbl
*lpVtbl
;
309 /* IDirectSoundCaptureBufferImpl fields */
310 DirectSoundCaptureDevice
* device
;
311 /* FIXME: don't need this */
312 LPDSCBUFFERDESC pdscbd
;
315 /* IDirectSoundCaptureNotifyImpl fields */
316 IDirectSoundCaptureNotifyImpl
* notify
;
317 LPDSBPOSITIONNOTIFY notifies
;
321 /*****************************************************************************
322 * IDirectSound3DListener implementation structure
324 struct IDirectSound3DListenerImpl
326 /* IUnknown fields */
327 const IDirectSound3DListenerVtbl
*lpVtbl
;
329 /* IDirectSound3DListenerImpl fields */
330 DirectSoundDevice
* device
;
333 HRESULT
IDirectSound3DListenerImpl_Create(
334 DirectSoundDevice
*device
,
335 IDirectSound3DListenerImpl
**pdsl
) DECLSPEC_HIDDEN
;
337 /*****************************************************************************
338 * IKsBufferPropertySet implementation structure
340 struct IKsBufferPropertySetImpl
342 /* IUnknown fields */
343 const IKsPropertySetVtbl
*lpVtbl
;
345 /* IKsPropertySetImpl fields */
346 IDirectSoundBufferImpl
* dsb
;
349 HRESULT
IKsBufferPropertySetImpl_Create(
350 IDirectSoundBufferImpl
*dsb
,
351 IKsBufferPropertySetImpl
**piks
) DECLSPEC_HIDDEN
;
352 HRESULT
IKsBufferPropertySetImpl_Destroy(
353 IKsBufferPropertySetImpl
*piks
) DECLSPEC_HIDDEN
;
355 HRESULT
IKsPrivatePropertySetImpl_Create(REFIID riid
, IKsPropertySet
**piks
) DECLSPEC_HIDDEN
;
357 /*****************************************************************************
358 * IDirectSound3DBuffer implementation structure
360 struct IDirectSound3DBufferImpl
362 /* IUnknown fields */
363 const IDirectSound3DBufferVtbl
*lpVtbl
;
365 /* IDirectSound3DBufferImpl fields */
366 IDirectSoundBufferImpl
* dsb
;
369 HRESULT
IDirectSound3DBufferImpl_Create(
370 IDirectSoundBufferImpl
*dsb
,
371 IDirectSound3DBufferImpl
**pds3db
) DECLSPEC_HIDDEN
;
372 HRESULT
IDirectSound3DBufferImpl_Destroy(
373 IDirectSound3DBufferImpl
*pds3db
) DECLSPEC_HIDDEN
;
375 /*******************************************************************************
380 HRESULT
DSOUND_Create(REFIID riid
, LPDIRECTSOUND
*ppDS
) DECLSPEC_HIDDEN
;
381 HRESULT
DSOUND_Create8(REFIID riid
, LPDIRECTSOUND8
*ppDS
) DECLSPEC_HIDDEN
;
385 DWORD
DSOUND_fraglen(DWORD nSamplesPerSec
, DWORD nBlockAlign
) DECLSPEC_HIDDEN
;
386 HRESULT
DSOUND_PrimaryCreate(DirectSoundDevice
*device
) DECLSPEC_HIDDEN
;
387 HRESULT
DSOUND_PrimaryDestroy(DirectSoundDevice
*device
) DECLSPEC_HIDDEN
;
388 HRESULT
DSOUND_PrimaryPlay(DirectSoundDevice
*device
) DECLSPEC_HIDDEN
;
389 HRESULT
DSOUND_PrimaryStop(DirectSoundDevice
*device
) DECLSPEC_HIDDEN
;
390 HRESULT
DSOUND_PrimaryGetPosition(DirectSoundDevice
*device
, LPDWORD playpos
, LPDWORD writepos
) DECLSPEC_HIDDEN
;
391 LPWAVEFORMATEX
DSOUND_CopyFormat(LPCWAVEFORMATEX wfex
) DECLSPEC_HIDDEN
;
392 HRESULT
DSOUND_ReopenDevice(DirectSoundDevice
*device
, BOOL forcewave
) DECLSPEC_HIDDEN
;
393 HRESULT
primarybuffer_create(DirectSoundDevice
*device
, IDirectSoundBufferImpl
**ppdsb
,
394 const DSBUFFERDESC
*dsbd
) DECLSPEC_HIDDEN
;
395 void primarybuffer_destroy(IDirectSoundBufferImpl
*This
) DECLSPEC_HIDDEN
;
396 HRESULT
primarybuffer_SetFormat(DirectSoundDevice
*device
, LPCWAVEFORMATEX wfex
) DECLSPEC_HIDDEN
;
400 HRESULT
DSOUND_FullDuplexCreate(REFIID riid
, LPDIRECTSOUNDFULLDUPLEX
* ppDSFD
) DECLSPEC_HIDDEN
;
403 DWORD
DSOUND_bufpos_to_mixpos(const DirectSoundDevice
* device
, DWORD pos
) DECLSPEC_HIDDEN
;
404 void DSOUND_CheckEvent(const IDirectSoundBufferImpl
*dsb
, DWORD playpos
, int len
) DECLSPEC_HIDDEN
;
405 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan
) DECLSPEC_HIDDEN
;
406 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan
) DECLSPEC_HIDDEN
;
407 void DSOUND_RecalcFormat(IDirectSoundBufferImpl
*dsb
) DECLSPEC_HIDDEN
;
408 void DSOUND_MixToTemporary(const IDirectSoundBufferImpl
*dsb
, DWORD writepos
, DWORD mixlen
, BOOL inmixer
) DECLSPEC_HIDDEN
;
409 DWORD
DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl
*dsb
, DWORD secpos
, DWORD secmixpos
, DWORD
* overshot
) DECLSPEC_HIDDEN
;
411 void CALLBACK
DSOUND_timer(UINT timerID
, UINT msg
, DWORD_PTR dwUser
, DWORD_PTR dw1
, DWORD_PTR dw2
) DECLSPEC_HIDDEN
;
415 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl
*dsb
) DECLSPEC_HIDDEN
;
419 HRESULT
DSOUND_CaptureCreate(REFIID riid
, LPDIRECTSOUNDCAPTURE
*ppDSC
) DECLSPEC_HIDDEN
;
420 HRESULT
DSOUND_CaptureCreate8(REFIID riid
, LPDIRECTSOUNDCAPTURE8
*ppDSC8
) DECLSPEC_HIDDEN
;
422 #define STATE_STOPPED 0
423 #define STATE_STARTING 1
424 #define STATE_PLAYING 2
425 #define STATE_CAPTURING 2
426 #define STATE_STOPPING 3
428 #define DSOUND_FREQSHIFT (20)
430 extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN
;
431 extern struct list DSOUND_renderers DECLSPEC_HIDDEN
;
433 extern DirectSoundCaptureDevice
* DSOUND_capture
[MAXWAVEDRIVERS
] DECLSPEC_HIDDEN
;
435 extern GUID DSOUND_renderer_guids
[MAXWAVEDRIVERS
] DECLSPEC_HIDDEN
;
436 extern GUID DSOUND_capture_guids
[MAXWAVEDRIVERS
] DECLSPEC_HIDDEN
;
438 HRESULT
mmErr(UINT err
) DECLSPEC_HIDDEN
;
439 void setup_dsound_options(void) DECLSPEC_HIDDEN
;
440 const char * dumpCooperativeLevel(DWORD level
) DECLSPEC_HIDDEN
;
442 HRESULT
get_mmdevice(EDataFlow flow
, const GUID
*tgt
, IMMDevice
**device
) DECLSPEC_HIDDEN
;