ReactOS 0.4.15-dev-8428-g6910fa6
primary.c File Reference
#include "dsound_private.h"
Include dependency graph for primary.c:

Go to the source code of this file.

Functions

DWORD DSOUND_fraglen (DWORD nSamplesPerSec, DWORD nBlockAlign)
 
static void DSOUND_RecalcPrimary (DirectSoundDevice *device)
 
HRESULT DSOUND_ReopenDevice (DirectSoundDevice *device, BOOL forcewave)
 
static HRESULT DSOUND_PrimaryOpen (DirectSoundDevice *device)
 
static void DSOUND_PrimaryClose (DirectSoundDevice *device)
 
HRESULT DSOUND_PrimaryCreate (DirectSoundDevice *device)
 
HRESULT DSOUND_PrimaryDestroy (DirectSoundDevice *device)
 
HRESULT DSOUND_PrimaryPlay (DirectSoundDevice *device)
 
HRESULT DSOUND_PrimaryStop (DirectSoundDevice *device)
 
HRESULT DSOUND_PrimaryGetPosition (DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
 
static DWORD DSOUND_GetFormatSize (LPCWAVEFORMATEX wfex)
 
LPWAVEFORMATEX DSOUND_CopyFormat (LPCWAVEFORMATEX wfex)
 
HRESULT primarybuffer_SetFormat (DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
 
static IDirectSoundBufferImplimpl_from_IDirectSoundBuffer (IDirectSoundBuffer *iface)
 
static HRESULT WINAPI PrimaryBufferImpl_SetFormat (LPDIRECTSOUNDBUFFER iface, LPCWAVEFORMATEX wfex)
 
static HRESULT WINAPI PrimaryBufferImpl_SetVolume (LPDIRECTSOUNDBUFFER iface, LONG vol)
 
static HRESULT WINAPI PrimaryBufferImpl_GetVolume (LPDIRECTSOUNDBUFFER iface, LPLONG vol)
 
static HRESULT WINAPI PrimaryBufferImpl_SetFrequency (LPDIRECTSOUNDBUFFER iface, DWORD freq)
 
static HRESULT WINAPI PrimaryBufferImpl_Play (LPDIRECTSOUNDBUFFER iface, DWORD reserved1, DWORD reserved2, DWORD flags)
 
static HRESULT WINAPI PrimaryBufferImpl_Stop (LPDIRECTSOUNDBUFFER iface)
 
static ULONG WINAPI PrimaryBufferImpl_AddRef (LPDIRECTSOUNDBUFFER iface)
 
void primarybuffer_destroy (IDirectSoundBufferImpl *This)
 
static ULONG WINAPI PrimaryBufferImpl_Release (LPDIRECTSOUNDBUFFER iface)
 
static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition (LPDIRECTSOUNDBUFFER iface, LPDWORD playpos, LPDWORD writepos)
 
static HRESULT WINAPI PrimaryBufferImpl_GetStatus (LPDIRECTSOUNDBUFFER iface, LPDWORD status)
 
static HRESULT WINAPI PrimaryBufferImpl_GetFormat (LPDIRECTSOUNDBUFFER iface, LPWAVEFORMATEX lpwf, DWORD wfsize, LPDWORD wfwritten)
 
static HRESULT WINAPI PrimaryBufferImpl_Lock (LPDIRECTSOUNDBUFFER iface, DWORD writecursor, DWORD writebytes, LPVOID *lplpaudioptr1, LPDWORD audiobytes1, LPVOID *lplpaudioptr2, LPDWORD audiobytes2, DWORD flags)
 
static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition (LPDIRECTSOUNDBUFFER iface, DWORD newpos)
 
static HRESULT WINAPI PrimaryBufferImpl_SetPan (LPDIRECTSOUNDBUFFER iface, LONG pan)
 
static HRESULT WINAPI PrimaryBufferImpl_GetPan (LPDIRECTSOUNDBUFFER iface, LPLONG pan)
 
static HRESULT WINAPI PrimaryBufferImpl_Unlock (LPDIRECTSOUNDBUFFER iface, LPVOID p1, DWORD x1, LPVOID p2, DWORD x2)
 
static HRESULT WINAPI PrimaryBufferImpl_Restore (LPDIRECTSOUNDBUFFER iface)
 
static HRESULT WINAPI PrimaryBufferImpl_GetFrequency (LPDIRECTSOUNDBUFFER iface, LPDWORD freq)
 
static HRESULT WINAPI PrimaryBufferImpl_Initialize (LPDIRECTSOUNDBUFFER iface, LPDIRECTSOUND dsound, LPCDSBUFFERDESC dbsd)
 
static HRESULT WINAPI PrimaryBufferImpl_GetCaps (LPDIRECTSOUNDBUFFER iface, LPDSBCAPS caps)
 
static HRESULT WINAPI PrimaryBufferImpl_QueryInterface (LPDIRECTSOUNDBUFFER iface, REFIID riid, LPVOID *ppobj)
 
HRESULT primarybuffer_create (DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, const DSBUFFERDESC *dsbd)
 

Variables

static const IDirectSoundBufferVtbl dspbvt
 

Function Documentation

◆ DSOUND_CopyFormat()

LPWAVEFORMATEX DSOUND_CopyFormat ( LPCWAVEFORMATEX  wfex)

Definition at line 437 of file primary.c.

438{
441 if (pwfx == NULL) {
442 WARN("out of memory\n");
443 } else if (wfex->wFormatTag != WAVE_FORMAT_PCM) {
444 CopyMemory(pwfx, wfex, size);
445 } else {
446 CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT));
447 pwfx->cbSize=0;
448 if (pwfx->nBlockAlign != pwfx->nChannels * pwfx->wBitsPerSample/8) {
449 WARN("Fixing bad nBlockAlign (%u)\n", pwfx->nBlockAlign);
450 pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample/8;
451 }
452 if (pwfx->nAvgBytesPerSec != pwfx->nSamplesPerSec * pwfx->nBlockAlign) {
453 WARN("Fixing bad nAvgBytesPerSec (%u)\n", pwfx->nAvgBytesPerSec);
454 pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
455 }
456 }
457 return pwfx;
458}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define WARN(fmt,...)
Definition: precomp.h:61
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
#define CopyMemory
Definition: winbase.h:1710
static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex)
Definition: primary.c:429

Referenced by IDirectSoundBufferImpl_Create(), IDirectSoundBufferImpl_Duplicate(), IDirectSoundCaptureBufferImpl_Create(), and primarybuffer_SetFormat().

◆ DSOUND_fraglen()

DWORD DSOUND_fraglen ( DWORD  nSamplesPerSec,
DWORD  nBlockAlign 
)

Calculate how long a fragment length of about 10 ms should be in frames

nSamplesPerSec: Frequency rate in samples per second nBlockAlign: Size of a single blockalign

Returns: Size in bytes of a single fragment

Definition at line 36 of file primary.c.

