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
76 DirectSoundDevice
*device
;
82 HRESULT
IDirectSoundImpl_Create(
83 LPDIRECTSOUND8
* ppds
);
85 /*****************************************************************************
86 * IDirectSoundDevice implementation structure
88 struct DirectSoundDevice
99 LPWAVEHDR pwave
[DS_HEL_FRAGS
];
100 UINT timerID
, pwplay
, pwwrite
, pwqueue
, prebuf
, precount
;
102 PIDSDRIVERBUFFER hwbuf
;
104 DWORD writelead
, buflen
, state
, playpos
, mixpos
;
107 IDirectSoundBufferImpl
** buffers
;
108 RTL_RWLOCK buffer_list_lock
;
109 CRITICAL_SECTION mixlock
;
110 PrimaryBufferImpl
* primary
;
112 DWORD speaker_config
;
114 DWORD tmp_buffer_len
;
116 /* DirectSound3DListener fields */
117 IDirectSound3DListenerImpl
* listener
;
119 BOOL ds3dl_need_recalc
;
122 /* reference counted buffer memory for duplicated buffer memory */
123 typedef struct BufferMemory
129 HRESULT
DirectSoundDevice_Create(DirectSoundDevice
** ppDevice
);
130 ULONG
DirectSoundDevice_AddRef(DirectSoundDevice
* device
);
131 ULONG
DirectSoundDevice_Release(DirectSoundDevice
* device
);
132 HRESULT
DirectSoundDevice_Initialize(
133 DirectSoundDevice
** ppDevice
,
135 HRESULT
DirectSoundDevice_AddBuffer(
136 DirectSoundDevice
* device
,
137 IDirectSoundBufferImpl
* pDSB
);
138 HRESULT
DirectSoundDevice_RemoveBuffer(
139 DirectSoundDevice
* device
,
140 IDirectSoundBufferImpl
* pDSB
);
141 HRESULT
DirectSoundDevice_GetCaps(DirectSoundDevice
* device
, LPDSCAPS lpDSCaps
);
142 HRESULT
DirectSoundDevice_CreateSoundBuffer(
143 DirectSoundDevice
* device
,
144 LPCDSBUFFERDESC dsbd
,
145 LPLPDIRECTSOUNDBUFFER ppdsb
,
148 HRESULT
DirectSoundDevice_DuplicateSoundBuffer(
149 DirectSoundDevice
* device
,
150 LPDIRECTSOUNDBUFFER psb
,
151 LPLPDIRECTSOUNDBUFFER ppdsb
);
152 HRESULT
DirectSoundDevice_SetCooperativeLevel(
153 DirectSoundDevice
* devcie
,
156 HRESULT
DirectSoundDevice_Compact(DirectSoundDevice
* device
);
157 HRESULT
DirectSoundDevice_GetSpeakerConfig(
158 DirectSoundDevice
* device
,
159 LPDWORD lpdwSpeakerConfig
);
160 HRESULT
DirectSoundDevice_SetSpeakerConfig(
161 DirectSoundDevice
* device
,
163 HRESULT
DirectSoundDevice_VerifyCertification(
164 DirectSoundDevice
* device
,
165 LPDWORD pdwCertified
);
167 /*****************************************************************************
168 * IDirectSound COM components
170 struct IDirectSound_IUnknown
{
171 const IUnknownVtbl
*lpVtbl
;
176 HRESULT
IDirectSound_IUnknown_Create(
180 struct IDirectSound_IDirectSound
{
181 const IDirectSoundVtbl
*lpVtbl
;
186 HRESULT
IDirectSound_IDirectSound_Create(
188 LPDIRECTSOUND
* ppds
);
190 /*****************************************************************************
191 * IDirectSound8 COM components
193 struct IDirectSound8_IUnknown
{
194 const IUnknownVtbl
*lpVtbl
;
199 HRESULT
IDirectSound8_IUnknown_Create(
203 struct IDirectSound8_IDirectSound
{
204 const IDirectSoundVtbl
*lpVtbl
;
209 HRESULT
IDirectSound8_IDirectSound_Create(
211 LPDIRECTSOUND
* ppds
);
213 struct IDirectSound8_IDirectSound8
{
214 const IDirectSound8Vtbl
*lpVtbl
;
219 HRESULT
IDirectSound8_IDirectSound8_Create(
221 LPDIRECTSOUND8
* ppds
);
223 /*****************************************************************************
224 * IDirectSoundBuffer implementation structure
226 struct IDirectSoundBufferImpl
228 /* FIXME: document */
229 /* IUnknown fields */
230 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
232 /* IDirectSoundBufferImpl fields */
233 SecondaryBufferImpl
* secondary
;
234 DirectSoundDevice
* device
;
235 CRITICAL_SECTION lock
;
236 PIDSDRIVERBUFFER hwbuf
;
238 BufferMemory
* buffer
;
239 DWORD playflags
,state
,leadin
;
240 DWORD playpos
,startpos
,writelead
,buflen
;
241 DWORD nAvgBytesPerSec
;
243 DSVOLUMEPAN volpan
, cvolpan
;
245 /* used for frequency conversion (PerfectPitch) */
246 ULONG freqAdjust
, freqAcc
;
247 /* used for intelligent (well, sort of) prebuffering */
248 DWORD probably_valid_to
, last_playpos
;
249 DWORD primary_mixpos
, buf_mixpos
;
252 /* IDirectSoundNotifyImpl fields */
253 IDirectSoundNotifyImpl
* notify
;
254 LPDSBPOSITIONNOTIFY notifies
;
256 PIDSDRIVERNOTIFY hwnotify
;
258 /* DirectSound3DBuffer fields */
259 IDirectSound3DBufferImpl
* ds3db
;
260 DS3DBUFFER ds3db_ds3db
;
262 BOOL ds3db_need_recalc
;
264 /* IKsPropertySet fields */
265 IKsBufferPropertySetImpl
* iks
;
268 HRESULT
IDirectSoundBufferImpl_Create(
269 DirectSoundDevice
*device
,
270 IDirectSoundBufferImpl
**ppdsb
,
271 LPCDSBUFFERDESC dsbd
);
272 HRESULT
IDirectSoundBufferImpl_Destroy(
273 IDirectSoundBufferImpl
*pdsb
);
274 HRESULT
IDirectSoundBufferImpl_Duplicate(
275 DirectSoundDevice
*device
,
276 IDirectSoundBufferImpl
**ppdsb
,
277 IDirectSoundBufferImpl
*pdsb
);
279 /*****************************************************************************
280 * SecondaryBuffer implementation structure
282 struct SecondaryBufferImpl
284 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
286 IDirectSoundBufferImpl
* dsb
;
289 HRESULT
SecondaryBufferImpl_Create(
290 IDirectSoundBufferImpl
*dsb
,
291 SecondaryBufferImpl
**pdsb
);
292 HRESULT
SecondaryBufferImpl_Destroy(
293 SecondaryBufferImpl
*pdsb
);
295 /*****************************************************************************
296 * PrimaryBuffer implementation structure
298 struct PrimaryBufferImpl
300 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
302 DirectSoundDevice
* device
;
305 HRESULT
PrimaryBufferImpl_Create(
306 DirectSoundDevice
* device
,
307 PrimaryBufferImpl
**ppdsb
,
308 LPCDSBUFFERDESC dsbd
);
310 /*****************************************************************************
311 * IDirectSoundCapture implementation structure
313 struct IDirectSoundCaptureImpl
315 /* IUnknown fields */
316 const IDirectSoundCaptureVtbl
*lpVtbl
;
319 DirectSoundCaptureDevice
*device
;
322 HRESULT
IDirectSoundCaptureImpl_Create(
323 LPDIRECTSOUNDCAPTURE8
* ppds
);
325 /*****************************************************************************
326 * DirectSoundCaptureDevice implementation structure
328 struct DirectSoundCaptureDevice
330 /* IDirectSoundCaptureImpl fields */
334 /* DirectSound driver stuff */
336 DSDRIVERDESC drvdesc
;
337 DSCDRIVERCAPS drvcaps
;
338 PIDSCDRIVERBUFFER hwbuf
;
340 /* wave driver info */
350 IDirectSoundCaptureBufferImpl
* capture_buffer
;
355 CRITICAL_SECTION lock
;
358 HRESULT
DirectSoundCaptureDevice_Create(
359 DirectSoundCaptureDevice
** ppDevice
);
361 HRESULT
DirectSoundCaptureDevice_Initialize(
362 DirectSoundCaptureDevice
** ppDevice
,
365 ULONG
DirectSoundCaptureDevice_AddRef(
366 DirectSoundCaptureDevice
* device
);
368 ULONG
DirectSoundCaptureDevice_Release(
369 DirectSoundCaptureDevice
* device
);
371 /*****************************************************************************
372 * IDirectSoundCaptureBuffer implementation structure
374 struct IDirectSoundCaptureBufferImpl
376 /* IUnknown fields */
377 const IDirectSoundCaptureBuffer8Vtbl
*lpVtbl
;
380 /* IDirectSoundCaptureBufferImpl fields */
381 DirectSoundCaptureDevice
* device
;
382 /* FIXME: don't need this */
383 LPDSCBUFFERDESC pdscbd
;
386 /* IDirectSoundCaptureNotifyImpl fields */
387 IDirectSoundCaptureNotifyImpl
* notify
;
388 LPDSBPOSITIONNOTIFY notifies
;
390 PIDSDRIVERNOTIFY hwnotify
;
393 HRESULT
IDirectSoundCaptureBufferImpl_Create(
394 DirectSoundCaptureDevice
*device
,
395 IDirectSoundCaptureBufferImpl
** ppobj
,
396 LPCDSCBUFFERDESC lpcDSCBufferDesc
);
398 /*****************************************************************************
399 * IDirectSoundFullDuplex implementation structure
401 struct IDirectSoundFullDuplexImpl
403 /* IUnknown fields */
404 const IDirectSoundFullDuplexVtbl
*lpVtbl
;
407 /* IDirectSoundFullDuplexImpl fields */
410 /*****************************************************************************
411 * IDirectSoundNotify implementation structure
413 struct IDirectSoundNotifyImpl
415 /* IUnknown fields */
416 const IDirectSoundNotifyVtbl
*lpVtbl
;
418 IDirectSoundBufferImpl
* dsb
;
421 HRESULT
IDirectSoundNotifyImpl_Create(
422 IDirectSoundBufferImpl
*dsb
,
423 IDirectSoundNotifyImpl
**pdsn
);
424 HRESULT
IDirectSoundNotifyImpl_Destroy(
425 IDirectSoundNotifyImpl
*pdsn
);
427 /*****************************************************************************
428 * IDirectSoundCaptureNotify implementation structure
430 struct IDirectSoundCaptureNotifyImpl
432 /* IUnknown fields */
433 const IDirectSoundNotifyVtbl
*lpVtbl
;
435 IDirectSoundCaptureBufferImpl
* dscb
;
438 HRESULT
IDirectSoundCaptureNotifyImpl_Create(
439 IDirectSoundCaptureBufferImpl
*dscb
,
440 IDirectSoundCaptureNotifyImpl
** pdscn
);
442 /*****************************************************************************
443 * IDirectSound3DListener implementation structure
445 struct IDirectSound3DListenerImpl
447 /* IUnknown fields */
448 const IDirectSound3DListenerVtbl
*lpVtbl
;
450 /* IDirectSound3DListenerImpl fields */
451 DirectSoundDevice
* device
;
454 HRESULT
IDirectSound3DListenerImpl_Create(
455 DirectSoundDevice
*device
,
456 IDirectSound3DListenerImpl
**pdsl
);
458 /*****************************************************************************
459 * IKsBufferPropertySet implementation structure
461 struct IKsBufferPropertySetImpl
463 /* IUnknown fields */
464 const IKsPropertySetVtbl
*lpVtbl
;
466 /* IKsPropertySetImpl fields */
467 IDirectSoundBufferImpl
* dsb
;
470 HRESULT
IKsBufferPropertySetImpl_Create(
471 IDirectSoundBufferImpl
*dsb
,
472 IKsBufferPropertySetImpl
**piks
);
473 HRESULT
IKsBufferPropertySetImpl_Destroy(
474 IKsBufferPropertySetImpl
*piks
);
476 /*****************************************************************************
477 * IKsPrivatePropertySet implementation structure
479 struct IKsPrivatePropertySetImpl
481 /* IUnknown fields */
482 const IKsPropertySetVtbl
*lpVtbl
;
486 HRESULT
IKsPrivatePropertySetImpl_Create(
487 IKsPrivatePropertySetImpl
**piks
);
489 /*****************************************************************************
490 * IDirectSound3DBuffer implementation structure
492 struct IDirectSound3DBufferImpl
494 /* IUnknown fields */
495 const IDirectSound3DBufferVtbl
*lpVtbl
;
497 /* IDirectSound3DBufferImpl fields */
498 IDirectSoundBufferImpl
* dsb
;
501 HRESULT
IDirectSound3DBufferImpl_Create(
502 IDirectSoundBufferImpl
*dsb
,
503 IDirectSound3DBufferImpl
**pds3db
);
504 HRESULT
IDirectSound3DBufferImpl_Destroy(
505 IDirectSound3DBufferImpl
*pds3db
);
507 /*******************************************************************************
508 * DirectSound ClassFactory implementation structure
510 struct IClassFactoryImpl
512 /* IUnknown fields */
513 const IClassFactoryVtbl
*lpVtbl
;
517 extern IClassFactoryImpl DSOUND_CAPTURE_CF
;
518 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF
;
520 /*******************************************************************************
525 HRESULT
DSOUND_Create(LPDIRECTSOUND
*ppDS
, IUnknown
*pUnkOuter
);
526 HRESULT
DSOUND_Create8(LPDIRECTSOUND8
*ppDS
, IUnknown
*pUnkOuter
);
530 HRESULT
DSOUND_PrimaryCreate(DirectSoundDevice
*device
);
531 HRESULT
DSOUND_PrimaryDestroy(DirectSoundDevice
*device
);
532 HRESULT
DSOUND_PrimaryPlay(DirectSoundDevice
*device
);
533 HRESULT
DSOUND_PrimaryStop(DirectSoundDevice
*device
);
534 HRESULT
DSOUND_PrimaryGetPosition(DirectSoundDevice
*device
, LPDWORD playpos
, LPDWORD writepos
);
535 HRESULT
DSOUND_PrimarySetFormat(DirectSoundDevice
*device
, LPCWAVEFORMATEX wfex
);
539 DWORD
DSOUND_CalcPlayPosition(IDirectSoundBufferImpl
*This
, DWORD pplay
, DWORD pwrite
);
543 void DSOUND_CheckEvent(IDirectSoundBufferImpl
*dsb
, int len
);
544 void DSOUND_ForceRemix(IDirectSoundBufferImpl
*dsb
);
545 void DSOUND_MixCancelAt(IDirectSoundBufferImpl
*dsb
, DWORD buf_writepos
);
546 void DSOUND_WaveQueue(DirectSoundDevice
*device
, DWORD mixq
);
547 void DSOUND_PerformMix(DirectSoundDevice
*device
);
548 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan
);
549 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan
);
550 void DSOUND_RecalcFormat(IDirectSoundBufferImpl
*dsb
);
551 void CALLBACK
DSOUND_timer(UINT timerID
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
552 void CALLBACK
DSOUND_callback(HWAVEOUT hwo
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
556 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl
*dsb
);
560 HRESULT WINAPI
IDirectSoundCaptureImpl_CreateCaptureBuffer(
561 LPDIRECTSOUNDCAPTURE iface
,
562 LPCDSCBUFFERDESC lpcDSCBufferDesc
,
563 LPDIRECTSOUNDCAPTUREBUFFER
* lplpDSCaptureBuffer
,
565 HRESULT WINAPI
IDirectSoundCaptureImpl_GetCaps(
566 LPDIRECTSOUNDCAPTURE iface
,
567 LPDSCCAPS lpDSCCaps
);
568 HRESULT WINAPI
IDirectSoundCaptureImpl_Initialize(
569 LPDIRECTSOUNDCAPTURE iface
,
572 #define STATE_STOPPED 0
573 #define STATE_STARTING 1
574 #define STATE_PLAYING 2
575 #define STATE_CAPTURING 2
576 #define STATE_STOPPING 3
578 #define DSOUND_FREQSHIFT (14)
580 extern DirectSoundDevice
* DSOUND_renderer
[MAXWAVEDRIVERS
];
581 extern GUID DSOUND_renderer_guids
[MAXWAVEDRIVERS
];
583 extern DirectSoundCaptureDevice
* DSOUND_capture
[MAXWAVEDRIVERS
];
584 extern GUID DSOUND_capture_guids
[MAXWAVEDRIVERS
];
586 HRESULT
mmErr(UINT err
);
587 void setup_dsound_options(void);
588 const char * get_device_id(LPCGUID pGuid
);
589 const char * dumpCooperativeLevel(DWORD level
);