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 HRESULT IDirectSoundImpl_Create(
85 LPDIRECTSOUND8 * ppds);
87 /*****************************************************************************
88 * IDirectSoundDevice implementation structure
90 struct DirectSoundDevice
101 LPWAVEHDR pwave[DS_HEL_FRAGS];
102 UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
104 PIDSDRIVERBUFFER hwbuf;
106 DWORD writelead, buflen, state, playpos, mixpos;
109 IDirectSoundBufferImpl** buffers;
110 RTL_RWLOCK buffer_list_lock;
111 CRITICAL_SECTION mixlock;
112 PrimaryBufferImpl* primary;
114 DWORD speaker_config;
116 DWORD tmp_buffer_len;
118 /* DirectSound3DListener fields */
119 IDirectSound3DListenerImpl* listener;
121 BOOL ds3dl_need_recalc;
124 /* reference counted buffer memory for duplicated buffer memory */
125 typedef struct BufferMemory
131 HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice);
132 ULONG DirectSoundDevice_AddRef(DirectSoundDevice * device);
133 ULONG DirectSoundDevice_Release(DirectSoundDevice * device);
134 HRESULT DirectSoundDevice_AddBuffer(
135 DirectSoundDevice *device,
136 IDirectSoundBufferImpl * pDSB);
137 HRESULT DirectSoundDevice_RemoveBuffer(
138 DirectSoundDevice *device,
139 IDirectSoundBufferImpl * pDSB);
141 /*****************************************************************************
142 * IDirectSound COM components
144 struct IDirectSound_IUnknown {
145 const IUnknownVtbl *lpVtbl;
150 HRESULT IDirectSound_IUnknown_Create(
154 struct IDirectSound_IDirectSound {
155 const IDirectSoundVtbl *lpVtbl;
160 HRESULT IDirectSound_IDirectSound_Create(
162 LPDIRECTSOUND * ppds);
164 /*****************************************************************************
165 * IDirectSound8 COM components
167 struct IDirectSound8_IUnknown {
168 const IUnknownVtbl *lpVtbl;
173 HRESULT IDirectSound8_IUnknown_Create(
177 struct IDirectSound8_IDirectSound {
178 const IDirectSoundVtbl *lpVtbl;
183 HRESULT IDirectSound8_IDirectSound_Create(
185 LPDIRECTSOUND * ppds);
187 struct IDirectSound8_IDirectSound8 {
188 const IDirectSound8Vtbl *lpVtbl;
193 HRESULT IDirectSound8_IDirectSound8_Create(
195 LPDIRECTSOUND8 * ppds);
197 /*****************************************************************************
198 * IDirectSoundBuffer implementation structure
200 struct IDirectSoundBufferImpl
202 /* FIXME: document */
203 /* IUnknown fields */
204 const IDirectSoundBuffer8Vtbl *lpVtbl;
206 /* IDirectSoundBufferImpl fields */
207 SecondaryBufferImpl* secondary;
208 DirectSoundDevice* device;
209 CRITICAL_SECTION lock;
210 PIDSDRIVERBUFFER hwbuf;
212 BufferMemory* buffer;
213 DWORD playflags,state,leadin;
214 DWORD playpos,startpos,writelead,buflen;
215 DWORD nAvgBytesPerSec;
217 DSVOLUMEPAN volpan, cvolpan;
219 /* used for frequency conversion (PerfectPitch) */
220 ULONG freqAdjust, freqAcc;
221 /* used for intelligent (well, sort of) prebuffering */
222 DWORD probably_valid_to, last_playpos;
223 DWORD primary_mixpos, buf_mixpos;
226 /* IDirectSoundNotifyImpl fields */
227 IDirectSoundNotifyImpl* notify;
228 LPDSBPOSITIONNOTIFY notifies;
230 PIDSDRIVERNOTIFY hwnotify;
232 /* DirectSound3DBuffer fields */
233 IDirectSound3DBufferImpl* ds3db;
234 DS3DBUFFER ds3db_ds3db;
236 BOOL ds3db_need_recalc;
238 /* IKsPropertySet fields */
239 IKsBufferPropertySetImpl* iks;
242 HRESULT IDirectSoundBufferImpl_Create(
243 DirectSoundDevice *device,
244 IDirectSoundBufferImpl **ppdsb,
245 LPCDSBUFFERDESC dsbd);
246 HRESULT IDirectSoundBufferImpl_Destroy(
247 IDirectSoundBufferImpl *pdsb);
248 HRESULT IDirectSoundBufferImpl_Duplicate(
249 DirectSoundDevice *device,
250 IDirectSoundBufferImpl **ppdsb,
251 IDirectSoundBufferImpl *pdsb);
253 /*****************************************************************************
254 * SecondaryBuffer implementation structure
256 struct SecondaryBufferImpl
258 const IDirectSoundBuffer8Vtbl *lpVtbl;
260 IDirectSoundBufferImpl* dsb;
263 HRESULT SecondaryBufferImpl_Create(
264 IDirectSoundBufferImpl *dsb,
265 SecondaryBufferImpl **pdsb);
266 HRESULT SecondaryBufferImpl_Destroy(
267 SecondaryBufferImpl *pdsb);
269 /*****************************************************************************
270 * PrimaryBuffer implementation structure
272 struct PrimaryBufferImpl
274 const IDirectSoundBuffer8Vtbl *lpVtbl;
276 DirectSoundDevice* device;
279 HRESULT PrimaryBufferImpl_Create(
280 DirectSoundDevice * device,
281 PrimaryBufferImpl **ppdsb,
282 LPCDSBUFFERDESC dsbd);
284 /*****************************************************************************
285 * IDirectSoundCapture implementation structure
287 struct IDirectSoundCaptureImpl
289 /* IUnknown fields */
290 const IDirectSoundCaptureVtbl *lpVtbl;
293 DirectSoundCaptureDevice *device;
296 HRESULT IDirectSoundCaptureImpl_Create(
297 LPDIRECTSOUNDCAPTURE8 * ppds);
299 /*****************************************************************************
300 * DirectSoundCaptureDevice implementation structure
302 struct DirectSoundCaptureDevice
304 /* IDirectSoundCaptureImpl fields */
308 /* DirectSound driver stuff */
310 DSDRIVERDESC drvdesc;
311 DSCDRIVERCAPS drvcaps;
312 PIDSCDRIVERBUFFER hwbuf;
314 /* wave driver info */
324 IDirectSoundCaptureBufferImpl* capture_buffer;
329 CRITICAL_SECTION lock;
332 HRESULT DirectSoundCaptureDevice_Create(
333 DirectSoundCaptureDevice ** ppDevice);
335 HRESULT DirectSoundCaptureDevice_Initialize(
336 DirectSoundCaptureDevice ** ppDevice,
339 ULONG DirectSoundCaptureDevice_AddRef(
340 DirectSoundCaptureDevice * device);
342 ULONG DirectSoundCaptureDevice_Release(
343 DirectSoundCaptureDevice * device);
345 /*****************************************************************************
346 * IDirectSoundCaptureBuffer implementation structure
348 struct IDirectSoundCaptureBufferImpl
350 /* IUnknown fields */
351 const IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
354 /* IDirectSoundCaptureBufferImpl fields */
355 DirectSoundCaptureDevice* device;
356 /* FIXME: don't need this */
357 LPDSCBUFFERDESC pdscbd;
360 /* IDirectSoundCaptureNotifyImpl fields */
361 IDirectSoundCaptureNotifyImpl* notify;
362 LPDSBPOSITIONNOTIFY notifies;
364 PIDSDRIVERNOTIFY hwnotify;
367 HRESULT IDirectSoundCaptureBufferImpl_Create(
368 DirectSoundCaptureDevice *device,
369 IDirectSoundCaptureBufferImpl ** ppobj,
370 LPCDSCBUFFERDESC lpcDSCBufferDesc);
372 /*****************************************************************************
373 * IDirectSoundFullDuplex implementation structure
375 struct IDirectSoundFullDuplexImpl
377 /* IUnknown fields */
378 const IDirectSoundFullDuplexVtbl *lpVtbl;
381 /* IDirectSoundFullDuplexImpl fields */
384 /*****************************************************************************
385 * IDirectSoundNotify implementation structure
387 struct IDirectSoundNotifyImpl
389 /* IUnknown fields */
390 const IDirectSoundNotifyVtbl *lpVtbl;
392 IDirectSoundBufferImpl* dsb;
395 HRESULT IDirectSoundNotifyImpl_Create(
396 IDirectSoundBufferImpl *dsb,
397 IDirectSoundNotifyImpl **pdsn);
398 HRESULT IDirectSoundNotifyImpl_Destroy(
399 IDirectSoundNotifyImpl *pdsn);
401 /*****************************************************************************
402 * IDirectSoundCaptureNotify implementation structure
404 struct IDirectSoundCaptureNotifyImpl
406 /* IUnknown fields */
407 const IDirectSoundNotifyVtbl *lpVtbl;
409 IDirectSoundCaptureBufferImpl* dscb;
412 HRESULT IDirectSoundCaptureNotifyImpl_Create(
413 IDirectSoundCaptureBufferImpl *dscb,
414 IDirectSoundCaptureNotifyImpl ** pdscn);
416 /*****************************************************************************
417 * IDirectSound3DListener implementation structure
419 struct IDirectSound3DListenerImpl
421 /* IUnknown fields */
422 const IDirectSound3DListenerVtbl *lpVtbl;
424 /* IDirectSound3DListenerImpl fields */
425 DirectSoundDevice* device;
428 HRESULT IDirectSound3DListenerImpl_Create(
429 DirectSoundDevice *device,
430 IDirectSound3DListenerImpl **pdsl);
432 /*****************************************************************************
433 * IKsBufferPropertySet implementation structure
435 struct IKsBufferPropertySetImpl
437 /* IUnknown fields */
438 const IKsPropertySetVtbl *lpVtbl;
440 /* IKsPropertySetImpl fields */
441 IDirectSoundBufferImpl* dsb;
444 HRESULT IKsBufferPropertySetImpl_Create(
445 IDirectSoundBufferImpl *dsb,
446 IKsBufferPropertySetImpl **piks);
447 HRESULT IKsBufferPropertySetImpl_Destroy(
448 IKsBufferPropertySetImpl *piks);
450 /*****************************************************************************
451 * IKsPrivatePropertySet implementation structure
453 struct IKsPrivatePropertySetImpl
455 /* IUnknown fields */
456 const IKsPropertySetVtbl *lpVtbl;
460 HRESULT IKsPrivatePropertySetImpl_Create(
461 IKsPrivatePropertySetImpl **piks);
463 /*****************************************************************************
464 * IDirectSound3DBuffer implementation structure
466 struct IDirectSound3DBufferImpl
468 /* IUnknown fields */
469 const IDirectSound3DBufferVtbl *lpVtbl;
471 /* IDirectSound3DBufferImpl fields */
472 IDirectSoundBufferImpl* dsb;
475 HRESULT IDirectSound3DBufferImpl_Create(
476 IDirectSoundBufferImpl *dsb,
477 IDirectSound3DBufferImpl **pds3db);
478 HRESULT IDirectSound3DBufferImpl_Destroy(
479 IDirectSound3DBufferImpl *pds3db);
481 /*******************************************************************************
482 * DirectSound ClassFactory implementation structure
484 struct IClassFactoryImpl
486 /* IUnknown fields */
487 const IClassFactoryVtbl *lpVtbl;
491 extern IClassFactoryImpl DSOUND_CAPTURE_CF;
492 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
494 /*******************************************************************************
499 HRESULT DSOUND_Create(LPDIRECTSOUND *ppDS, IUnknown *pUnkOuter);
500 HRESULT DSOUND_Create8(LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter);
504 HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device);
505 HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device);
506 HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
507 HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
508 HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
509 HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex);
513 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite);
517 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
518 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
519 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
520 void DSOUND_WaveQueue(DirectSoundDevice *device, DWORD mixq);
521 void DSOUND_PerformMix(DirectSoundDevice *device);
522 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
523 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
524 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
525 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
526 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
530 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
534 HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
535 LPDIRECTSOUNDCAPTURE iface,
536 LPCDSCBUFFERDESC lpcDSCBufferDesc,
537 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
539 HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(
540 LPDIRECTSOUNDCAPTURE iface,
541 LPDSCCAPS lpDSCCaps);
542 HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
543 LPDIRECTSOUNDCAPTURE iface,
546 #define STATE_STOPPED 0
547 #define STATE_STARTING 1
548 #define STATE_PLAYING 2
549 #define STATE_CAPTURING 2
550 #define STATE_STOPPING 3
552 #define DSOUND_FREQSHIFT (14)
554 extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
555 extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
557 extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];
558 extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
560 HRESULT mmErr(UINT err);
561 void setup_dsound_options(void);
562 const char * get_device_id(LPCGUID pGuid);
563 const char * dumpCooperativeLevel(DWORD level);