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 extern int ds_emuldriver;
30 extern int ds_hel_margin;
31 extern int ds_hel_queue;
32 extern int ds_snd_queue_max;
33 extern int ds_snd_queue_min;
35 /*****************************************************************************
36 * Predeclare the interface implementation structures
38 typedef struct IDirectSoundImpl IDirectSoundImpl;
39 typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
40 typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
41 typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
42 typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
43 typedef struct IKsPropertySetImpl IKsPropertySetImpl;
44 typedef struct PrimaryBufferImpl PrimaryBufferImpl;
46 /*****************************************************************************
47 * IDirectSound implementation structure
49 struct IDirectSoundImpl
52 ICOM_VFIELD(IDirectSound8);
54 /* IDirectSoundImpl fields */
59 WAVEFORMATEX wfx; /* current main waveformat */
61 LPWAVEHDR pwave[DS_HEL_FRAGS];
62 UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
64 PIDSDRIVERBUFFER hwbuf;
66 DWORD writelead, buflen, state, playpos, mixpos;
69 IDirectSoundBufferImpl** buffers;
70 IDirectSound3DListenerImpl* listener;
72 CRITICAL_SECTION mixlock;
76 /*****************************************************************************
77 * IDirectSoundBuffer implementation structure
79 struct IDirectSoundBufferImpl
83 ICOM_VFIELD(IDirectSoundBuffer8);
85 /* IDirectSoundBufferImpl fields */
86 IDirectSoundImpl* dsound;
87 IDirectSoundBufferImpl* parent; /* for duplicates */
88 IDirectSound3DBufferImpl* ds3db;
89 IKsPropertySetImpl* iks;
90 CRITICAL_SECTION lock;
91 PIDSDRIVERBUFFER hwbuf;
94 DWORD playflags,state,leadin;
95 DWORD playpos,startpos,writelead,buflen;
96 DWORD nAvgBytesPerSec;
98 DSVOLUMEPAN volpan, cvolpan;
100 /* used for frequency conversion (PerfectPitch) */
101 ULONG freqAdjust, freqAcc;
102 /* used for intelligent (well, sort of) prebuffering */
103 DWORD probably_valid_to, last_playpos;
104 DWORD primary_mixpos, buf_mixpos;
106 /* IDirectSoundNotifyImpl fields */
107 LPDSBPOSITIONNOTIFY notifies;
111 HRESULT WINAPI SecondaryBuffer_Create(
112 IDirectSoundImpl *This,
113 IDirectSoundBufferImpl **pdsb,
114 LPDSBUFFERDESC dsbd);
116 struct PrimaryBufferImpl {
117 ICOM_VFIELD(IDirectSoundBuffer8);
119 IDirectSoundImpl* dsound;
123 HRESULT WINAPI PrimaryBuffer_Create(
124 IDirectSoundImpl *This,
125 PrimaryBufferImpl **pdsb,
126 LPDSBUFFERDESC dsbd);
128 /*****************************************************************************
129 * IDirectSoundNotify implementation structure
131 struct IDirectSoundNotifyImpl
133 /* IUnknown fields */
134 ICOM_VFIELD(IDirectSoundNotify);
136 /* IDirectSoundNotifyImpl fields */
137 IDirectSoundBufferImpl* dsb;
140 /*****************************************************************************
141 * IDirectSound3DListener implementation structure
143 struct IDirectSound3DListenerImpl
145 /* IUnknown fields */
146 ICOM_VFIELD(IDirectSound3DListener);
148 /* IDirectSound3DListenerImpl fields */
149 PrimaryBufferImpl* dsb;
151 CRITICAL_SECTION lock;
155 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
156 PrimaryBufferImpl *This,
157 IDirectSound3DListenerImpl **pdsl);
159 /*****************************************************************************
160 * IKsPropertySet implementation structure
162 struct IKsPropertySetImpl
164 /* IUnknown fields */
165 ICOM_VFIELD(IKsPropertySet);
167 /* IKsPropertySetImpl fields */
168 IDirectSoundBufferImpl* dsb;
171 HRESULT WINAPI IKsPropertySetImpl_Create(
172 IDirectSoundBufferImpl *This,
173 IKsPropertySetImpl **piks);
175 /*****************************************************************************
176 * IDirectSound3DBuffer implementation structure
178 struct IDirectSound3DBufferImpl
180 /* IUnknown fields */
181 ICOM_VFIELD(IDirectSound3DBuffer);
183 /* IDirectSound3DBufferImpl fields */
184 IDirectSoundBufferImpl* dsb;
187 CRITICAL_SECTION lock;
191 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
192 IDirectSoundBufferImpl *This,
193 IDirectSound3DBufferImpl **pds3db);
195 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
196 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
200 HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
201 HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
202 HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
203 HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
204 HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
208 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
209 DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
213 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
214 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
215 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
216 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
217 void DSOUND_PerformMix(void);
218 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
219 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
221 #define STATE_STOPPED 0
222 #define STATE_STARTING 1
223 #define STATE_PLAYING 2
224 #define STATE_STOPPING 3
226 #define DSOUND_FREQSHIFT (14)
228 extern IDirectSoundImpl* dsound;
230 struct PrimaryBuffer {
232 PIDSDRIVERBUFFER hwbuf;