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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 */
26 #define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
27 * (changing this won't help you) */
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
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
;
44 /*****************************************************************************
45 * Predeclare the interface implementation structures
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 typedef struct DirectSoundDevice DirectSoundDevice
;
67 typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice
;
69 /*****************************************************************************
70 * IDirectSound implementation structure
72 struct IDirectSoundImpl
75 const IDirectSound8Vtbl
*lpVtbl
;
78 DirectSoundDevice
*device
;
84 struct DirectSoundDevice
95 LPWAVEHDR pwave
[DS_HEL_FRAGS
];
96 UINT timerID
, pwplay
, pwwrite
, pwqueue
, prebuf
, precount
;
98 PIDSDRIVERBUFFER hwbuf
;
100 DWORD writelead
, buflen
, state
, playpos
, mixpos
;
103 IDirectSoundBufferImpl
** buffers
;
104 RTL_RWLOCK buffer_list_lock
;
105 CRITICAL_SECTION mixlock
;
106 PrimaryBufferImpl
* primary
;
108 DWORD speaker_config
;
110 DWORD tmp_buffer_len
;
112 /* DirectSound3DListener fields */
113 IDirectSound3DListenerImpl
* listener
;
115 BOOL ds3dl_need_recalc
;
118 /* reference counted buffer memory for duplicated buffer memory */
119 typedef struct BufferMemory
125 HRESULT
IDirectSoundImpl_Create(
126 LPDIRECTSOUND8
* ppds
);
128 HRESULT
DSOUND_Create(
130 IUnknown
*pUnkOuter
);
132 HRESULT
DSOUND_Create8(
133 LPDIRECTSOUND8
*ppDS
,
134 IUnknown
*pUnkOuter
);
136 /*****************************************************************************
137 * IDirectSound COM components
139 struct IDirectSound_IUnknown
{
140 const IUnknownVtbl
*lpVtbl
;
145 HRESULT
IDirectSound_IUnknown_Create(
149 struct IDirectSound_IDirectSound
{
150 const IDirectSoundVtbl
*lpVtbl
;
155 HRESULT
IDirectSound_IDirectSound_Create(
157 LPDIRECTSOUND
* ppds
);
159 /*****************************************************************************
160 * IDirectSound8 COM components
162 struct IDirectSound8_IUnknown
{
163 const IUnknownVtbl
*lpVtbl
;
168 HRESULT
IDirectSound8_IUnknown_Create(
172 struct IDirectSound8_IDirectSound
{
173 const IDirectSoundVtbl
*lpVtbl
;
178 HRESULT
IDirectSound8_IDirectSound_Create(
180 LPDIRECTSOUND
* ppds
);
182 struct IDirectSound8_IDirectSound8
{
183 const IDirectSound8Vtbl
*lpVtbl
;
188 HRESULT
IDirectSound8_IDirectSound8_Create(
190 LPDIRECTSOUND8
* ppds
);
192 /*****************************************************************************
193 * IDirectSoundBuffer implementation structure
195 struct IDirectSoundBufferImpl
197 /* FIXME: document */
198 /* IUnknown fields */
199 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
201 /* IDirectSoundBufferImpl fields */
202 SecondaryBufferImpl
* secondary
;
203 IDirectSoundImpl
* dsound
;
204 CRITICAL_SECTION lock
;
205 PIDSDRIVERBUFFER hwbuf
;
207 BufferMemory
* buffer
;
208 DWORD playflags
,state
,leadin
;
209 DWORD playpos
,startpos
,writelead
,buflen
;
210 DWORD nAvgBytesPerSec
;
212 DSVOLUMEPAN volpan
, cvolpan
;
214 /* used for frequency conversion (PerfectPitch) */
215 ULONG freqAdjust
, freqAcc
;
216 /* used for intelligent (well, sort of) prebuffering */
217 DWORD probably_valid_to
, last_playpos
;
218 DWORD primary_mixpos
, buf_mixpos
;
221 /* IDirectSoundNotifyImpl fields */
222 IDirectSoundNotifyImpl
* notify
;
223 LPDSBPOSITIONNOTIFY notifies
;
225 PIDSDRIVERNOTIFY hwnotify
;
227 /* DirectSound3DBuffer fields */
228 IDirectSound3DBufferImpl
* ds3db
;
229 DS3DBUFFER ds3db_ds3db
;
231 BOOL ds3db_need_recalc
;
233 /* IKsPropertySet fields */
234 IKsBufferPropertySetImpl
* iks
;
237 HRESULT
IDirectSoundBufferImpl_Create(
238 IDirectSoundImpl
*ds
,
239 IDirectSoundBufferImpl
**pdsb
,
240 LPCDSBUFFERDESC dsbd
);
241 HRESULT
IDirectSoundBufferImpl_Destroy(
242 IDirectSoundBufferImpl
*pdsb
);
244 /*****************************************************************************
245 * SecondaryBuffer implementation structure
247 struct SecondaryBufferImpl
249 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
251 IDirectSoundBufferImpl
* dsb
;
254 HRESULT
SecondaryBufferImpl_Create(
255 IDirectSoundBufferImpl
*dsb
,
256 SecondaryBufferImpl
**pdsb
);
257 HRESULT
SecondaryBufferImpl_Destroy(
258 SecondaryBufferImpl
*pdsb
);
260 /*****************************************************************************
261 * PrimaryBuffer implementation structure
263 struct PrimaryBufferImpl
265 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
267 IDirectSoundImpl
* dsound
;
270 HRESULT
PrimaryBufferImpl_Create(
271 IDirectSoundImpl
*ds
,
272 PrimaryBufferImpl
**pdsb
,
273 LPCDSBUFFERDESC dsbd
);
275 /*****************************************************************************
276 * IDirectSoundCapture implementation structure
278 struct IDirectSoundCaptureImpl
280 /* IUnknown fields */
281 const IDirectSoundCaptureVtbl
*lpVtbl
;
284 DirectSoundCaptureDevice
*device
;
287 HRESULT
IDirectSoundCaptureImpl_Create(
288 LPDIRECTSOUNDCAPTURE8
* ppds
);
290 /*****************************************************************************
291 * DirectSoundCaptureDevice implementation structure
293 struct DirectSoundCaptureDevice
295 /* IDirectSoundCaptureImpl fields */
299 /* DirectSound driver stuff */
301 DSDRIVERDESC drvdesc
;
302 DSCDRIVERCAPS drvcaps
;
303 PIDSCDRIVERBUFFER hwbuf
;
305 /* wave driver info */
315 IDirectSoundCaptureBufferImpl
* capture_buffer
;
320 CRITICAL_SECTION lock
;
323 HRESULT
DirectSoundCaptureDevice_Create(
324 DirectSoundCaptureDevice
** ppDevice
);
326 HRESULT
DirectSoundCaptureDevice_Initialize(
327 DirectSoundCaptureDevice
** ppDevice
,
330 ULONG
DirectSoundCaptureDevice_AddRef(
331 DirectSoundCaptureDevice
* device
);
333 ULONG
DirectSoundCaptureDevice_Release(
334 DirectSoundCaptureDevice
* device
);
336 /*****************************************************************************
337 * IDirectSoundCaptureBuffer implementation structure
339 struct IDirectSoundCaptureBufferImpl
341 /* IUnknown fields */
342 const IDirectSoundCaptureBuffer8Vtbl
*lpVtbl
;
345 /* IDirectSoundCaptureBufferImpl fields */
346 DirectSoundCaptureDevice
* device
;
347 /* FIXME: don't need this */
348 LPDSCBUFFERDESC pdscbd
;
351 /* IDirectSoundCaptureNotifyImpl fields */
352 IDirectSoundCaptureNotifyImpl
* notify
;
353 LPDSBPOSITIONNOTIFY notifies
;
355 PIDSDRIVERNOTIFY hwnotify
;
358 HRESULT
IDirectSoundCaptureBufferImpl_Create(
359 DirectSoundCaptureDevice
*device
,
360 IDirectSoundCaptureBufferImpl
** ppobj
,
361 LPCDSCBUFFERDESC lpcDSCBufferDesc
);
363 /*****************************************************************************
364 * IDirectSoundFullDuplex implementation structure
366 struct IDirectSoundFullDuplexImpl
368 /* IUnknown fields */
369 const IDirectSoundFullDuplexVtbl
*lpVtbl
;
372 /* IDirectSoundFullDuplexImpl fields */
375 /*****************************************************************************
376 * IDirectSoundNotify implementation structure
378 struct IDirectSoundNotifyImpl
380 /* IUnknown fields */
381 const IDirectSoundNotifyVtbl
*lpVtbl
;
383 IDirectSoundBufferImpl
* dsb
;
386 HRESULT
IDirectSoundNotifyImpl_Create(
387 IDirectSoundBufferImpl
*dsb
,
388 IDirectSoundNotifyImpl
**pdsn
);
389 HRESULT
IDirectSoundNotifyImpl_Destroy(
390 IDirectSoundNotifyImpl
*pdsn
);
392 /*****************************************************************************
393 * IDirectSoundCaptureNotify implementation structure
395 struct IDirectSoundCaptureNotifyImpl
397 /* IUnknown fields */
398 const IDirectSoundNotifyVtbl
*lpVtbl
;
400 IDirectSoundCaptureBufferImpl
* dscb
;
403 HRESULT
IDirectSoundCaptureNotifyImpl_Create(
404 IDirectSoundCaptureBufferImpl
*dscb
,
405 IDirectSoundCaptureNotifyImpl
** pdscn
);
407 /*****************************************************************************
408 * IDirectSound3DListener implementation structure
410 struct IDirectSound3DListenerImpl
412 /* IUnknown fields */
413 const IDirectSound3DListenerVtbl
*lpVtbl
;
415 /* IDirectSound3DListenerImpl fields */
416 IDirectSoundImpl
* dsound
;
419 HRESULT
IDirectSound3DListenerImpl_Create(
420 PrimaryBufferImpl
*pb
,
421 IDirectSound3DListenerImpl
**pdsl
);
423 /*****************************************************************************
424 * IKsBufferPropertySet implementation structure
426 struct IKsBufferPropertySetImpl
428 /* IUnknown fields */
429 const IKsPropertySetVtbl
*lpVtbl
;
431 /* IKsPropertySetImpl fields */
432 IDirectSoundBufferImpl
* dsb
;
435 HRESULT
IKsBufferPropertySetImpl_Create(
436 IDirectSoundBufferImpl
*dsb
,
437 IKsBufferPropertySetImpl
**piks
);
438 HRESULT
IKsBufferPropertySetImpl_Destroy(
439 IKsBufferPropertySetImpl
*piks
);
441 /*****************************************************************************
442 * IKsPrivatePropertySet implementation structure
444 struct IKsPrivatePropertySetImpl
446 /* IUnknown fields */
447 const IKsPropertySetVtbl
*lpVtbl
;
451 HRESULT
IKsPrivatePropertySetImpl_Create(
452 IKsPrivatePropertySetImpl
**piks
);
454 /*****************************************************************************
455 * IDirectSound3DBuffer implementation structure
457 struct IDirectSound3DBufferImpl
459 /* IUnknown fields */
460 const IDirectSound3DBufferVtbl
*lpVtbl
;
462 /* IDirectSound3DBufferImpl fields */
463 IDirectSoundBufferImpl
* dsb
;
466 HRESULT
IDirectSound3DBufferImpl_Create(
467 IDirectSoundBufferImpl
*dsb
,
468 IDirectSound3DBufferImpl
**pds3db
);
469 HRESULT
IDirectSound3DBufferImpl_Destroy(
470 IDirectSound3DBufferImpl
*pds3db
);
472 /*******************************************************************************
473 * DirectSound ClassFactory implementation structure
475 struct IClassFactoryImpl
477 /* IUnknown fields */
478 const IClassFactoryVtbl
*lpVtbl
;
482 extern IClassFactoryImpl DSOUND_CAPTURE_CF
;
483 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF
;
485 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan
);
486 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan
);
487 void DSOUND_RecalcFormat(IDirectSoundBufferImpl
*dsb
);
491 HRESULT
DSOUND_AddBuffer(IDirectSoundImpl
* pDS
, IDirectSoundBufferImpl
* pDSB
);
492 HRESULT
DSOUND_RemoveBuffer(IDirectSoundImpl
* pDS
, IDirectSoundBufferImpl
* pDSB
);
496 HRESULT
DSOUND_PrimaryCreate(DirectSoundDevice
*device
);
497 HRESULT
DSOUND_PrimaryDestroy(DirectSoundDevice
*device
);
498 HRESULT
DSOUND_PrimaryPlay(DirectSoundDevice
*device
);
499 HRESULT
DSOUND_PrimaryStop(DirectSoundDevice
*device
);
500 HRESULT
DSOUND_PrimaryGetPosition(DirectSoundDevice
*device
, LPDWORD playpos
, LPDWORD writepos
);
504 DWORD
DSOUND_CalcPlayPosition(IDirectSoundBufferImpl
*This
, DWORD pplay
, DWORD pwrite
);
508 void DSOUND_CheckEvent(IDirectSoundBufferImpl
*dsb
, int len
);
509 void DSOUND_ForceRemix(IDirectSoundBufferImpl
*dsb
);
510 void DSOUND_MixCancelAt(IDirectSoundBufferImpl
*dsb
, DWORD buf_writepos
);
511 void DSOUND_WaveQueue(DirectSoundDevice
*device
, DWORD mixq
);
512 void DSOUND_PerformMix(DirectSoundDevice
*device
);
513 void CALLBACK
DSOUND_timer(UINT timerID
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
514 void CALLBACK
DSOUND_callback(HWAVEOUT hwo
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
518 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl
*dsb
);
520 #define STATE_STOPPED 0
521 #define STATE_STARTING 1
522 #define STATE_PLAYING 2
523 #define STATE_CAPTURING 2
524 #define STATE_STOPPING 3
526 #define DSOUND_FREQSHIFT (14)
528 extern DirectSoundDevice
* DSOUND_renderer
[MAXWAVEDRIVERS
];
529 extern GUID DSOUND_renderer_guids
[MAXWAVEDRIVERS
];
531 extern DirectSoundCaptureDevice
* DSOUND_capture
[MAXWAVEDRIVERS
];
532 extern GUID DSOUND_capture_guids
[MAXWAVEDRIVERS
];
534 extern HRESULT
mmErr(UINT err
);
535 extern void setup_dsound_options(void);
536 extern const char * get_device_id(LPCGUID pGuid
);