37{
38 /* Given a timer delay of 10ms, the fragment size is approximately:
39 * fraglen = (nSamplesPerSec * 10 / 1000) * nBlockAlign
40 * ==> fraglen = (nSamplesPerSec / 100) * nBlockSize
41 *
42 * ALSA uses buffers that are powers of 2. Because of this, fraglen
43 * is rounded up to the nearest power of 2:
44 */
45
46 if (nSamplesPerSec <= 12800)
47 return 128 * nBlockAlign;
48
49 if (nSamplesPerSec <= 25600)
50 return 256 * nBlockAlign;
51
52 if (nSamplesPerSec <= 51200)
53 return 512 * nBlockAlign;
54
55 return 1024 * nBlockAlign;
56}

Referenced by DSOUND_RecalcPrimary(), and IDirectSoundCaptureBufferImpl_Start().

◆ DSOUND_GetFormatSize()

static DWORD DSOUND_GetFormatSize ( LPCWAVEFORMATEX  wfex)
static

Definition at line 429 of file primary.c.

430{
431 if (wfex->wFormatTag == WAVE_FORMAT_PCM)
432 return sizeof(WAVEFORMATEX);
433 else
434 return sizeof(WAVEFORMATEX) + wfex->cbSize;
435}

Referenced by DSOUND_CopyFormat(), and primarybuffer_SetFormat().

◆ DSOUND_PrimaryClose()

static void DSOUND_PrimaryClose ( DirectSoundDevice device)
static

Definition at line 275 of file primary.c.

276{
277 TRACE("(%p)\n", device);
278
279 /* are we using waveOut stuff? */
280 if (!device->hwbuf) {
281 unsigned c;
282
283 /* get out of CS when calling the wave system */
284 LeaveCriticalSection(&(device->mixlock));
285 /* **** */
286 device->pwqueue = (DWORD)-1; /* resetting queues */
287 waveOutReset(device->hwo);
288 for (c=0; c<device->helfrags; c++)
289 waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
290 /* **** */
291 EnterCriticalSection(&(device->mixlock));
292
293 /* clear the queue */
294 device->pwqueue = 0;
295 } else {
297 if (!ref)
298 device->hwbuf = 0;
299 else
300 ERR("Still %d references on primary buffer, refcount leak?\n", ref);
301 }
302}
#define ERR(fmt,...)
Definition: precomp.h:57
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
#define DWORD
Definition: nt_native.h:44
#define TRACE(s)
Definition: solgame.cpp:4
Definition: devices.h:37
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307

Referenced by DSOUND_PrimaryDestroy(), DSOUND_PrimaryStop(), and primarybuffer_SetFormat().

◆ DSOUND_PrimaryCreate()

HRESULT DSOUND_PrimaryCreate ( DirectSoundDevice device)

Definition at line 304 of file primary.c.

305{
306 HRESULT err = DS_OK;
307 TRACE("(%p)\n", device);
308
309 device->buflen = ds_hel_buflen;
311
312 if (err != DS_OK) {
313 WARN("DSOUND_PrimaryOpen failed\n");
314 return err;
315 }
316
317 device->state = STATE_STOPPED;
318 return DS_OK;
319}
#define DS_OK
Definition: dsound.h:116
int ds_hel_buflen
Definition: dsound_main.c:74
#define STATE_STOPPED
#define err(...)
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
Definition: primary.c:136

Referenced by DirectSoundDevice_Initialize().

◆ DSOUND_PrimaryDestroy()

HRESULT DSOUND_PrimaryDestroy ( DirectSoundDevice device)

Definition at line 321 of file primary.c.

322{
323 TRACE("(%p)\n", device);
324
325 /* **** */
326 EnterCriticalSection(&(device->mixlock));
327
329 if (device->driver) {
330 if (device->hwbuf) {
331 if (IDsDriverBuffer_Release(device->hwbuf) == 0)
332 device->hwbuf = 0;
333 }
334 } else
335 HeapFree(GetProcessHeap(),0,device->pwave);
336 HeapFree(GetProcessHeap(),0,device->pwfx);
337 device->pwfx=NULL;
338
339 LeaveCriticalSection(&(device->mixlock));
340 /* **** */
341
342 return DS_OK;
343}
#define HeapFree(x, y, z)
Definition: compat.h:735
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275

Referenced by DirectSoundDevice_Release().

◆ DSOUND_PrimaryGetPosition()

HRESULT DSOUND_PrimaryGetPosition ( DirectSoundDevice device,
LPDWORD  playpos,
LPDWORD  writepos 
)

Definition at line 402 of file primary.c.

403{
404 TRACE("(%p,%p,%p)\n", device, playpos, writepos);
405
406 if (device->hwbuf) {
407 HRESULT err=IDsDriverBuffer_GetPosition(device->hwbuf,playpos,writepos);
408 if (err != S_OK) {
409 WARN("IDsDriverBuffer_GetPosition failed\n");
410 return err;
411 }
412 } else {
413 TRACE("pwplay=%i, pwqueue=%i\n", device->pwplay, device->pwqueue);
414
415 /* check if playpos was requested */
416 if (playpos)
417 /* use the cached play position */
418 *playpos = device->pwplay * device->fraglen;
419
420 /* check if writepos was requested */
421 if (writepos)
422 /* the writepos is the first non-queued position */
423 *writepos = ((device->pwplay + device->pwqueue) % device->helfrags) * device->fraglen;
424 }
425 TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:-1, writepos?*writepos:-1, device, GetTickCount());
426 return DS_OK;
427}
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define IDsDriverBuffer_GetPosition(p, a, b)
Definition: dsdriver.h:202
#define S_OK
Definition: intsafe.h:52

Referenced by DSOUND_PerformMix(), and PrimaryBufferImpl_GetCurrentPosition().

◆ DSOUND_PrimaryOpen()

static HRESULT DSOUND_PrimaryOpen ( DirectSoundDevice device)
static

Definition at line 136 of file primary.c.

