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 IDirectSoundFullDuplex_IUnknown IDirectSoundFullDuplex_IUnknown;
58 typedef struct IDirectSoundFullDuplex_IDirectSound IDirectSoundFullDuplex_IDirectSound;
59 typedef struct IDirectSoundFullDuplex_IDirectSound8 IDirectSoundFullDuplex_IDirectSound8;
60 typedef struct IDirectSoundFullDuplex_IDirectSoundCapture IDirectSoundFullDuplex_IDirectSoundCapture;
61 typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
62 typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
63 typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
64 typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
65 typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
66 typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
67 typedef struct PrimaryBufferImpl PrimaryBufferImpl;
68 typedef struct SecondaryBufferImpl SecondaryBufferImpl;
69 typedef struct IClassFactoryImpl IClassFactoryImpl;
70 typedef struct DirectSoundDevice DirectSoundDevice;
71 typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
73 /*****************************************************************************
74 * IDirectSound implementation structure
76 struct IDirectSoundImpl
80 DirectSoundDevice *device;
86 HRESULT IDirectSoundImpl_Create(
87 LPDIRECTSOUND8 * ppds);
89 /*****************************************************************************
90 * IDirectSoundDevice implementation structure
92 struct DirectSoundDevice
103 LPWAVEHDR pwave[DS_HEL_FRAGS];
104 UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
106 PIDSDRIVERBUFFER hwbuf;
108 DWORD writelead, buflen, state, playpos, mixpos;
111 IDirectSoundBufferImpl** buffers;
112 RTL_RWLOCK buffer_list_lock;
113 CRITICAL_SECTION mixlock;
114 PrimaryBufferImpl* primary;
116 DWORD speaker_config;
118 DWORD tmp_buffer_len;
120 /* DirectSound3DListener fields */
121 IDirectSound3DListenerImpl* listener;
123 BOOL ds3dl_need_recalc;
126 /* reference counted buffer memory for duplicated buffer memory */
127 typedef struct BufferMemory
133 HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice);
134 ULONG DirectSoundDevice_AddRef(DirectSoundDevice * device);
135 ULONG DirectSoundDevice_Release(DirectSoundDevice * device);
136 HRESULT DirectSoundDevice_Initialize(
137 DirectSoundDevice ** ppDevice,
139 HRESULT DirectSoundDevice_AddBuffer(
140 DirectSoundDevice * device,
141 IDirectSoundBufferImpl * pDSB);
142 HRESULT DirectSoundDevice_RemoveBuffer(
143 DirectSoundDevice * device,
144 IDirectSoundBufferImpl * pDSB);
145 HRESULT DirectSoundDevice_GetCaps(DirectSoundDevice * device, LPDSCAPS lpDSCaps);
146 HRESULT DirectSoundDevice_CreateSoundBuffer(
147 DirectSoundDevice * device,
148 LPCDSBUFFERDESC dsbd,
149 LPLPDIRECTSOUNDBUFFER ppdsb,
152 HRESULT DirectSoundDevice_DuplicateSoundBuffer(
153 DirectSoundDevice * device,
154 LPDIRECTSOUNDBUFFER psb,
155 LPLPDIRECTSOUNDBUFFER ppdsb);
156 HRESULT DirectSoundDevice_SetCooperativeLevel(
157 DirectSoundDevice * devcie,
160 HRESULT DirectSoundDevice_Compact(DirectSoundDevice * device);
161 HRESULT DirectSoundDevice_GetSpeakerConfig(
162 DirectSoundDevice * device,
163 LPDWORD lpdwSpeakerConfig);
164 HRESULT DirectSoundDevice_SetSpeakerConfig(
165 DirectSoundDevice * device,
167 HRESULT DirectSoundDevice_VerifyCertification(
168 DirectSoundDevice * device,
169 LPDWORD pdwCertified);
171 /*****************************************************************************
172 * IDirectSound COM components
174 struct IDirectSound_IUnknown {
175 const IUnknownVtbl *lpVtbl;
180 HRESULT IDirectSound_IUnknown_Create(
184 struct IDirectSound_IDirectSound {
185 const IDirectSoundVtbl *lpVtbl;
190 HRESULT IDirectSound_IDirectSound_Create(
192 LPDIRECTSOUND * ppds);
194 /*****************************************************************************
195 * IDirectSound8 COM components
197 struct IDirectSound8_IUnknown {
198 const IUnknownVtbl *lpVtbl;
203 HRESULT IDirectSound8_IUnknown_Create(
207 struct IDirectSound8_IDirectSound {
208 const IDirectSoundVtbl *lpVtbl;
213 HRESULT IDirectSound8_IDirectSound_Create(
215 LPDIRECTSOUND * ppds);
217 struct IDirectSound8_IDirectSound8 {
218 const IDirectSound8Vtbl *lpVtbl;
223 HRESULT IDirectSound8_IDirectSound8_Create(
225 LPDIRECTSOUND8 * ppds);
227 /*****************************************************************************
228 * IDirectSoundBuffer implementation structure
230 struct IDirectSoundBufferImpl
232 /* FIXME: document */
233 /* IUnknown fields */
234 const IDirectSoundBuffer8Vtbl *lpVtbl;
236 /* IDirectSoundBufferImpl fields */
237 SecondaryBufferImpl* secondary;
238 DirectSoundDevice* device;
239 CRITICAL_SECTION lock;
240 PIDSDRIVERBUFFER hwbuf;
242 BufferMemory* buffer;
243 DWORD playflags,state,leadin;
244 DWORD playpos,startpos,writelead,buflen;
245 DWORD nAvgBytesPerSec;
247 DSVOLUMEPAN volpan, cvolpan;
249 /* used for frequency conversion (PerfectPitch) */
250 ULONG freqAdjust, freqAcc;
251 /* used for intelligent (well, sort of) prebuffering */
252 DWORD probably_valid_to, last_playpos;
253 DWORD primary_mixpos, buf_mixpos;
256 /* IDirectSoundNotifyImpl fields */
257 IDirectSoundNotifyImpl* notify;
258 LPDSBPOSITIONNOTIFY notifies;
260 PIDSDRIVERNOTIFY hwnotify;
262 /* DirectSound3DBuffer fields */
263 IDirectSound3DBufferImpl* ds3db;
264 DS3DBUFFER ds3db_ds3db;
266 BOOL ds3db_need_recalc;
268 /* IKsPropertySet fields */
269 IKsBufferPropertySetImpl* iks;
272 HRESULT IDirectSoundBufferImpl_Create(
273 DirectSoundDevice *device,
274 IDirectSoundBufferImpl **ppdsb,
275 LPCDSBUFFERDESC dsbd);
276 HRESULT IDirectSoundBufferImpl_Destroy(
277 IDirectSoundBufferImpl *pdsb);
278 HRESULT IDirectSoundBufferImpl_Duplicate(
279 DirectSoundDevice *device,
280 IDirectSoundBufferImpl **ppdsb,
281 IDirectSoundBufferImpl *pdsb);
283 /*****************************************************************************
284 * SecondaryBuffer implementation structure
286 struct SecondaryBufferImpl
288 const IDirectSoundBuffer8Vtbl *lpVtbl;
290 IDirectSoundBufferImpl* dsb;
293 HRESULT SecondaryBufferImpl_Create(
294 IDirectSoundBufferImpl *dsb,
295 SecondaryBufferImpl **pdsb);
296 HRESULT SecondaryBufferImpl_Destroy(
297 SecondaryBufferImpl *pdsb);
299 /*****************************************************************************
300 * PrimaryBuffer implementation structure
302 struct PrimaryBufferImpl
304 const IDirectSoundBuffer8Vtbl *lpVtbl;
306 DirectSoundDevice* device;
309 HRESULT PrimaryBufferImpl_Create(
310 DirectSoundDevice * device,
311 PrimaryBufferImpl **ppdsb,
312 LPCDSBUFFERDESC dsbd);
314 /*****************************************************************************
315 * IDirectSoundCapture implementation structure
317 struct IDirectSoundCaptureImpl
319 /* IUnknown fields */
320 const IDirectSoundCaptureVtbl *lpVtbl;
323 DirectSoundCaptureDevice *device;
326 HRESULT IDirectSoundCaptureImpl_Create(
327 LPDIRECTSOUNDCAPTURE8 * ppds);
329 /*****************************************************************************
330 * DirectSoundCaptureDevice implementation structure
332 struct DirectSoundCaptureDevice
334 /* IDirectSoundCaptureImpl fields */
338 /* DirectSound driver stuff */
340 DSDRIVERDESC drvdesc;
341 DSCDRIVERCAPS drvcaps;
342 PIDSCDRIVERBUFFER hwbuf;
344 /* wave driver info */
354 IDirectSoundCaptureBufferImpl* capture_buffer;
359 CRITICAL_SECTION lock;
362 HRESULT DirectSoundCaptureDevice_Create(
363 DirectSoundCaptureDevice ** ppDevice);
364 HRESULT DirectSoundCaptureDevice_Initialize(
365 DirectSoundCaptureDevice ** ppDevice,
367 ULONG DirectSoundCaptureDevice_AddRef(
368 DirectSoundCaptureDevice * device);
369 ULONG DirectSoundCaptureDevice_Release(
370 DirectSoundCaptureDevice * device);
372 /*****************************************************************************
373 * IDirectSoundCaptureBuffer implementation structure
375 struct IDirectSoundCaptureBufferImpl
377 /* IUnknown fields */
378 const IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
381 /* IDirectSoundCaptureBufferImpl fields */
382 DirectSoundCaptureDevice* device;
383 /* FIXME: don't need this */
384 LPDSCBUFFERDESC pdscbd;
387 /* IDirectSoundCaptureNotifyImpl fields */
388 IDirectSoundCaptureNotifyImpl* notify;
389 LPDSBPOSITIONNOTIFY notifies;
391 PIDSDRIVERNOTIFY hwnotify;
394 HRESULT IDirectSoundCaptureBufferImpl_Create(
395 DirectSoundCaptureDevice *device,
396 IDirectSoundCaptureBufferImpl ** ppobj,
397 LPCDSCBUFFERDESC lpcDSCBufferDesc);
399 /*****************************************************************************
400 * IDirectSoundFullDuplex implementation structure
402 struct IDirectSoundFullDuplexImpl
404 /* IUnknown fields */
405 const IDirectSoundFullDuplexVtbl *lpVtbl;
408 /* IDirectSoundFullDuplexImpl fields */
409 DirectSoundDevice *renderer_device;
410 DirectSoundCaptureDevice *capture_device;
415 LPDIRECTSOUNDCAPTURE pDSC;
418 /*****************************************************************************
419 * IDirectSoundFullDuplex COM components
421 struct IDirectSoundFullDuplex_IUnknown {
422 const IUnknownVtbl *lpVtbl;
424 IDirectSoundFullDuplexImpl *pdsfd;
427 HRESULT IDirectSoundFullDuplex_IUnknown_Create(
428 LPDIRECTSOUNDFULLDUPLEX pdsfd,
431 struct IDirectSoundFullDuplex_IDirectSound {
432 const IDirectSoundVtbl *lpVtbl;
434 IDirectSoundFullDuplexImpl *pdsfd;
437 HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
438 LPDIRECTSOUNDFULLDUPLEX pdsfd,
439 LPDIRECTSOUND * ppds);
441 struct IDirectSoundFullDuplex_IDirectSound8 {
442 const IDirectSound8Vtbl *lpVtbl;
444 IDirectSoundFullDuplexImpl *pdsfd;
447 HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
448 LPDIRECTSOUNDFULLDUPLEX pdsfd,
449 LPDIRECTSOUND8 * ppds8);
451 struct IDirectSoundFullDuplex_IDirectSoundCapture {
452 const IDirectSoundCaptureVtbl *lpVtbl;
454 IDirectSoundFullDuplexImpl *pdsfd;
457 HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
458 LPDIRECTSOUNDFULLDUPLEX pdsfd,
459 LPDIRECTSOUNDCAPTURE8 * ppdsc8);
461 /*****************************************************************************
462 * IDirectSoundNotify implementation structure
464 struct IDirectSoundNotifyImpl
466 /* IUnknown fields */
467 const IDirectSoundNotifyVtbl *lpVtbl;
469 IDirectSoundBufferImpl* dsb;
472 HRESULT IDirectSoundNotifyImpl_Create(
473 IDirectSoundBufferImpl *dsb,
474 IDirectSoundNotifyImpl **pdsn);
475 HRESULT IDirectSoundNotifyImpl_Destroy(
476 IDirectSoundNotifyImpl *pdsn);
478 /*****************************************************************************
479 * IDirectSoundCaptureNotify implementation structure
481 struct IDirectSoundCaptureNotifyImpl
483 /* IUnknown fields */
484 const IDirectSoundNotifyVtbl *lpVtbl;
486 IDirectSoundCaptureBufferImpl* dscb;
489 HRESULT IDirectSoundCaptureNotifyImpl_Create(
490 IDirectSoundCaptureBufferImpl *dscb,
491 IDirectSoundCaptureNotifyImpl ** pdscn);
493 /*****************************************************************************
494 * IDirectSound3DListener implementation structure
496 struct IDirectSound3DListenerImpl
498 /* IUnknown fields */
499 const IDirectSound3DListenerVtbl *lpVtbl;
501 /* IDirectSound3DListenerImpl fields */
502 DirectSoundDevice* device;
505 HRESULT IDirectSound3DListenerImpl_Create(
506 DirectSoundDevice *device,
507 IDirectSound3DListenerImpl **pdsl);
509 /*****************************************************************************
510 * IKsBufferPropertySet implementation structure
512 struct IKsBufferPropertySetImpl
514 /* IUnknown fields */
515 const IKsPropertySetVtbl *lpVtbl;
517 /* IKsPropertySetImpl fields */
518 IDirectSoundBufferImpl* dsb;
521 HRESULT IKsBufferPropertySetImpl_Create(
522 IDirectSoundBufferImpl *dsb,
523 IKsBufferPropertySetImpl **piks);
524 HRESULT IKsBufferPropertySetImpl_Destroy(
525 IKsBufferPropertySetImpl *piks);
527 /*****************************************************************************
528 * IKsPrivatePropertySet implementation structure
530 struct IKsPrivatePropertySetImpl
532 /* IUnknown fields */
533 const IKsPropertySetVtbl *lpVtbl;
537 HRESULT IKsPrivatePropertySetImpl_Create(
538 IKsPrivatePropertySetImpl **piks);
540 /*****************************************************************************
541 * IDirectSound3DBuffer implementation structure
543 struct IDirectSound3DBufferImpl
545 /* IUnknown fields */
546 const IDirectSound3DBufferVtbl *lpVtbl;
548 /* IDirectSound3DBufferImpl fields */
549 IDirectSoundBufferImpl* dsb;
552 HRESULT IDirectSound3DBufferImpl_Create(
553 IDirectSoundBufferImpl *dsb,
554 IDirectSound3DBufferImpl **pds3db);
555 HRESULT IDirectSound3DBufferImpl_Destroy(
556 IDirectSound3DBufferImpl *pds3db);
558 /*******************************************************************************
559 * DirectSound ClassFactory implementation structure
561 struct IClassFactoryImpl
563 /* IUnknown fields */
564 const IClassFactoryVtbl *lpVtbl;
568 extern IClassFactoryImpl DSOUND_CAPTURE_CF;
569 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
571 /*******************************************************************************
576 HRESULT DSOUND_Create(LPDIRECTSOUND *ppDS, IUnknown *pUnkOuter);
577 HRESULT DSOUND_Create8(LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter);
581 HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device);
582 HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device);
583 HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
584 HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
585 HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
586 HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex);
590 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite);
594 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
595 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
596 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
597 void DSOUND_WaveQueue(DirectSoundDevice *device, DWORD mixq);
598 void DSOUND_PerformMix(DirectSoundDevice *device);
599 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
600 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
601 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
602 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
603 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
607 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
611 HRESULT DSOUND_FullDuplexCreate(LPDIRECTSOUNDFULLDUPLEX* ppDSFD, IUnknown *pUnkOuter);
615 HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
616 LPDIRECTSOUNDCAPTURE iface,
617 LPCDSCBUFFERDESC lpcDSCBufferDesc,
618 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
620 HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(
621 LPDIRECTSOUNDCAPTURE iface,
622 LPDSCCAPS lpDSCCaps);
623 HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
624 LPDIRECTSOUNDCAPTURE iface,
627 #define STATE_STOPPED 0
628 #define STATE_STARTING 1
629 #define STATE_PLAYING 2
630 #define STATE_CAPTURING 2
631 #define STATE_STOPPING 3
633 #define DSOUND_FREQSHIFT (14)
635 extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
636 extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
638 extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];
639 extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
641 HRESULT mmErr(UINT err);
642 void setup_dsound_options(void);
643 const char * get_device_id(LPCGUID pGuid);
644 const char * dumpCooperativeLevel(DWORD level);