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;
67 /*****************************************************************************
68 * IDirectSound implementation structure
70 struct IDirectSoundImpl
73 ICOM_VFIELD(IDirectSound8);
75 /* IDirectSoundImpl fields */
81 WAVEFORMATEX wfx; /* current main waveformat */
83 LPWAVEHDR pwave[DS_HEL_FRAGS];
84 UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
86 PIDSDRIVERBUFFER hwbuf;
88 DWORD writelead, buflen, state, playpos, mixpos;
91 IDirectSoundBufferImpl** buffers;
93 CRITICAL_SECTION mixlock;
95 PrimaryBufferImpl* primary;
99 /* DirectSound3DListener fields */
100 IDirectSound3DListenerImpl* listener;
102 BOOL ds3dl_need_recalc;
109 /* reference counted buffer memory for duplicated buffer memory */
110 typedef struct BufferMemory
116 HRESULT WINAPI IDirectSoundImpl_Create(
118 LPDIRECTSOUND8 * ppds);
120 /*****************************************************************************
121 * IDirectSound COM components
123 struct IDirectSound_IUnknown {
124 ICOM_VFIELD(IUnknown);
129 HRESULT WINAPI IDirectSound_IUnknown_Create(
133 struct IDirectSound_IDirectSound {
134 ICOM_VFIELD(IDirectSound);
139 HRESULT WINAPI IDirectSound_IDirectSound_Create(
141 LPDIRECTSOUND * ppds);
143 /*****************************************************************************
144 * IDirectSound8 COM components
146 struct IDirectSound8_IUnknown {
147 ICOM_VFIELD(IUnknown);
152 HRESULT WINAPI IDirectSound8_IUnknown_Create(
156 struct IDirectSound8_IDirectSound {
157 ICOM_VFIELD(IDirectSound);
162 HRESULT WINAPI IDirectSound8_IDirectSound_Create(
164 LPDIRECTSOUND * ppds);
166 struct IDirectSound8_IDirectSound8 {
167 ICOM_VFIELD(IDirectSound8);
172 HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
174 LPDIRECTSOUND8 * ppds);
176 /*****************************************************************************
177 * IDirectSoundBuffer implementation structure
179 struct IDirectSoundBufferImpl
181 /* FIXME: document */
182 /* IUnknown fields */
183 ICOM_VFIELD(IDirectSoundBuffer8);
185 /* IDirectSoundBufferImpl fields */
186 SecondaryBufferImpl* dsb;
187 IDirectSoundImpl* dsound;
188 CRITICAL_SECTION lock;
189 PIDSDRIVERBUFFER hwbuf;
191 BufferMemory* buffer;
192 DWORD playflags,state,leadin;
193 DWORD playpos,startpos,writelead,buflen;
194 DWORD nAvgBytesPerSec;
196 DSVOLUMEPAN volpan, cvolpan;
198 /* used for frequency conversion (PerfectPitch) */
199 ULONG freqAdjust, freqAcc;
200 /* used for intelligent (well, sort of) prebuffering */
201 DWORD probably_valid_to, last_playpos;
202 DWORD primary_mixpos, buf_mixpos;
205 /* IDirectSoundNotifyImpl fields */
206 IDirectSoundNotifyImpl* notify;
207 LPDSBPOSITIONNOTIFY notifies;
209 PIDSDRIVERNOTIFY hwnotify;
211 /* DirectSound3DBuffer fields */
212 IDirectSound3DBufferImpl* ds3db;
213 DS3DBUFFER ds3db_ds3db;
215 BOOL ds3db_need_recalc;
217 /* IKsPropertySet fields */
218 IKsBufferPropertySetImpl* iks;
221 HRESULT WINAPI IDirectSoundBufferImpl_Create(
222 IDirectSoundImpl *ds,
223 IDirectSoundBufferImpl **pdsb,
224 LPCDSBUFFERDESC dsbd);
225 HRESULT WINAPI IDirectSoundBufferImpl_Destroy(
226 IDirectSoundBufferImpl *pdsb);
228 /*****************************************************************************
229 * SecondaryBuffer implementation structure
231 struct SecondaryBufferImpl
233 ICOM_VFIELD(IDirectSoundBuffer8);
235 IDirectSoundBufferImpl* dsb;
238 HRESULT WINAPI SecondaryBufferImpl_Create(
239 IDirectSoundBufferImpl *dsb,
240 SecondaryBufferImpl **pdsb);
241 HRESULT WINAPI SecondaryBufferImpl_Destroy(
242 SecondaryBufferImpl *pdsb);
244 /*****************************************************************************
245 * PrimaryBuffer implementation structure
247 struct PrimaryBufferImpl
249 ICOM_VFIELD(IDirectSoundBuffer8);
251 IDirectSoundImpl* dsound;
254 HRESULT WINAPI PrimaryBufferImpl_Create(
255 IDirectSoundImpl *ds,
256 PrimaryBufferImpl **pdsb,
257 LPCDSBUFFERDESC dsbd);
259 /*****************************************************************************
260 * IDirectSoundCapture implementation structure
262 struct IDirectSoundCaptureImpl
264 /* IUnknown fields */
265 ICOM_VFIELD(IDirectSoundCapture);
268 /* IDirectSoundCaptureImpl fields */
272 /* DirectSound driver stuff */
274 DSDRIVERDESC drvdesc;
275 DSCDRIVERCAPS drvcaps;
276 PIDSCDRIVERBUFFER hwbuf;
278 /* wave driver info */
288 IDirectSoundCaptureBufferImpl* capture_buffer;
293 CRITICAL_SECTION lock;
296 /*****************************************************************************
297 * IDirectSoundCaptureBuffer implementation structure
299 struct IDirectSoundCaptureBufferImpl
301 /* IUnknown fields */
302 ICOM_VFIELD(IDirectSoundCaptureBuffer8);
305 /* IDirectSoundCaptureBufferImpl fields */
306 IDirectSoundCaptureImpl* dsound;
307 /* FIXME: don't need this */
308 LPDSCBUFFERDESC pdscbd;
311 /* IDirectSoundCaptureNotifyImpl fields */
312 IDirectSoundCaptureNotifyImpl* notify;
313 LPDSBPOSITIONNOTIFY notifies;
315 PIDSDRIVERNOTIFY hwnotify;
318 /*****************************************************************************
319 * IDirectSoundFullDuplex implementation structure
321 struct IDirectSoundFullDuplexImpl
323 /* IUnknown fields */
324 ICOM_VFIELD(IDirectSoundFullDuplex);
327 /* IDirectSoundFullDuplexImpl fields */
328 CRITICAL_SECTION lock;
331 /*****************************************************************************
332 * IDirectSoundNotify implementation structure
334 struct IDirectSoundNotifyImpl
336 /* IUnknown fields */
337 ICOM_VFIELD(IDirectSoundNotify);
339 IDirectSoundBufferImpl* dsb;
342 HRESULT WINAPI IDirectSoundNotifyImpl_Create(
343 IDirectSoundBufferImpl *dsb,
344 IDirectSoundNotifyImpl **pdsn);
345 HRESULT WINAPI IDirectSoundNotifyImpl_Destroy(
346 IDirectSoundNotifyImpl *pdsn);
348 /*****************************************************************************
349 * IDirectSoundCaptureNotify implementation structure
351 struct IDirectSoundCaptureNotifyImpl
353 /* IUnknown fields */
354 ICOM_VFIELD(IDirectSoundNotify);
356 IDirectSoundCaptureBufferImpl* dscb;
359 HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
360 IDirectSoundCaptureBufferImpl *dscb,
361 IDirectSoundCaptureNotifyImpl ** pdscn);
363 /*****************************************************************************
364 * IDirectSound3DListener implementation structure
366 struct IDirectSound3DListenerImpl
368 /* IUnknown fields */
369 ICOM_VFIELD(IDirectSound3DListener);
371 /* IDirectSound3DListenerImpl fields */
372 IDirectSoundImpl* dsound;
375 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
376 PrimaryBufferImpl *pb,
377 IDirectSound3DListenerImpl **pdsl);
379 /*****************************************************************************
380 * IKsBufferPropertySet implementation structure
382 struct IKsBufferPropertySetImpl
384 /* IUnknown fields */
385 ICOM_VFIELD(IKsPropertySet);
387 /* IKsPropertySetImpl fields */
388 IDirectSoundBufferImpl* dsb;
391 HRESULT WINAPI IKsBufferPropertySetImpl_Create(
392 IDirectSoundBufferImpl *dsb,
393 IKsBufferPropertySetImpl **piks);
394 HRESULT WINAPI IKsBufferPropertySetImpl_Destroy(
395 IKsBufferPropertySetImpl *piks);
397 /*****************************************************************************
398 * IKsPrivatePropertySet implementation structure
400 struct IKsPrivatePropertySetImpl
402 /* IUnknown fields */
403 ICOM_VFIELD(IKsPropertySet);
407 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
408 IKsPrivatePropertySetImpl **piks);
410 /*****************************************************************************
411 * IDirectSound3DBuffer implementation structure
413 struct IDirectSound3DBufferImpl
415 /* IUnknown fields */
416 ICOM_VFIELD(IDirectSound3DBuffer);
418 /* IDirectSound3DBufferImpl fields */
419 IDirectSoundBufferImpl* dsb;
422 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
423 IDirectSoundBufferImpl *dsb,
424 IDirectSound3DBufferImpl **pds3db);
425 HRESULT WINAPI IDirectSound3DBufferImpl_Destroy(
426 IDirectSound3DBufferImpl *pds3db);
428 /*******************************************************************************
429 * DirectSound ClassFactory implementation structure
431 struct IClassFactoryImpl
433 /* IUnknown fields */
434 ICOM_VFIELD(IClassFactory);
438 extern IClassFactoryImpl DSOUND_CAPTURE_CF;
439 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
441 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
442 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
446 HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
447 HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
448 HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
449 HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
450 HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
454 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
455 DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
459 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
460 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
461 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
462 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
463 void DSOUND_PerformMix(IDirectSoundImpl *dsound);
464 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
465 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
469 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
471 #define STATE_STOPPED 0
472 #define STATE_STARTING 1
473 #define STATE_PLAYING 2
474 #define STATE_CAPTURING 2
475 #define STATE_STOPPING 3
477 #define DSOUND_FREQSHIFT (14)
479 extern IDirectSoundImpl* dsound;
481 extern HRESULT mmErr(UINT err);
482 extern void setup_dsound_options(void);