137{
138 DWORD buflen;
139 HRESULT err = DS_OK;
140 TRACE("(%p)\n", device);
141
142 /* on original windows, the buffer it set to a fixed size, no matter what the settings are.
143 on windows this size is always fixed (tested on win-xp) */
144 if (!device->buflen)
145 device->buflen = ds_hel_buflen;
146 buflen = device->buflen;
147 buflen -= buflen % device->pwfx->nBlockAlign;
148 device->buflen = buflen;
149
150 if (device->driver)
151 {
154 &(device->buflen),&(device->buffer),
155 (LPVOID*)&(device->hwbuf));
156
157 if (err != DS_OK) {
158 WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err);
160 if (FAILED(err))
161 {
162 WARN("Falling back to waveout failed too! Giving up\n");
163 return err;
164 }
165 }
166 if (device->hwbuf)
168
170 device->prebuf = ds_snd_queue_max;
171 if (device->helfrags < ds_snd_queue_min)
172 {
173 WARN("Too little sound buffer to be effective (%d/%d) falling back to waveout\n", device->buflen, ds_snd_queue_min * device->fraglen);
174 device->buflen = buflen;
176 device->hwbuf = NULL;
178 if (FAILED(err))
179 {
180 WARN("Falling back to waveout failed too! Giving up\n");
181 return err;
182 }
183 }
184 else if (device->helfrags < ds_snd_queue_max)
185 device->prebuf = device->helfrags;
186 }
187
188 device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
189 device->mix_buffer = HeapAlloc(GetProcessHeap(), 0, device->mix_buffer_len);
190 if (!device->mix_buffer)
191 {
192 if (device->hwbuf)
194 device->hwbuf = NULL;
195 return DSERR_OUTOFMEMORY;
196 }
197
198 if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
199 else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
200
201 /* are we using waveOut stuff? */
202 if (!device->driver) {
203 LPBYTE newbuf;
205 DWORD overshot;
206 unsigned int c;
207
208 /* Start in pause mode, to allow buffers to get filled */
209 waveOutPause(device->hwo);
210
211 TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
212
213 /* reallocate emulated primary buffer */
214 if (device->buffer)
215 newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, buflen);
216 else
217 newbuf = HeapAlloc(GetProcessHeap(),0, buflen);
218
219 if (!newbuf) {
220 ERR("failed to allocate primary buffer\n");
221 return DSERR_OUTOFMEMORY;
222 /* but the old buffer might still exist and must be re-prepared */
223 }
224
226 if (device->pwave)
227 headers = HeapReAlloc(GetProcessHeap(),0,device->pwave, device->helfrags * sizeof(WAVEHDR));
228 else
229 headers = HeapAlloc(GetProcessHeap(),0,device->helfrags * sizeof(WAVEHDR));
230
231 if (!headers) {
232 ERR("failed to allocate wave headers\n");
233 HeapFree(GetProcessHeap(), 0, newbuf);
235 return DSERR_OUTOFMEMORY;
236 }
237
238 device->buffer = newbuf;
239 device->pwave = headers;
240
241 /* prepare fragment headers */
242 for (c=0; c<device->helfrags; c++) {
243 device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
244 device->pwave[c].dwBufferLength = device->fraglen;
245 device->pwave[c].dwUser = (DWORD_PTR)device;
246 device->pwave[c].dwFlags = 0;
247 device->pwave[c].dwLoops = 0;
248 err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
249 if (err != DS_OK) {
250 while (c--)
251 waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
252 break;
253 }
254 }
255
256 overshot = device->buflen % device->fraglen;
257 /* sanity */
258 if(overshot)
259 {
260 overshot -= overshot % device->pwfx->nBlockAlign;
261 device->pwave[device->helfrags - 1].dwBufferLength += overshot;
262 }
263
264 TRACE("fraglen=%d, overshot=%d\n", device->fraglen, overshot);
265 }
266 device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
267 device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
268 FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
269 FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
270 device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
271 return err;
272}
#define TRUE
Definition: types.h:120
#define HeapReAlloc
Definition: compat.h:734
#define IDsDriver_CreateSoundBuffer(p, a, b, c, d, e, f)
Definition: dsdriver.h:163
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
const mixfunc mixfunctions[4]
const normfunc normfunctions[4]
int ds_snd_queue_min
Definition: dsound_main.c:76
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
int ds_snd_queue_max
Definition: dsound_main.c:75
#define STATE_STOPPING
#define STATE_PLAYING
#define STATE_STARTING
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice *device, DWORD pos) DECLSPEC_HIDDEN
Definition: mixer.c:84
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
#define FAILED(hr)
Definition: intsafe.h:51
vector< Header * > headers
Definition: sdkparse.cpp:39
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
Definition: primary.c:58
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
Definition: primary.c:73
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2371

Referenced by DSOUND_PrimaryCreate(), DSOUND_PrimaryStop(), and primarybuffer_SetFormat().

◆ DSOUND_PrimaryPlay()

HRESULT DSOUND_PrimaryPlay ( DirectSoundDevice device)

Definition at line 345 of file primary.c.

346{
347 HRESULT err = DS_OK;
348 TRACE("(%p)\n", device);
349
350 if (device->hwbuf) {
352 if (err != DS_OK)
353 WARN("IDsDriverBuffer_Play failed\n");
354 } else {
356 if (err != DS_OK)
357 WARN("waveOutRestart failed\n");
358 }
359
360 return err;
361}
#define IDsDriverBuffer_Play(p, a, b, c)
Definition: dsdriver.h:203
#define DSBPLAY_LOOPING
Definition: dsound.h:189
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2399

Referenced by DSOUND_PerformMix().

◆ DSOUND_PrimaryStop()

HRESULT DSOUND_PrimaryStop ( DirectSoundDevice device)

Definition at line 363 of file primary.c.

364{
365 HRESULT err = DS_OK;
366 TRACE("(%p)\n", device);
367
368 if (device->hwbuf) {
370 if (err == DSERR_BUFFERLOST) {
373 if (FAILED(err))
374 ERR("DSOUND_ReopenDevice failed\n");
375 else
376 {
378 if (FAILED(err))
379 WARN("DSOUND_PrimaryOpen failed\n");
380 }
381 } else if (err != DS_OK) {
382 WARN("IDsDriverBuffer_Stop failed\n");
383 }
384 } else {
385
386 /* don't call the wave system with the lock set */
387 LeaveCriticalSection(&(device->mixlock));
388 /* **** */
389
390 err = mmErr(waveOutPause(device->hwo));
391
392 /* **** */
393 EnterCriticalSection(&(device->mixlock));
394
395 if (err != DS_OK)
396 WARN("waveOutPause failed\n");
397 }
398
399 return err;
400}
#define FALSE
Definition: types.h:117
#define IDsDriverBuffer_Stop(p)
Definition: dsdriver.h:204
#define DSERR_BUFFERLOST
Definition: dsound.h:131

Referenced by DSOUND_PerformMix().

◆ DSOUND_RecalcPrimary()

static void DSOUND_RecalcPrimary ( DirectSoundDevice device)
static

Definition at line 58 of file primary.c.

59{
60 TRACE("(%p)\n", device);
61
62 device->fraglen = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
63 device->helfrags = device->buflen / device->fraglen;
64 TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
65
66 if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
67 device->writelead = 0;
68 else
69 /* calculate the 10ms write lead */
70 device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
71}
#define DSDDESC_DONTNEEDWRITELEAD
Definition: dsdriver.h:55
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
Definition: primary.c:36

Referenced by DSOUND_PrimaryOpen(), and primarybuffer_SetFormat().

◆ DSOUND_ReopenDevice()

HRESULT DSOUND_ReopenDevice ( DirectSoundDevice device,
BOOL  forcewave 
)

Definition at line 73 of file primary.c.

