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 #include "dxroslayer/dxros_layer.h"
24 /* Linux does not support better timing than 10ms */
25 #define DS_TIME_RES 10 /* Resolution of multimedia timer */
26 #define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
28 #define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
29 * (changing this won't help you) */
32 #include "dxroslayer/dxros_layer.h"
33 /* direct sound hardware acceleration levels */
34 #define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
35 #define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
36 #define DS_HW_ACCEL_BASIC 2
37 #define DS_HW_ACCEL_EMULATION 3
39 extern int ds_emuldriver
;
40 extern int ds_hel_margin
;
41 extern int ds_hel_queue
;
42 extern int ds_snd_queue_max
;
43 extern int ds_snd_queue_min
;
44 extern int ds_hw_accel
;
45 extern int ds_default_playback
;
46 extern int ds_default_capture
;
48 /*****************************************************************************
49 * Predeclare the interface implementation structures
51 typedef struct IDirectSoundImpl IDirectSoundImpl
;
52 typedef struct IDirectSound_IUnknown IDirectSound_IUnknown
;
53 typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound
;
54 typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown
;
55 typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound
;
56 typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8
;
57 typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl
;
58 typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl
;
59 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl
;
60 typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl
;
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
79 const IDirectSound8Vtbl
*lpVtbl
;
82 DirectSoundDevice
*device
;
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 WINAPI
IDirectSoundImpl_Create(
130 LPDIRECTSOUND8
* ppds
);
132 HRESULT WINAPI
DSOUND_Create(
134 IUnknown
*pUnkOuter
);
136 HRESULT WINAPI
DSOUND_Create8(
137 LPDIRECTSOUND8
*ppDS
,
138 IUnknown
*pUnkOuter
);
140 /*****************************************************************************
141 * IDirectSound COM components
143 struct IDirectSound_IUnknown
{
144 const IUnknownVtbl
*lpVtbl
;
149 HRESULT WINAPI
IDirectSound_IUnknown_Create(
153 struct IDirectSound_IDirectSound
{
154 const IDirectSoundVtbl
*lpVtbl
;
159 HRESULT WINAPI
IDirectSound_IDirectSound_Create(
161 LPDIRECTSOUND
* ppds
);
163 /*****************************************************************************
164 * IDirectSound8 COM components
166 struct IDirectSound8_IUnknown
{
167 const IUnknownVtbl
*lpVtbl
;
172 HRESULT WINAPI
IDirectSound8_IUnknown_Create(
176 struct IDirectSound8_IDirectSound
{
177 const IDirectSoundVtbl
*lpVtbl
;
182 HRESULT WINAPI
IDirectSound8_IDirectSound_Create(
184 LPDIRECTSOUND
* ppds
);
186 struct IDirectSound8_IDirectSound8
{
187 const IDirectSound8Vtbl
*lpVtbl
;
192 HRESULT WINAPI
IDirectSound8_IDirectSound8_Create(
194 LPDIRECTSOUND8
* ppds
);
196 /*****************************************************************************
197 * IDirectSoundBuffer implementation structure
199 struct IDirectSoundBufferImpl
201 /* FIXME: document */
202 /* IUnknown fields */
203 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
205 /* IDirectSoundBufferImpl fields */
206 SecondaryBufferImpl
* dsb
;
207 IDirectSoundImpl
* dsound
;
208 CRITICAL_SECTION lock
;
209 PIDSDRIVERBUFFER hwbuf
;
211 BufferMemory
* buffer
;
212 DWORD playflags
,state
,leadin
;
213 DWORD playpos
,startpos
,writelead
,buflen
;
214 DWORD nAvgBytesPerSec
;
216 DSVOLUMEPAN volpan
, cvolpan
;
218 /* used for frequency conversion (PerfectPitch) */
219 ULONG freqAdjust
, freqAcc
;
220 /* used for intelligent (well, sort of) prebuffering */
221 DWORD probably_valid_to
, last_playpos
;
222 DWORD primary_mixpos
, buf_mixpos
;
225 /* IDirectSoundNotifyImpl fields */
226 IDirectSoundNotifyImpl
* notify
;
227 LPDSBPOSITIONNOTIFY notifies
;
229 PIDSDRIVERNOTIFY hwnotify
;
231 /* DirectSound3DBuffer fields */
232 IDirectSound3DBufferImpl
* ds3db
;
233 DS3DBUFFER ds3db_ds3db
;
235 BOOL ds3db_need_recalc
;
237 /* IKsPropertySet fields */
238 IKsBufferPropertySetImpl
* iks
;
241 HRESULT WINAPI
IDirectSoundBufferImpl_Create(
242 IDirectSoundImpl
*ds
,
243 IDirectSoundBufferImpl
**pdsb
,
244 LPCDSBUFFERDESC dsbd
);
245 HRESULT WINAPI
IDirectSoundBufferImpl_Destroy(
246 IDirectSoundBufferImpl
*pdsb
);
248 /*****************************************************************************
249 * SecondaryBuffer implementation structure
251 struct SecondaryBufferImpl
253 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
255 IDirectSoundBufferImpl
* dsb
;
258 HRESULT WINAPI
SecondaryBufferImpl_Create(
259 IDirectSoundBufferImpl
*dsb
,
260 SecondaryBufferImpl
**pdsb
);
261 HRESULT WINAPI
SecondaryBufferImpl_Destroy(
262 SecondaryBufferImpl
*pdsb
);
264 /*****************************************************************************
265 * PrimaryBuffer implementation structure
267 struct PrimaryBufferImpl
269 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
271 IDirectSoundImpl
* dsound
;
274 HRESULT WINAPI
PrimaryBufferImpl_Create(
275 IDirectSoundImpl
*ds
,
276 PrimaryBufferImpl
**pdsb
,
277 LPCDSBUFFERDESC dsbd
);
279 /*****************************************************************************
280 * IDirectSoundCapture implementation structure
282 struct IDirectSoundCaptureImpl
284 /* IUnknown fields */
285 const IDirectSoundCaptureVtbl
*lpVtbl
;
288 DirectSoundCaptureDevice
*device
;
291 struct DirectSoundCaptureDevice
293 /* IDirectSoundCaptureImpl fields */
297 /* DirectSound driver stuff */
299 DSDRIVERDESC drvdesc
;
300 DSCDRIVERCAPS drvcaps
;
301 PIDSCDRIVERBUFFER hwbuf
;
303 /* wave driver info */
313 IDirectSoundCaptureBufferImpl
* capture_buffer
;
318 CRITICAL_SECTION lock
;
321 HRESULT WINAPI
IDirectSoundCaptureImpl_Create(
322 LPDIRECTSOUNDCAPTURE8
* ppds
);
324 HRESULT WINAPI
DSOUND_CaptureCreate(
325 LPDIRECTSOUNDCAPTURE
*ppDSC
,
326 IUnknown
*pUnkOuter
);
328 HRESULT WINAPI
DSOUND_CaptureCreate8(
329 LPDIRECTSOUNDCAPTURE8
*ppDSC8
,
330 IUnknown
*pUnkOuter
);
332 /*****************************************************************************
333 * IDirectSoundCaptureBuffer implementation structure
335 struct IDirectSoundCaptureBufferImpl
337 /* IUnknown fields */
338 const IDirectSoundCaptureBuffer8Vtbl
*lpVtbl
;
341 /* IDirectSoundCaptureBufferImpl fields */
342 IDirectSoundCaptureImpl
* dsound
;
343 /* FIXME: don't need this */
344 LPDSCBUFFERDESC pdscbd
;
347 /* IDirectSoundCaptureNotifyImpl fields */
348 IDirectSoundCaptureNotifyImpl
* notify
;
349 LPDSBPOSITIONNOTIFY notifies
;
351 PIDSDRIVERNOTIFY hwnotify
;
354 /*****************************************************************************
355 * IDirectSoundFullDuplex implementation structure
357 struct IDirectSoundFullDuplexImpl
359 /* IUnknown fields */
360 const IDirectSoundFullDuplexVtbl
*lpVtbl
;
363 /* IDirectSoundFullDuplexImpl fields */
364 CRITICAL_SECTION lock
;
367 /*****************************************************************************
368 * IDirectSoundNotify implementation structure
370 struct IDirectSoundNotifyImpl
372 /* IUnknown fields */
373 const IDirectSoundNotifyVtbl
*lpVtbl
;
375 IDirectSoundBufferImpl
* dsb
;
378 HRESULT WINAPI
IDirectSoundNotifyImpl_Create(
379 IDirectSoundBufferImpl
*dsb
,
380 IDirectSoundNotifyImpl
**pdsn
);
381 HRESULT WINAPI
IDirectSoundNotifyImpl_Destroy(
382 IDirectSoundNotifyImpl
*pdsn
);
384 /*****************************************************************************
385 * IDirectSoundCaptureNotify implementation structure
387 struct IDirectSoundCaptureNotifyImpl
389 /* IUnknown fields */
390 const IDirectSoundNotifyVtbl
*lpVtbl
;
392 IDirectSoundCaptureBufferImpl
* dscb
;
395 HRESULT WINAPI
IDirectSoundCaptureNotifyImpl_Create(
396 IDirectSoundCaptureBufferImpl
*dscb
,
397 IDirectSoundCaptureNotifyImpl
** pdscn
);
399 /*****************************************************************************
400 * IDirectSound3DListener implementation structure
402 struct IDirectSound3DListenerImpl
404 /* IUnknown fields */
405 const IDirectSound3DListenerVtbl
*lpVtbl
;
407 /* IDirectSound3DListenerImpl fields */
408 IDirectSoundImpl
* dsound
;
411 HRESULT WINAPI
IDirectSound3DListenerImpl_Create(
412 PrimaryBufferImpl
*pb
,
413 IDirectSound3DListenerImpl
**pdsl
);
415 /*****************************************************************************
416 * IKsBufferPropertySet implementation structure
418 struct IKsBufferPropertySetImpl
420 /* IUnknown fields */
421 const IKsPropertySetVtbl
*lpVtbl
;
423 /* IKsPropertySetImpl fields */
424 IDirectSoundBufferImpl
* dsb
;
427 HRESULT WINAPI
IKsBufferPropertySetImpl_Create(
428 IDirectSoundBufferImpl
*dsb
,
429 IKsBufferPropertySetImpl
**piks
);
430 HRESULT WINAPI
IKsBufferPropertySetImpl_Destroy(
431 IKsBufferPropertySetImpl
*piks
);
433 /*****************************************************************************
434 * IKsPrivatePropertySet implementation structure
436 struct IKsPrivatePropertySetImpl
438 /* IUnknown fields */
439 const IKsPropertySetVtbl
*lpVtbl
;
443 HRESULT WINAPI
IKsPrivatePropertySetImpl_Create(
444 IKsPrivatePropertySetImpl
**piks
);
446 /*****************************************************************************
447 * IDirectSound3DBuffer implementation structure
449 struct IDirectSound3DBufferImpl
451 /* IUnknown fields */
452 const IDirectSound3DBufferVtbl
*lpVtbl
;
454 /* IDirectSound3DBufferImpl fields */
455 IDirectSoundBufferImpl
* dsb
;
458 HRESULT WINAPI
IDirectSound3DBufferImpl_Create(
459 IDirectSoundBufferImpl
*dsb
,
460 IDirectSound3DBufferImpl
**pds3db
);
461 HRESULT WINAPI
IDirectSound3DBufferImpl_Destroy(
462 IDirectSound3DBufferImpl
*pds3db
);
464 /*******************************************************************************
465 * DirectSound ClassFactory implementation structure
467 struct IClassFactoryImpl
469 /* IUnknown fields */
470 const IClassFactoryVtbl
*lpVtbl
;
474 extern IClassFactoryImpl DSOUND_CAPTURE_CF
;
475 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF
;
477 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan
);
478 void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan
);
479 void DSOUND_RecalcFormat(IDirectSoundBufferImpl
*dsb
);
483 HRESULT
DSOUND_AddBuffer(IDirectSoundImpl
* pDS
, IDirectSoundBufferImpl
* pDSB
);
484 HRESULT
DSOUND_RemoveBuffer(IDirectSoundImpl
* pDS
, IDirectSoundBufferImpl
* pDSB
);
488 HRESULT
DSOUND_PrimaryCreate(DirectSoundDevice
*device
);
489 HRESULT
DSOUND_PrimaryDestroy(DirectSoundDevice
*device
);
490 HRESULT
DSOUND_PrimaryPlay(DirectSoundDevice
*device
);
491 HRESULT
DSOUND_PrimaryStop(DirectSoundDevice
*device
);
492 HRESULT
DSOUND_PrimaryGetPosition(DirectSoundDevice
*device
, LPDWORD playpos
, LPDWORD writepos
);
496 DWORD
DSOUND_CalcPlayPosition(IDirectSoundBufferImpl
*This
, DWORD pplay
, DWORD pwrite
);
500 void DSOUND_CheckEvent(IDirectSoundBufferImpl
*dsb
, int len
);
501 void DSOUND_ForceRemix(IDirectSoundBufferImpl
*dsb
);
502 void DSOUND_MixCancelAt(IDirectSoundBufferImpl
*dsb
, DWORD buf_writepos
);
503 void DSOUND_WaveQueue(DirectSoundDevice
*device
, DWORD mixq
);
504 void DSOUND_PerformMix(DirectSoundDevice
*device
);
505 void CALLBACK
DSOUND_timer(UINT timerID
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
506 void CALLBACK
DSOUND_callback(HWAVEOUT hwo
, UINT msg
, DWORD dwUser
, DWORD dw1
, DWORD dw2
);
510 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl
*dsb
);
512 #define STATE_STOPPED 0
513 #define STATE_STARTING 1
514 #define STATE_PLAYING 2
515 #define STATE_CAPTURING 2
516 #define STATE_STOPPING 3
518 #define DSOUND_FREQSHIFT (14)
520 extern DirectSoundDevice
* DSOUND_renderer
[MAXWAVEDRIVERS
];
521 extern GUID DSOUND_renderer_guids
[MAXWAVEDRIVERS
];
523 extern DirectSoundCaptureDevice
* DSOUND_capture
[MAXWAVEDRIVERS
];
524 extern GUID DSOUND_capture_guids
[MAXWAVEDRIVERS
];
526 extern HRESULT
mmErr(UINT err
);
527 extern void setup_dsound_options(void);
528 extern const char * get_device_id(LPCGUID pGuid
);