3D buffer and listener reference counts should be fixed.
[wine] / dlls / dsound / dsound_private.h
1 /*                      DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2001 TransGaming Technologies, Inc.
6  *
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.
11  *
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.
16  *
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
20  */
21
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 */
25
26 #define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
27                          * (changing this won't help you) */
28
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
34
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;
43
44 /*****************************************************************************
45  * Predeclare the interface implementation structures
46  */
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
58 /*****************************************************************************
59  * IDirectSound implementation structure
60  */
61 struct IDirectSoundImpl
62 {
63     /* IUnknown fields */
64     ICOM_VFIELD(IDirectSound8);
65     DWORD                       ref;
66     /* IDirectSoundImpl fields */
67     GUID                        guid;
68     PIDSDRIVER                  driver;
69     DSDRIVERDESC                drvdesc;
70     DSDRIVERCAPS                drvcaps;
71     DWORD                       priolevel;
72     WAVEFORMATEX                wfx; /* current main waveformat */
73     HWAVEOUT                    hwo;
74     LPWAVEHDR                   pwave[DS_HEL_FRAGS];
75     UINT                        timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
76     DWORD                       fraglen;
77     PIDSDRIVERBUFFER            hwbuf;
78     LPBYTE                      buffer;
79     DWORD                       writelead, buflen, state, playpos, mixpos;
80     BOOL                        need_remix;
81     int                         nrofbuffers;
82     IDirectSoundBufferImpl**    buffers;
83     RTL_RWLOCK                  lock;
84     CRITICAL_SECTION            mixlock;
85     DSVOLUMEPAN                 volpan;
86     PrimaryBufferImpl*          primary;
87     DSBUFFERDESC                dsbd;
88
89     /* DirectSound3DListener fields */
90     IDirectSound3DListenerImpl* listener;
91     DS3DLISTENER                ds3dl;
92     CRITICAL_SECTION            ds3dl_lock;
93     BOOL                        ds3dl_need_recalc;
94 };
95
96 /* reference counted buffer memory for duplicated buffer memory */
97 typedef struct BufferMemory
98 {
99     DWORD                       ref;
100     LPBYTE                      memory;
101 } BufferMemory;
102
103 /*****************************************************************************
104  * IDirectSoundBuffer implementation structure
105  */
106 struct IDirectSoundBufferImpl
107 {
108     /* FIXME: document */
109     /* IUnknown fields */
110     ICOM_VFIELD(IDirectSoundBuffer8);
111     DWORD                       ref;
112     /* IDirectSoundBufferImpl fields */
113     IDirectSoundImpl*           dsound;
114     IDirectSound3DBufferImpl*   ds3db;
115     IKsPropertySetImpl*         iks;
116     CRITICAL_SECTION            lock;
117     PIDSDRIVERBUFFER            hwbuf;
118     WAVEFORMATEX                wfx;
119     BufferMemory*               buffer;
120     DWORD                       playflags,state,leadin;
121     DWORD                       playpos,startpos,writelead,buflen;
122     DWORD                       nAvgBytesPerSec;
123     DWORD                       freq;
124     DSVOLUMEPAN                 volpan, cvolpan;
125     DSBUFFERDESC                dsbd;
126     /* used for frequency conversion (PerfectPitch) */
127     ULONG                       freqAdjust, freqAcc;
128     /* used for intelligent (well, sort of) prebuffering */
129     DWORD                       probably_valid_to, last_playpos;
130     DWORD                       primary_mixpos, buf_mixpos;
131     BOOL                        need_remix;
132     /* IDirectSoundNotifyImpl fields */
133     IDirectSoundNotifyImpl*     notify;
134
135     /* DirectSound3DBuffer fields */
136     DS3DBUFFER                  ds3db_ds3db;
137     LONG                        ds3db_lVolume;
138     BOOL                        ds3db_need_recalc;
139 };
140
141 HRESULT WINAPI SecondaryBuffer_Create(
142         IDirectSoundImpl *This,
143         IDirectSoundBufferImpl **pdsb,
144         LPDSBUFFERDESC dsbd);
145
146 struct PrimaryBufferImpl {
147     ICOM_VFIELD(IDirectSoundBuffer8);
148     DWORD                       ref;
149     IDirectSoundImpl*           dsound;
150 };
151
152 HRESULT WINAPI PrimaryBuffer_Create(
153         IDirectSoundImpl *This,
154         PrimaryBufferImpl **pdsb,
155         LPDSBUFFERDESC dsbd);
156
157 /*****************************************************************************
158  * IDirectSoundCapture implementation structure
159  */
160 struct IDirectSoundCaptureImpl
161 {
162     /* IUnknown fields */
163     ICOM_VFIELD(IDirectSoundCapture);
164     DWORD                              ref;
165
166     /* IDirectSoundCaptureImpl fields */
167     GUID                               guid;
168     BOOL                               initialized;
169
170     /* DirectSound driver stuff */
171     PIDSCDRIVER                        driver;
172     DSDRIVERDESC                       drvdesc;
173     DSCDRIVERCAPS                      drvcaps;
174     PIDSCDRIVERBUFFER                  hwbuf;
175
176     /* wave driver info */
177     HWAVEIN                            hwi;
178
179     /* more stuff */
180     LPBYTE                             buffer;
181     DWORD                              buflen;
182     DWORD                              read_position;
183
184     /* FIXME: this should be a pointer because it can be bigger */
185     WAVEFORMATEX                       wfx;
186
187     IDirectSoundCaptureBufferImpl*     capture_buffer;
188     DWORD                              state;
189     LPWAVEHDR                          pwave;
190     int                                nrofpwaves;
191     int                                index;
192     CRITICAL_SECTION                   lock;
193 };
194
195 /*****************************************************************************
196  * IDirectSoundCaptureBuffer implementation structure
197  */
198 struct IDirectSoundCaptureBufferImpl
199 {
200     /* IUnknown fields */
201     ICOM_VFIELD(IDirectSoundCaptureBuffer8);
202     DWORD                               ref;
203
204     /* IDirectSoundCaptureBufferImpl fields */
205     IDirectSoundCaptureImpl*            dsound;
206     /* FIXME: don't need this */
207     LPDSCBUFFERDESC                     pdscbd;
208     DWORD                               flags;
209     /* IDirectSoundNotifyImpl fields */
210     IDirectSoundNotifyImpl*             notify;
211 };
212
213 /*****************************************************************************
214  * IDirectSoundFullDuplex implementation structure
215  */
216 struct IDirectSoundFullDuplexImpl
217 {
218     /* IUnknown fields */
219     ICOM_VFIELD(IDirectSoundFullDuplex);
220     DWORD                       ref;
221
222     /* IDirectSoundFullDuplexImpl fields */
223     CRITICAL_SECTION            lock;
224 };
225
226 /*****************************************************************************
227  * IDirectSoundNotify implementation structure
228  */
229 struct IDirectSoundNotifyImpl
230 {
231     /* IUnknown fields */
232     ICOM_VFIELD(IDirectSoundNotify);
233     DWORD                       ref;
234     /* IDirectSoundNotifyImpl fields */
235     LPDSBPOSITIONNOTIFY         notifies;
236     int                         nrofnotifies;
237
238     PIDSDRIVERNOTIFY            hwnotify;
239 };
240
241 /*****************************************************************************
242  *  IDirectSound3DListener implementation structure
243  */
244 struct IDirectSound3DListenerImpl
245 {
246     /* IUnknown fields */
247     ICOM_VFIELD(IDirectSound3DListener);
248     DWORD                       ref;
249     /* IDirectSound3DListenerImpl fields */
250     IDirectSoundImpl*           dsound;
251 };
252
253 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
254         PrimaryBufferImpl *This,
255         IDirectSound3DListenerImpl **pdsl);
256
257 /*****************************************************************************
258  *  IKsPropertySet implementation structure
259  */
260 struct IKsPropertySetImpl
261 {
262     /* IUnknown fields */
263     ICOM_VFIELD(IKsPropertySet);
264     DWORD                       ref;
265     /* IKsPropertySetImpl fields */
266     IDirectSoundBufferImpl*     dsb;
267 };
268
269 HRESULT WINAPI IKsPropertySetImpl_Create(
270         IDirectSoundBufferImpl *This,
271         IKsPropertySetImpl **piks);
272
273 /*****************************************************************************
274  * IDirectSound3DBuffer implementation structure
275  */
276 struct IDirectSound3DBufferImpl
277 {
278     /* IUnknown fields */
279     ICOM_VFIELD(IDirectSound3DBuffer);
280     DWORD                       ref;
281     /* IDirectSound3DBufferImpl fields */
282     IDirectSoundBufferImpl*     dsb;
283     CRITICAL_SECTION            lock;
284 };
285
286 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
287         IDirectSoundBufferImpl *This,
288         IDirectSound3DBufferImpl **pds3db);
289
290 void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
291 void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
292
293 /* primary.c */
294
295 HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
296 HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
297 HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
298 HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
299 HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
300
301 /* buffer.c */
302
303 DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
304                               DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
305
306 /* mixer.c */
307
308 void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
309 void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
310 void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
311 void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
312 void DSOUND_PerformMix(void);
313 void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
314 void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
315
316 /* sound3d.c */
317
318 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
319
320 #define STATE_STOPPED   0
321 #define STATE_STARTING  1
322 #define STATE_PLAYING   2
323 #define STATE_CAPTURING 2
324 #define STATE_STOPPING  3
325
326 #define DSOUND_FREQSHIFT (14)
327
328 extern IDirectSoundImpl* dsound;
329 extern IDirectSoundCaptureImpl* dsound_capture;
330
331 extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
332 extern HRESULT mmErr(UINT err);
333 extern void setup_dsound_options(void);