74{
76 TRACE("(%p, %d)\n", device, forcewave);
77
78 if (device->driver)
79 {
80 IDsDriver_Close(device->driver);
81 if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
82 waveOutClose(device->hwo);
84 device->driver = NULL;
85 device->buffer = NULL;
86 device->hwo = 0;
87 }
88 else if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
89 waveOutClose(device->hwo);
90
91 /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
92 if (ds_hw_accel != DS_HW_ACCEL_EMULATION && !forcewave)
93 waveOutMessage((HWAVEOUT)(DWORD_PTR)device->drvdesc.dnDevNode, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0);
94
95 /* Get driver description */
96 if (device->driver) {
97 DWORD wod = device->drvdesc.dnDevNode;
98 hres = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc));
99 device->drvdesc.dnDevNode = wod;
100 if (FAILED(hres)) {
101 WARN("IDsDriver_GetDriverDesc failed: %08x\n", hres);
102 IDsDriver_Release(device->driver);
103 device->driver = NULL;
104 }
105 }
106
107 /* if no DirectSound interface available, use WINMM API instead */
108 if (!device->driver)
110
111 if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
112 {
114
115 if (device->driver)
117
118 hres = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD_PTR)device, flags));
119 if (FAILED(hres)) {
120 WARN("waveOutOpen failed\n");
121 if (device->driver)
122 {
123 IDsDriver_Release(device->driver);
124 device->driver = NULL;
125 }
126 return hres;
127 }
128 }
129
130 if (device->driver)
131 hres = IDsDriver_Open(device->driver);
132
133 return hres;
134}
#define IDsDriver_Close(p)
Definition: dsdriver.h:161
#define DSDDESC_DOMMSYSTEMOPEN
Definition: dsdriver.h:50
#define IDsDriver_GetDriverDesc(p, a)
Definition: dsdriver.h:159
#define IDsDriver_Open(p)
Definition: dsdriver.h:160
#define DSDDESC_DOMMSYSTEMSETFORMAT
Definition: dsdriver.h:51
#define IDsDriver_Release(p)
Definition: dsdriver.h:157
int ds_hw_accel
Definition: dsound_main.c:78
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN
Definition: mixer.c:1011
#define DS_HW_ACCEL_EMULATION
GLbitfield flags
Definition: glext.h:7161
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
HRESULT hres
Definition: protocol.c:465
#define WAVE_DIRECTSOUND
Definition: mmddk.h:482
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2538
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257

Referenced by DirectSoundDevice_Initialize(), DSOUND_PrimaryOpen(), DSOUND_PrimaryStop(), and primarybuffer_SetFormat().

◆ impl_from_IDirectSoundBuffer()

◆ primarybuffer_create()

HRESULT primarybuffer_create ( DirectSoundDevice device,
IDirectSoundBufferImpl **  ppdsb,
const DSBUFFERDESC dsbd 
)

Definition at line 1223 of file primary.c.

1225{
1227 TRACE("%p,%p,%p)\n",device,ppdsb,dsbd);
1228
1229 if (dsbd->lpwfxFormat) {
1230 WARN("invalid parameter: dsbd->lpwfxFormat != NULL\n");
1231 *ppdsb = NULL;
1232 return DSERR_INVALIDPARAM;
1233 }
1234
1235 dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
1236
1237 if (dsb == NULL) {
1238 WARN("out of memory\n");
1239 *ppdsb = NULL;
1240 return DSERR_OUTOFMEMORY;
1241 }
1242
1243 dsb->ref = 1;
1244 dsb->numIfaces = 1;
1245 dsb->device = device;
1246 dsb->IDirectSoundBuffer8_iface.lpVtbl = (IDirectSoundBuffer8Vtbl *)&dspbvt;
1247 dsb->dsbd = *dsbd;
1248
1249 TRACE("Created primary buffer at %p\n", dsb);
1250 TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
1251 "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
1252 device->pwfx->wFormatTag, device->pwfx->nChannels,
1253 device->pwfx->nSamplesPerSec, device->pwfx->nAvgBytesPerSec,
1254 device->pwfx->nBlockAlign, device->pwfx->wBitsPerSample,
1255 device->pwfx->cbSize);
1256
1257 *ppdsb = dsb;
1258 return S_OK;
1259}
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
DirectSoundDevice * device
IDirectSoundBuffer8 IDirectSoundBuffer8_iface
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
static const IDirectSoundBufferVtbl dspbvt
Definition: primary.c:1198

Referenced by DirectSoundDevice_CreateSoundBuffer().

◆ primarybuffer_destroy()

void primarybuffer_destroy ( IDirectSoundBufferImpl This)

Definition at line 763 of file primary.c.

764{
765 This->device->primary = NULL;
767 TRACE("(%p) released\n", This);
768}

Referenced by IDirectSound3DListenerImpl_Release(), IDirectSoundBufferImpl_Release(), and PrimaryBufferImpl_Release().

◆ primarybuffer_SetFormat()

HRESULT primarybuffer_SetFormat ( DirectSoundDevice device,
LPCWAVEFORMATEX  wfex 
)

Definition at line 460 of file primary.c.

