dsound_private.h 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*  			DirectSound
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 * Copyright 2000-2001 TransGaming Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 21 22
 */

/* Linux does not support better timing than 10ms */
23
#define DS_TIME_RES 2  /* Resolution of multimedia timer */
24 25
#define DS_TIME_DEL 10  /* Delay of multimedia timer callback, and duration of HEL fragment */

26 27 28
#include "wingdi.h"
#include "mmdeviceapi.h"
#include "audioclient.h"
29
#include "mediaobj.h"
30
#include "mmsystem.h"
31
#include "uuids.h"
32

33 34
#include "wine/list.h"

35
#define DS_MAX_CHANNELS 6
36

37
extern int ds_hel_buflen DECLSPEC_HIDDEN;
38 39 40 41

/*****************************************************************************
 * Predeclare the interface implementation structures
 */
42
typedef struct IDirectSoundBufferImpl        IDirectSoundBufferImpl;
43
typedef struct DirectSoundDevice             DirectSoundDevice;
44

45
/* dsound_convert.h */
46 47 48
typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD);
typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float);
extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN;
49
void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
50
void putieee32_sum(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
51
void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN;
52
typedef void (*normfunc)(const void *, void *, unsigned);
53
extern const normfunc normfunctions[4] DECLSPEC_HIDDEN;
54

55 56
typedef struct _DSVOLUMEPAN
{
57
    DWORD	dwTotalAmpFactor[DS_MAX_CHANNELS];
58 59 60 61
    LONG	lVolume;
    LONG	lPan;
} DSVOLUMEPAN,*PDSVOLUMEPAN;

62 63 64 65 66 67
typedef struct DSFilter {
    GUID guid;
    IMediaObject* obj;
    IMediaObjectInPlace* inplace;
} DSFilter;

68 69 70
/*****************************************************************************
 * IDirectSoundDevice implementation structure
 */
71 72
struct DirectSoundDevice
{
73
    LONG                        ref;
74

75
    GUID                        guid;
76
    DSCAPS                      drvcaps;
77
    DWORD                       priolevel, sleeptime;
78
    PWAVEFORMATEX               pwfx, primary_pwfx;
79
    LPBYTE                      buffer;
80
    DWORD                       writelead, buflen, aclen, fraglen, playpos, pad, stopped;
81 82
    int                         nrofbuffers;
    IDirectSoundBufferImpl**    buffers;
83
    RTL_RWLOCK                  buffer_list_lock;
84
    CRITICAL_SECTION            mixlock;
85
    IDirectSoundBufferImpl     *primary;
86
    DWORD                       speaker_config;
87 88 89 90
    float                       speaker_angles[DS_MAX_CHANNELS];
    int                         speaker_num[DS_MAX_CHANNELS];
    int                         num_speakers;
    int                         lfe_channel;
91 92
    float *tmp_buffer, *cp_buffer;
    DWORD                       tmp_buffer_len, cp_buffer_len;
93

94 95
    DSVOLUMEPAN                 volpan;

96
    normfunc normfunction;
97 98 99 100

    /* DirectSound3DListener fields */
    DS3DLISTENER                ds3dl;
    BOOL                        ds3dl_need_recalc;
101 102 103 104 105 106

    IMMDevice *mmdevice;
    IAudioClient *client;
    IAudioStreamVolume *volume;
    IAudioRenderClient *render;

107
    HANDLE sleepev, thread;
108
    HANDLE thread_finished;
109
    struct list entry;
110 111
};

112 113 114
/* reference counted buffer memory for duplicated buffer memory */
typedef struct BufferMemory
{
115
    LONG                        ref;
116
    LONG                        lockedbytes;
117
    LPBYTE                      memory;
118
    struct list buffers;
119 120
} BufferMemory;

121
HRESULT DirectSoundDevice_AddBuffer(
122
    DirectSoundDevice * device,
123
    IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
124
void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
125

126 127 128 129 130
/*****************************************************************************
 * IDirectSoundBuffer implementation structure
 */
struct IDirectSoundBufferImpl
{
131
    IDirectSoundBuffer8         IDirectSoundBuffer8_iface;
132
    IDirectSoundNotify          IDirectSoundNotify_iface;
133
    IDirectSound3DListener      IDirectSound3DListener_iface; /* only primary buffer */
134
    IDirectSound3DBuffer        IDirectSound3DBuffer_iface; /* only secondary buffer */
135
    IKsPropertySet              IKsPropertySet_iface;
136
    LONG                        numIfaces; /* "in use interfaces" refcount */
137
    LONG                        ref, refn, ref3D, refiks;
138
    /* IDirectSoundBufferImpl fields */
Robert Reif's avatar
Robert Reif committed
139
    DirectSoundDevice*          device;
140
    RTL_RWLOCK                  lock;
141
    PWAVEFORMATEX               pwfx;
142 143
    BufferMemory*               buffer;
    DWORD                       playflags,state,leadin;
144
    DWORD                       writelead,buflen;
145
    DWORD                       nAvgBytesPerSec;
146
    DWORD                       freq;
147
    DSVOLUMEPAN                 volpan;
148
    DSBUFFERDESC                dsbd;
149
    /* used for frequency conversion (PerfectPitch) */
150
    ULONG                       freqneeded;
151
    DWORD                       firstep;
152 153 154
    float                       firgain;
    LONG64                      freqAdjustNum,freqAdjustDen;
    LONG64                      freqAccNum;
155
    /* used for mixing */
156
    DWORD                       sec_mixpos;
157

158
    /* IDirectSoundNotify fields */
159 160
    LPDSBPOSITIONNOTIFY         notifies;
    int                         nrofnotifies;
161 162 163 164
    /* DirectSound3DBuffer fields */
    DS3DBUFFER                  ds3db_ds3db;
    LONG                        ds3db_lVolume;
    BOOL                        ds3db_need_recalc;
165
    /* Used for bit depth conversion */
166 167 168
    int                         mix_channels;
    bitsgetfunc get, get_aux;
    bitsputfunc put, put_aux;
169 170
    int                         num_filters;
    DSFilter*                   filters;
171

172
    struct list entry;
173 174
};

175 176
float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel) DECLSPEC_HIDDEN;
void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
177 178
void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
179 180
void put_mono2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
181
void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
182
void put_quad2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
183

184 185
HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *dsbd,
        IDirectSoundBuffer **buffer) DECLSPEC_HIDDEN;
