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 IDirectSoundBufferImpl IDirectSoundBufferImpl;
49 typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
50 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
51 typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
52 typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
53 typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
54 typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
55 typedef struct IKsPropertySetImpl IKsPropertySetImpl;
56 typedef struct PrimaryBufferImpl PrimaryBufferImpl;
57 typedef struct IClassFactoryImpl IClassFactoryImpl;
59 /*****************************************************************************
60 * IDirectSound implementation structure
62 struct IDirectSoundImpl
65 ICOM_VFIELD(IDirectSound8);
67 /* IDirectSoundImpl fields */
73 WAVEFORMATEX wfx; /* current main waveformat */
75 LPWAVEHDR pwave[DS_HEL_FRAGS];
76 UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
78 PIDSDRIVERBUFFER hwbuf;
80 DWORD writelead, buflen, state, playpos, mixpos;
83 IDirectSoundBufferImpl** buffers;
85 CRITICAL_SECTION mixlock;
87 PrimaryBufferImpl* primary;
90 /* DirectSound3DListener fields */
91 IDirectSound3DListenerImpl* listener;
93 CRITICAL_SECTION ds3dl_lock;
94 BOOL ds3dl_need_recalc;
97 /* reference counted buffer memory for duplicated buffer memory */
98 typedef struct BufferMemory
104 /*****************************************************************************
105 * IDirectSoundBuffer implementation structure
107 struct IDirectSoundBufferImpl
109 /* FIXME: document */
110 /* IUnknown fields */
111 ICOM_VFIELD(IDirectSoundBuffer8);
113 /* IDirectSoundBufferImpl fields */
114 IDirectSoundImpl* dsound;
115 IDirectSound3DBufferImpl* ds3db;
116 IKsPropertySetImpl* iks;
117 CRITICAL_SECTION lock;
118 PIDSDRIVERBUFFER hwbuf;
120 BufferMemory* buffer;
121 DWORD playflags,state,leadin;
122 DWORD playpos,startpos,writelead,buflen;
123 DWORD nAvgBytesPerSec;
125 DSVOLUMEPAN volpan, cvolpan;
127 /* used for frequency conversion (PerfectPitch) */
128 ULONG freqAdjust, freqAcc;
129 /* used for intelligent (well, sort of) prebuffering */
130 DWORD probably_valid_to, last_playpos;
131 DWORD primary_mixpos, buf_mixpos;
133 /* IDirectSoundNotifyImpl fields */
134 IDirectSoundNotifyImpl* notify;
136 /* DirectSound3DBuffer fields */
137 DS3DBUFFER ds3db_ds3db;
139 BOOL ds3db_need_recalc;
142 HRESULT WINAPI SecondaryBuffer_Create(
143 IDirectSoundImpl *This,
144 IDirectSoundBufferImpl **pdsb,
145 LPDSBUFFERDESC dsbd);
147 struct PrimaryBufferImpl {
148 ICOM_VFIELD(IDirectSoundBuffer8);
150 IDirectSoundImpl* dsound;
153 HRESULT WINAPI PrimaryBuffer_Create(
154 IDirectSoundImpl *This,
155 PrimaryBufferImpl **pdsb,
156 LPDSBUFFERDESC dsbd);
158 /*****************************************************************************
159 * IDirectSoundCapture implementation structure
161 struct IDirectSoundCaptureImpl
163 /* IUnknown fields */
164 ICOM_VFIELD(IDirectSoundCapture);
167 /* IDirectSoundCaptureImpl fields */
171 /* DirectSound driver stuff */
173 DSDRIVERDESC drvdesc;
174 DSCDRIVERCAPS drvcaps;
175 PIDSCDRIVERBUFFER hwbuf;
177 /* wave driver info */
185 /* FIXME: this should be a pointer because it can be bigger */
188 IDirectSoundCaptureBufferImpl* capture_buffer;
193 CRITICAL_SECTION lock;
196 /*****************************************************************************
197 * IDirectSoundCaptureBuffer implementation structure
199 struct IDirectSoundCaptureBufferImpl
201 /* IUnknown fields */
202 ICOM_VFIELD(IDirectSoundCaptureBuffer8);
205 /* IDirectSoundCaptureBufferImpl fields */
206 IDirectSoundCaptureImpl* dsound;
207 /* FIXME: don't need this */
208 LPDSCBUFFERDESC pdscbd;
210 /* IDirectSoundNotifyImpl fields */
211 IDirectSoundNotifyImpl* notify;
214 /*****************************************************************************
215 * IDirectSoundFullDuplex implementation structure
217 struct IDirectSoundFullDuplexImpl
219 /* IUnknown fields */
220 ICOM_VFIELD(IDirectSoundFullDuplex);
223 /* IDirectSoundFullDuplexImpl fields */
224 CRITICAL_SECTION lock;
227 /*****************************************************************************
228 * IDirectSoundNotify implementation structure
230 struct IDirectSoundNotifyImpl
232 /* IUnknown fields */
233 ICOM_VFIELD(IDirectSoundNotify);
235 /* IDirectSoundNotifyImpl fields */
236 LPDSBPOSITIONNOTIFY notifies;
239 PIDSDRIVERNOTIFY hwnotify;
242 /*****************************************************************************
243 * IDirectSound3DListener implementation structure
245 struct IDirectSound3DListenerImpl
247 /* IUnknown fields */
248 ICOM_VFIELD(IDirectSound3DListener);
250 /* IDirectSound3DListenerImpl fields */
251 IDirectSoundImpl* dsound;
254 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
255 PrimaryBufferImpl *This,
256 IDirectSound3DListenerImpl **pdsl);
258 /*****************************************************************************
259 * IKsPropertySet implementation structure
261 struct IKsPropertySetImpl
263 /* IUnknown fields */
264 ICOM_VFIELD(IKsPropertySet);
266 /* IKsPropertySetImpl fields */
267 IDirectSoundBufferImpl* dsb;
270 HRESULT WINAPI IKsPropertySetImpl_Create(
271 IDirectSoundBufferImpl *This,
272 IKsPropertySetImpl **piks);
274 /*****************************************************************************
275 * IDirectSound3DBuffer implementation structure
277 struct IDirectSound3DBufferImpl
279 /* IUnknown fields */
280 ICOM_VFIELD(IDirectSound3DBuffer);
282 /* IDirectSound3DBufferImpl fields */
283 IDirectSoundBufferImpl* dsb;
284 CRITICAL_SECTION lock;
287 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
288 IDirectSoundBufferImpl *This,
289 IDirectSound3DBufferImpl **pds3db);
291 /*******************************************************************************
292 * DirectSound ClassFactory implementation structure
294 struct IClassFactoryImpl
296 /* IUnknown fields */
297 ICOM_VFIELD(IClassFactory);
301 extern IClassFactoryImpl DSOUND_CAPTURE_CF;
302 extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
304 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
305 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
309 HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
310 HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
311 HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
312 HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
313 HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
317 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
318 DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
322 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
323 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
324 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
325 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
326 void DSOUND_PerformMix(void);
327 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
328 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
332 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
334 #define STATE_STOPPED 0
335 #define STATE_STARTING 1
336 #define STATE_PLAYING 2
337 #define STATE_CAPTURING 2
338 #define STATE_STOPPING 3
340 #define DSOUND_FREQSHIFT (14)
342 extern IDirectSoundImpl* dsound;
343 extern IDirectSoundCaptureImpl* dsound_capture;
345 extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
346 extern HRESULT mmErr(UINT err);
347 extern void setup_dsound_options(void);