461{
463 int i;
464 DWORD nSamplesPerSec, bpp, chans;
465 LPWAVEFORMATEX oldpwfx;
466 BOOL forced = device->priolevel == DSSCL_WRITEPRIMARY;
467
468 TRACE("(%p,%p)\n", device, wfex);
469
470 if (device->priolevel == DSSCL_NORMAL) {
471 WARN("failed priority check!\n");
473 }
474
475 /* Let's be pedantic! */
476 if (wfex == NULL) {
477 WARN("invalid parameter: wfex==NULL!\n");
478 return DSERR_INVALIDPARAM;
479 }
480 TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
481 "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
482 wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
483 wfex->nAvgBytesPerSec, wfex->nBlockAlign,
484 wfex->wBitsPerSample, wfex->cbSize);
485
486 /* **** */
487 RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
488 EnterCriticalSection(&(device->mixlock));
489
490 nSamplesPerSec = device->pwfx->nSamplesPerSec;
491 bpp = device->pwfx->wBitsPerSample;
492 chans = device->pwfx->nChannels;
493
494 oldpwfx = device->pwfx;
495 device->pwfx = DSOUND_CopyFormat(wfex);
496 if (device->pwfx == NULL) {
497 device->pwfx = oldpwfx;
498 oldpwfx = NULL;
500 goto done;
501 }
502
503 if (!(device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) && device->hwbuf) {
505
506 /* On bad format, try to re-create, big chance it will work then, only do this if we <HAVE> to */
507 if (forced && (device->pwfx->nSamplesPerSec/100 != wfex->nSamplesPerSec/100 || err == DSERR_BADFORMAT))
508 {
509 DWORD cp_size = wfex->wFormatTag == WAVE_FORMAT_PCM ?
510 sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX) + wfex->cbSize;
512 CopyMemory(device->pwfx, wfex, cp_size);
513 }
514
515 if (err != DSERR_BUFFERLOST && FAILED(err)) {
517 WARN("IDsDriverBuffer_SetFormat failed\n");
518 if (!forced) {
519 CopyMemory(device->pwfx, oldpwfx, size);
520 err = DS_OK;
521 }
522 goto done;
523 }
524
525 if (err == S_FALSE)
526 {
527 /* ALSA specific: S_FALSE tells that recreation was successful,
528 * but size and location may be changed, and buffer has to be restarted
529 * I put it here, so if frequency doesn't match the error will be changed to DSERR_BUFFERLOST
530 * and the entire re-initialization will occur anyway
531 */
532 IDsDriverBuffer_Lock(device->hwbuf, (LPVOID *)&device->buffer, &device->buflen, NULL, NULL, 0, 0, DSBLOCK_ENTIREBUFFER);
533 IDsDriverBuffer_Unlock(device->hwbuf, device->buffer, 0, NULL, 0);
534
535 if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
536 else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
537 device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
538 err = DS_OK;
539 }
541 }
542
543 if (err == DSERR_BUFFERLOST)
544 {
546
548 if (FAILED(err))
549 {
550 WARN("DSOUND_ReopenDevice failed: %08x\n", err);
551 goto done;
552 }
554 if (err != DS_OK) {
555 WARN("DSOUND_PrimaryOpen failed\n");
556 goto done;
557 }
558
559 if (wfex->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
560 {
562 device->pwfx->nSamplesPerSec = wfex->nSamplesPerSec;
564 if (FAILED(err))
565 WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
566 else if (FAILED((err = DSOUND_PrimaryOpen(device))))
567 WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
568 }
569 }
570
571 device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
572 device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
573 FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
574 device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
575 device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
576
577 if (nSamplesPerSec != device->pwfx->nSamplesPerSec || bpp != device->pwfx->wBitsPerSample || chans != device->pwfx->nChannels) {
578 IDirectSoundBufferImpl** dsb = device->buffers;
579 for (i = 0; i < device->nrofbuffers; i++, dsb++) {
580 /* **** */
581 RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);
582
583 (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
584 DSOUND_RecalcFormat((*dsb));
585 DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
586 (*dsb)->primary_mixpos = 0;
587
588 RtlReleaseResource(&(*dsb)->lock);
589 /* **** */
590 }
591 }
592
593done:
594 LeaveCriticalSection(&(device->mixlock));
595 RtlReleaseResource(&(device->buffer_list_lock));
596 /* **** */
597
598 HeapFree(GetProcessHeap(), 0, oldpwfx);
599 return err;
600}
DWORD bpp
Definition: surface.c:185
#define IDsDriverBuffer_SetFormat(p, a)
Definition: dsdriver.h:198
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
#define DSERR_BADFORMAT
Definition: dsound.h:126
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define DSSCL_NORMAL
Definition: dsound.h:247
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DSOUND_FREQSHIFT
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN
Definition: mixer.c:332
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: mixer.c:162
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct pcmwaveformat_tag PCMWAVEFORMAT
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
uint64_t DWORD64
Definition: typedefs.h:67
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
Definition: primary.c:437
#define S_FALSE
Definition: winerror.h:2357

Referenced by IDirectSoundBufferImpl_SetFormat(), and PrimaryBufferImpl_SetFormat().

◆ PrimaryBufferImpl_AddRef()

static ULONG WINAPI PrimaryBufferImpl_AddRef ( LPDIRECTSOUNDBUFFER  iface)
static

Definition at line 753 of file primary.c.

754{
757 TRACE("(%p) ref was %d\n", This, ref - 1);
758 if(ref == 1)
759 InterlockedIncrement(&This->numIfaces);
760 return ref;
761}
#define InterlockedIncrement
Definition: armddk.h:53
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ PrimaryBufferImpl_GetCaps()

static HRESULT WINAPI PrimaryBufferImpl_GetCaps ( LPDIRECTSOUNDBUFFER  iface,
LPDSBCAPS  caps 
)
static

Definition at line 1110 of file primary.c.

1112 {
1114 DirectSoundDevice *device = This->device;
1115 TRACE("(%p,%p)\n", iface, caps);
1116
1117 if (caps == NULL) {
1118 WARN("invalid parameter: caps == NULL\n");
1119 return DSERR_INVALIDPARAM;
1120 }
1121
1122 if (caps->dwSize < sizeof(*caps)) {
1123 WARN("invalid parameter: caps->dwSize = %d\n", caps->dwSize);
1124 return DSERR_INVALIDPARAM;
1125 }
1126
1127 caps->dwFlags = This->dsbd.dwFlags;
1128 caps->dwBufferBytes = device->buflen;
1129
1130 /* Windows reports these as zero */
1131 caps->dwUnlockTransferRate = 0;
1132 caps->dwPlayCpuOverhead = 0;
1133
1134 return DS_OK;
1135}
DWORD dwUnlockTransferRate
Definition: dsound.h:242
DWORD dwPlayCpuOverhead
Definition: dsound.h:243
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD dwFlags
Definition: dsound.h:240
DWORD dwSize
Definition: dsound.h:239

◆ PrimaryBufferImpl_GetCurrentPosition()

static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition ( LPDIRECTSOUNDBUFFER  iface,
LPDWORD  playpos,
LPDWORD  writepos 
)
static

Definition at line 781 of file primary.c.

783 {
786 DirectSoundDevice *device = This->device;
787 TRACE("(%p,%p,%p)\n", iface, playpos, writepos);
788
789 /* **** */
790 EnterCriticalSection(&(device->mixlock));
791
792 hres = DSOUND_PrimaryGetPosition(device, playpos, writepos);
793 if (hres != DS_OK) {
794 WARN("DSOUND_PrimaryGetPosition failed\n");
795 LeaveCriticalSection(&(device->mixlock));
796 return hres;
797 }
798 if (writepos) {
799 if (device->state != STATE_STOPPED)
800 /* apply the documented 10ms lead to writepos */
801 *writepos += device->writelead;
802 while (*writepos >= device->buflen) *writepos -= device->buflen;
803 }
804
805 LeaveCriticalSection(&(device->mixlock));
806 /* **** */
807
808 TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:0, writepos?*writepos:0, device, GetTickCount());
809 return DS_OK;
810}
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:402

◆ PrimaryBufferImpl_GetFormat()

static HRESULT WINAPI PrimaryBufferImpl_GetFormat ( LPDIRECTSOUNDBUFFER  iface,
LPWAVEFORMATEX  lpwf,
DWORD  wfsize,
LPDWORD  wfwritten 
)
static

Definition at line 834 of file primary.c.

839{
840 DWORD size;
842 DirectSoundDevice *device = This->device;
843 TRACE("(%p,%p,%d,%p)\n", iface, lpwf, wfsize, wfwritten);
844
845 size = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
846
847 if (lpwf) { /* NULL is valid */
848 if (wfsize >= size) {
849 CopyMemory(lpwf,device->pwfx,size);
850 if (wfwritten)
851 *wfwritten = size;
852 } else {
853 WARN("invalid parameter: wfsize too small\n");
854 if (wfwritten)
855 *wfwritten = 0;
856 return DSERR_INVALIDPARAM;
857 }
858 } else {
859 if (wfwritten)
860 *wfwritten = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
861 else {
862 WARN("invalid parameter: wfwritten == NULL\n");
863 return DSERR_INVALIDPARAM;
864 }
865 }
866
867 return DS_OK;
868}
if(dx< 0)
Definition: linetemp.h:194