186 187 188
HRESULT IDirectSoundBufferImpl_Duplicate(
    DirectSoundDevice *device,
    IDirectSoundBufferImpl **ppdsb,
189
    IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
190
void secondarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
191
const IDirectSound3DListenerVtbl ds3dlvt DECLSPEC_HIDDEN;
192
const IDirectSound3DBufferVtbl ds3dbvt DECLSPEC_HIDDEN;
193
const IKsPropertySetVtbl iksbvt DECLSPEC_HIDDEN;
194

195
HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
196

197 198
/*******************************************************************************
 */
199

200 201
/* dsound.c */

202 203
HRESULT DSOUND_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT DSOUND_Create8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
204
HRESULT IDirectSoundImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_ds8) DECLSPEC_HIDDEN;
205
void DSOUND_ParseSpeakerConfig(DirectSoundDevice *device) DECLSPEC_HIDDEN;
206

207 208
/* primary.c */

209 210 211 212 213
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device) DECLSPEC_HIDDEN;
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) DECLSPEC_HIDDEN;
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN;
214 215
HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
    const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
216
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
217
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
218
LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
219

220
/* duplex.c */
221 222

HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
223

224
/* mixer.c */
225 226 227 228
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
229
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float *overshot) DECLSPEC_HIDDEN;
230

231
DWORD CALLBACK DSOUND_mixthread(void *ptr) DECLSPEC_HIDDEN;
232

233 234
/* sound3d.c */

235
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
236

237
/* capture.c */
238
 
239 240
HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
241
HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_dsc8) DECLSPEC_HIDDEN;
242

243 244 245 246 247
#define STATE_STOPPED   0
#define STATE_STARTING  1
#define STATE_PLAYING   2
#define STATE_CAPTURING 2
#define STATE_STOPPING  3
248

249
extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN;
250 251
extern CRITICAL_SECTION DSOUND_capturers_lock DECLSPEC_HIDDEN;
extern struct list DSOUND_capturers DECLSPEC_HIDDEN;
252
extern struct list DSOUND_renderers DECLSPEC_HIDDEN;
253

254
extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
255
extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
256

257 258
extern WCHAR wine_vxd_drv[] DECLSPEC_HIDDEN;

259
void setup_dsound_options(void) DECLSPEC_HIDDEN;
260 261

HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) DECLSPEC_HIDDEN;
262 263 264

BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate,
        DWORD depth, WORD channels) DECLSPEC_HIDDEN;
265 266
HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
        LPDSENUMCALLBACKW cb, void *user) DECLSPEC_HIDDEN;