◆ PrimaryBufferImpl_GetFrequency()

static HRESULT WINAPI PrimaryBufferImpl_GetFrequency ( LPDIRECTSOUNDBUFFER  iface,
LPDWORD  freq 
)
static

Definition at line 1079 of file primary.c.

1081 {
1083 DirectSoundDevice *device = This->device;
1084 TRACE("(%p,%p)\n", iface, freq);
1085
1086 if (freq == NULL) {
1087 WARN("invalid parameter: freq == NULL\n");
1088 return DSERR_INVALIDPARAM;
1089 }
1090
1091 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
1092 WARN("control unavailable\n");
1093 return DSERR_CONTROLUNAVAIL;
1094 }
1095
1096 *freq = device->pwfx->nSamplesPerSec;
1097 TRACE("-> %d\n", *freq);
1098
1099 return DS_OK;
1100}
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211

◆ PrimaryBufferImpl_GetPan()

static HRESULT WINAPI PrimaryBufferImpl_GetPan ( LPDIRECTSOUNDBUFFER  iface,
LPLONG  pan 
)
static

Definition at line 1013 of file primary.c.

1015 {
1017 DirectSoundDevice *device = This->device;
1018 DWORD ampfactors;
1019 TRACE("(%p,%p)\n", iface, pan);
1020
1021 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
1022 WARN("control unavailable\n");
1023 return DSERR_CONTROLUNAVAIL;
1024 }
1025
1026 if (pan == NULL) {
1027 WARN("invalid parameter: pan == NULL\n");
1028 return DSERR_INVALIDPARAM;
1029 }
1030
1031 if (!device->hwbuf)
1032 {
1033 waveOutGetVolume(device->hwo, &ampfactors);
1034 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
1035 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
1037 }
1038 *pan = device->volpan.lPan;
1039 return DS_OK;
1040}
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2485

◆ PrimaryBufferImpl_GetStatus()

static HRESULT WINAPI PrimaryBufferImpl_GetStatus ( LPDIRECTSOUNDBUFFER  iface,
LPDWORD  status 
)
static

Definition at line 812 of file primary.c.

814 {
816 DirectSoundDevice *device = This->device;
817 TRACE("(%p,%p)\n", iface, status);
818
819 if (status == NULL) {
820 WARN("invalid parameter: status == NULL\n");
821 return DSERR_INVALIDPARAM;
822 }
823
824 *status = 0;
825 if ((device->state == STATE_STARTING) ||
826 (device->state == STATE_PLAYING))
828
829 TRACE("status=%x\n", *status);
830 return DS_OK;
831}
#define DSBSTATUS_LOOPING
Definition: dsound.h:198
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
Definition: ps.c:97

◆ PrimaryBufferImpl_GetVolume()

static HRESULT WINAPI PrimaryBufferImpl_GetVolume ( LPDIRECTSOUNDBUFFER  iface,
LPLONG  vol 
)
static

Definition at line 667 of file primary.c.

669 {
671 DirectSoundDevice *device = This->device;
672 DWORD ampfactors;
673 TRACE("(%p,%p)\n", iface, vol);
674
675 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
676 WARN("control unavailable\n");
678 }
679
680 if (vol == NULL) {
681 WARN("invalid parameter: vol = NULL\n");
682 return DSERR_INVALIDPARAM;
683 }
684
685 if (!device->hwbuf)
686 {
687 waveOutGetVolume(device->hwo, &ampfactors);
688 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
689 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
691 }
692 *vol = device->volpan.lVolume;
693 return DS_OK;
694}
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213

◆ PrimaryBufferImpl_Initialize()

static HRESULT WINAPI PrimaryBufferImpl_Initialize ( LPDIRECTSOUNDBUFFER  iface,
LPDIRECTSOUND  dsound,
LPCDSBUFFERDESC  dbsd 
)
static

Definition at line 1102 of file primary.c.

1104 {
1106 WARN("(%p) already initialized\n", This);
1108}
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129

◆ PrimaryBufferImpl_Lock()

static HRESULT WINAPI PrimaryBufferImpl_Lock ( LPDIRECTSOUNDBUFFER  iface,
DWORD  writecursor,
DWORD  writebytes,
LPVOID lplpaudioptr1,
LPDWORD  audiobytes1,
LPVOID lplpaudioptr2,
LPDWORD  audiobytes2,
DWORD  flags 
)
static

Definition at line 870 of file primary.c.

872 {
875 DirectSoundDevice *device = This->device;
876 TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n",
877 iface,
878 writecursor,
879 writebytes,
880 lplpaudioptr1,
881 audiobytes1,
882 lplpaudioptr2,
883 audiobytes2,
884 flags,
886 );
887
888 if (!audiobytes1)
889 return DSERR_INVALIDPARAM;
890
891 if (device->priolevel != DSSCL_WRITEPRIMARY) {
892 WARN("failed priority check!\n");
894 }
895
896 /* when this flag is set, writecursor is meaningless and must be calculated */
898 /* GetCurrentPosition does too much magic to duplicate here */
899 hres = IDirectSoundBuffer_GetCurrentPosition(iface, NULL, &writecursor);
900 if (hres != DS_OK) {
901 WARN("IDirectSoundBuffer_GetCurrentPosition failed\n");
902 return hres;
903 }
904 }
905
906 /* when this flag is set, writebytes is meaningless and must be set */
908 writebytes = device->buflen;
909
910 if (writecursor >= device->buflen) {
911 WARN("Invalid parameter, writecursor: %u >= buflen: %u\n",
912 writecursor, device->buflen);
913 return DSERR_INVALIDPARAM;
914 }
915
916 if (writebytes > device->buflen) {
917 WARN("Invalid parameter, writebytes: %u > buflen: %u\n",
918 writebytes, device->buflen);
919 return DSERR_INVALIDPARAM;
920 }
921
922 if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
924 lplpaudioptr1, audiobytes1,
925 lplpaudioptr2, audiobytes2,
926 writecursor, writebytes,
927 0);
928 if (hres != DS_OK) {
929 WARN("IDsDriverBuffer_Lock failed\n");
930 return hres;
931 }
932 } else {
933 if (writecursor+writebytes <= device->buflen) {
934 *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
935 *audiobytes1 = writebytes;
936 if (lplpaudioptr2)
937 *(LPBYTE*)lplpaudioptr2 = NULL;
938 if (audiobytes2)
939 *audiobytes2 = 0;
940 TRACE("->%d.0\n",writebytes);
941 } else {
942 *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
943 *audiobytes1 = device->buflen-writecursor;
944 if (lplpaudioptr2)
945 *(LPBYTE*)lplpaudioptr2 = device->buffer;
946 if (audiobytes2)
947 *audiobytes2 = writebytes-(device->buflen-writecursor);
948 TRACE("->%d.%d\n",*audiobytes1,audiobytes2?*audiobytes2:0);
949 }
950 }
951 return DS_OK;
952}
#define DSDDESC_DONTNEEDPRIMARYLOCK
Definition: dsdriver.h:53
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
#define DSBLOCK_FROMWRITECURSOR
Definition: dsound.h:203

◆ PrimaryBufferImpl_Play()

static HRESULT WINAPI PrimaryBufferImpl_Play ( LPDIRECTSOUNDBUFFER  iface,
DWORD  reserved1,
DWORD  reserved2,
DWORD  flags 
)
static

Definition at line 707 of file primary.c.

709 {
711 DirectSoundDevice *device = This->device;
712 TRACE("(%p,%08x,%08x,%08x)\n", iface, reserved1, reserved2, flags);
713
714 if (!(flags & DSBPLAY_LOOPING)) {
715 WARN("invalid parameter: flags = %08x\n", flags);
716 return DSERR_INVALIDPARAM;
717 }
718
719 /* **** */
720 EnterCriticalSection(&(device->mixlock));
721
722 if (device->state == STATE_STOPPED)
723 device->state = STATE_STARTING;
724 else if (device->state == STATE_STOPPING)
725 device->state = STATE_PLAYING;
726
727 LeaveCriticalSection(&(device->mixlock));
728 /* **** */
729
730 return DS_OK;
731}
uint8_t reserved2[12]
Definition: fsck.fat.h:23

◆ PrimaryBufferImpl_QueryInterface()

static HRESULT WINAPI PrimaryBufferImpl_QueryInterface ( LPDIRECTSOUNDBUFFER  iface,
REFIID  riid,
LPVOID ppobj 
)
static

Definition at line 1137 of file primary.c.

1139 {
1141 DirectSoundDevice *device = This->device;
1142 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj);
1143
1144 if (ppobj == NULL) {
1145 WARN("invalid parameter\n");
1146 return E_INVALIDARG;
1147 }
1148
1149 *ppobj = NULL; /* assume failure */
1150
1151 if ( IsEqualGUID(riid, &IID_IUnknown) ||
1152 IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
1154 *ppobj = This;
1155 return S_OK;
1156 }
1157
1158 /* DirectSoundBuffer and DirectSoundBuffer8 are different and */
1159 /* a primary buffer can't have a DirectSoundBuffer8 interface */
1160 if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
1161 WARN("app requested DirectSoundBuffer8 on primary buffer\n");
1162 return E_NOINTERFACE;
1163 }
1164
1165 if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
1166 ERR("app requested IDirectSoundNotify on primary buffer\n");
1167 /* FIXME: should we support this? */
1168 return E_NOINTERFACE;
1169 }
1170
1171 if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
1172 ERR("app requested IDirectSound3DBuffer on primary buffer\n");
1173 return E_NOINTERFACE;
1174 }
1175
1176 if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
1177 if (!device->listener)
1179 if (device->listener) {
1180 *ppobj = device->listener;
1182 return S_OK;
1183 }
1184
1185 WARN("IID_IDirectSound3DListener failed\n");
1186 return E_NOINTERFACE;
1187 }
1188
1189 if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
1190 FIXME("app requested IKsPropertySet on primary buffer\n");
1191 return E_NOINTERFACE;
1192 }
1193
1194 FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
1195 return E_NOINTERFACE;
1196}
#define FIXME(fmt,...)
Definition: precomp.h:53
const GUID IID_IUnknown
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define IDirectSoundBuffer_AddRef(p)
Definition: dsound.h:573
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
struct IDirectSound3DListener * LPDIRECTSOUND3DLISTENER
Definition: dsound.h:86
#define IDirectSound3DListener_AddRef(p)
Definition: dsound.h:980
HRESULT IDirectSound3DListenerImpl_Create(DirectSoundDevice *device, IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN
Definition: sound3d.c:1034
REFIID riid
Definition: atlbase.h:39
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ PrimaryBufferImpl_Release()

static ULONG WINAPI PrimaryBufferImpl_Release ( LPDIRECTSOUNDBUFFER  iface)
static

Definition at line 770 of file primary.c.

771{
774 TRACE("(%p) ref was %d\n", This, ref + 1);
775
776 if (!ref && !InterlockedDecrement(&This->numIfaces))
778 return ref;
779}
#define InterlockedDecrement
Definition: armddk.h:52
void primarybuffer_destroy(IDirectSoundBufferImpl *This)
Definition: primary.c:763

◆ PrimaryBufferImpl_Restore()

static HRESULT WINAPI PrimaryBufferImpl_Restore ( LPDIRECTSOUNDBUFFER  iface)
static

Definition at line 1071 of file primary.c.

1073 {
1075 FIXME("(%p):stub\n",This);
1076 return DS_OK;
1077}

◆ PrimaryBufferImpl_SetCurrentPosition()

static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition ( LPDIRECTSOUNDBUFFER  iface,
DWORD  newpos 
)
static

Definition at line 954 of file primary.c.

956 {
958 TRACE("(%p,%d)\n",This,newpos);
959
960 /* You cannot set the position of the primary buffer */
961 WARN("invalid call\n");
962 return DSERR_INVALIDCALL;
963}
#define DSERR_INVALIDCALL
Definition: dsound.h:122

◆ PrimaryBufferImpl_SetFormat()

static HRESULT WINAPI PrimaryBufferImpl_SetFormat ( LPDIRECTSOUNDBUFFER  iface,
LPCWAVEFORMATEX  wfex 
)
static

Definition at line 613 of file primary.c.

616{
618 TRACE("(%p,%p)\n", iface, wfex);
619 return primarybuffer_SetFormat(This->device, wfex);
620}
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
Definition: primary.c:460

◆ PrimaryBufferImpl_SetFrequency()

static HRESULT WINAPI PrimaryBufferImpl_SetFrequency ( LPDIRECTSOUNDBUFFER  iface,
DWORD  freq 
)
static

Definition at line 696 of file primary.c.

698 {
700 TRACE("(%p,%d)\n",This,freq);
701
702 /* You cannot set the frequency of the primary buffer */
703 WARN("control unavailable\n");
705}

◆ PrimaryBufferImpl_SetPan()

static HRESULT WINAPI PrimaryBufferImpl_SetPan ( LPDIRECTSOUNDBUFFER  iface,
LONG  pan 
)
static

Definition at line 965 of file primary.c.

967 {
969 DirectSoundDevice *device = This->device;
970 DWORD ampfactors;
972 TRACE("(%p,%d)\n", iface, pan);
973
974 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
975 WARN("control unavailable\n");
977 }
978
979 if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
980 WARN("invalid parameter: pan = %d\n", pan);
981 return DSERR_INVALIDPARAM;
982 }
983
984 /* **** */
985 EnterCriticalSection(&(device->mixlock));
986
987 if (!device->hwbuf)
988 {
989 waveOutGetVolume(device->hwo, &ampfactors);
990 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
991 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
993 }
994 if (pan != device->volpan.lPan) {
995 device->volpan.lPan=pan;
996 DSOUND_RecalcVolPan(&device->volpan);
997 if (device->hwbuf) {
999 if (hres != DS_OK)
1000 WARN("IDsDriverBuffer_SetVolumePan failed\n");
1001 } else {
1002 ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
1003 waveOutSetVolume(device->hwo, ampfactors);
1004 }
1005 }
1006
1007 LeaveCriticalSection(&(device->mixlock));
1008 /* **** */
1009
1010 return hres;
1011}
#define DSBPAN_LEFT
Definition: dsound.h:226
#define DSBPAN_RIGHT
Definition: dsound.h:228
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2505

◆ PrimaryBufferImpl_SetVolume()

static HRESULT WINAPI PrimaryBufferImpl_SetVolume ( LPDIRECTSOUNDBUFFER  iface,
LONG  vol 
)
static

Definition at line 622 of file primary.c.

624 {
626 DirectSoundDevice *device = This->device;
627 DWORD ampfactors;
629 TRACE("(%p,%d)\n", iface, vol);
630
631 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
632 WARN("control unavailable\n");
634 }
635
636 if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {
637 WARN("invalid parameter: vol = %d\n", vol);
638 return DSERR_INVALIDPARAM;
639 }
640
641 /* **** */
642 EnterCriticalSection(&(device->mixlock));
643
644 waveOutGetVolume(device->hwo, &ampfactors);
645 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
646 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
648 if (vol != device->volpan.lVolume) {
649 device->volpan.lVolume=vol;
650 DSOUND_RecalcVolPan(&device->volpan);
651 if (device->hwbuf) {
653 if (hres != DS_OK)
654 WARN("IDsDriverBuffer_SetVolumePan failed\n");
655 } else {
656 ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
657 waveOutSetVolume(device->hwo, ampfactors);
658 }
659 }
660
661 LeaveCriticalSection(&(device->mixlock));
662 /* **** */
663
664 return hres;
665}
#define DSBVOLUME_MAX
Definition: dsound.h:229
#define DSBVOLUME_MIN
Definition: dsound.h:230

◆ PrimaryBufferImpl_Stop()

static HRESULT WINAPI PrimaryBufferImpl_Stop ( LPDIRECTSOUNDBUFFER  iface)
static

Definition at line 733 of file primary.c.

734{
736 DirectSoundDevice *device = This->device;
737 TRACE("(%p)\n", iface);
738
739 /* **** */
740 EnterCriticalSection(&(device->mixlock));
741
742 if (device->state == STATE_PLAYING)
743 device->state = STATE_STOPPING;
744 else if (device->state == STATE_STARTING)
745 device->state = STATE_STOPPED;
746
747 LeaveCriticalSection(&(device->mixlock));
748 /* **** */
749
750 return DS_OK;
751}

◆ PrimaryBufferImpl_Unlock()

static HRESULT WINAPI PrimaryBufferImpl_Unlock ( LPDIRECTSOUNDBUFFER  iface,
LPVOID  p1,
DWORD  x1,
LPVOID  p2,
DWORD  x2 
)
static

Definition at line 1042 of file primary.c.

1044 {
1046 DirectSoundDevice *device = This->device;
1047 TRACE("(%p,%p,%d,%p,%d)\n", iface, p1, x1, p2, x2);
1048
1049 if (device->priolevel != DSSCL_WRITEPRIMARY) {
1050 WARN("failed priority check!\n");
1051 return DSERR_PRIOLEVELNEEDED;
1052 }
1053
1054 if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
1055 HRESULT hres;
1056
1057 if ((char *)p1 - (char *)device->buffer + x1 > device->buflen)
1059 else
1060 hres = IDsDriverBuffer_Unlock(device->hwbuf, p1, x1, p2, x2);
1061
1062 if (hres != DS_OK) {
1063 WARN("IDsDriverBuffer_Unlock failed\n");
1064 return hres;
1065 }
1066 }
1067
1068 return DS_OK;
1069}
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708

Variable Documentation

◆ dspbvt

const IDirectSoundBufferVtbl dspbvt
static
Initial value:
=
{
}
static HRESULT WINAPI PrimaryBufferImpl_Unlock(LPDIRECTSOUNDBUFFER iface, LPVOID p1, DWORD x1, LPVOID p2, DWORD x2)
Definition: primary.c:1042
static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(LPDIRECTSOUNDBUFFER iface, LPDWORD freq)
Definition: primary.c:1079
static HRESULT WINAPI PrimaryBufferImpl_GetFormat(LPDIRECTSOUNDBUFFER iface, LPWAVEFORMATEX lpwf, DWORD wfsize, LPDWORD wfwritten)
Definition: primary.c:834
static HRESULT WINAPI PrimaryBufferImpl_GetVolume(LPDIRECTSOUNDBUFFER iface, LPLONG vol)
Definition: primary.c:667
static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(LPDIRECTSOUNDBUFFER iface, DWORD newpos)
Definition: primary.c:954
static HRESULT WINAPI PrimaryBufferImpl_Play(LPDIRECTSOUNDBUFFER iface, DWORD reserved1, DWORD reserved2, DWORD flags)
Definition: primary.c:707
static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(LPDIRECTSOUNDBUFFER iface, DWORD freq)
Definition: primary.c:696
static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:770
static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(LPDIRECTSOUNDBUFFER iface, REFIID riid, LPVOID *ppobj)
Definition: primary.c:1137
static HRESULT WINAPI PrimaryBufferImpl_SetPan(LPDIRECTSOUNDBUFFER iface, LONG pan)
Definition: primary.c:965
static HRESULT WINAPI PrimaryBufferImpl_SetFormat(LPDIRECTSOUNDBUFFER iface, LPCWAVEFORMATEX wfex)
Definition: primary.c:613
static HRESULT WINAPI PrimaryBufferImpl_GetCaps(LPDIRECTSOUNDBUFFER iface, LPDSBCAPS caps)
Definition: primary.c:1110
static HRESULT WINAPI PrimaryBufferImpl_Initialize(LPDIRECTSOUNDBUFFER iface, LPDIRECTSOUND dsound, LPCDSBUFFERDESC dbsd)
Definition: primary.c:1102
static HRESULT WINAPI PrimaryBufferImpl_SetVolume(LPDIRECTSOUNDBUFFER iface, LONG vol)
Definition: primary.c:622
static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:733
static HRESULT WINAPI PrimaryBufferImpl_GetStatus(LPDIRECTSOUNDBUFFER iface, LPDWORD status)
Definition: primary.c:812
static HRESULT WINAPI PrimaryBufferImpl_Lock(LPDIRECTSOUNDBUFFER iface, DWORD writecursor, DWORD writebytes, LPVOID *lplpaudioptr1, LPDWORD audiobytes1, LPVOID *lplpaudioptr2, LPDWORD audiobytes2, DWORD flags)
Definition: primary.c:870
static HRESULT WINAPI PrimaryBufferImpl_Restore(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:1071
static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:753
static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(LPDIRECTSOUNDBUFFER iface, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:781
static HRESULT WINAPI PrimaryBufferImpl_GetPan(LPDIRECTSOUNDBUFFER iface, LPLONG pan)
Definition: primary.c:1013

Definition at line 1198 of file primary.c.

Referenced by primarybuffer_create().