ReactOS  0.4.14-dev-368-gfa26425
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 }
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define WAVE_FORMAT_PCM
Definition: constants.h:425
static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex)
Definition: primary.c:429
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
WORD wFormatTag
Definition: mmreg.h:78
WORD cbSize
Definition: mmreg.h:84
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83

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 }
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
#define WAVE_FORMAT_PCM
Definition: constants.h:425
WORD wFormatTag
Definition: mmreg.h:78
WORD cbSize
Definition: mmreg.h:84

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 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
Definition: devices.h:37
#define TRACE(s)
Definition: solgame.cpp:4
const GLubyte * c
Definition: glext.h:8905
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define ERR(fmt,...)
Definition: debug.h:109
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388

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 WARN(fmt,...)
Definition: debug.h:111
Definition: devices.h:37
#define STATE_STOPPED
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
Definition: primary.c:136
#define err(...)
int ds_hel_buflen
Definition: dsound_main.c:73

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 }
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define HeapFree(x, y, z)
Definition: compat.h:402

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 }
#define WARN(fmt,...)
Definition: debug.h:111
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
Definition: devices.h:37
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
#define err(...)
#define S_OK
Definition: intsafe.h:59
#define IDsDriverBuffer_GetPosition(p, a, b)
Definition: dsdriver.h:202

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)
167  IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
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 }
const normfunc normfunctions[4]
int ds_snd_queue_min
Definition: dsound_main.c:75
#define TRUE
Definition: types.h:120
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice *device, DWORD pos) DECLSPEC_HIDDEN
Definition: mixer.c:84
#define WARN(fmt,...)
Definition: debug.h:111
#define STATE_PLAYING
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
Definition: primary.c:73
#define IDsDriver_CreateSoundBuffer(p, a, b, c, d, e, f)
Definition: dsdriver.h:163
vector< Header * > headers
Definition: sdkparse.cpp:39
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
Definition: primary.c:58
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
unsigned char * LPBYTE
Definition: typedefs.h:52
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define STATE_STOPPED
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
LONG HRESULT
Definition: typedefs.h:77
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
#define STATE_STARTING
const mixfunc mixfunctions[4]
#define err(...)
uint32_t DWORD_PTR
Definition: typedefs.h:63
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define ERR(fmt,...)
Definition: debug.h:109
int ds_hel_buflen
Definition: dsound_main.c:73
#define HeapReAlloc
Definition: compat.h:401
int ds_snd_queue_max
Definition: dsound_main.c:74
#define c
Definition: ke_i.h:80
#define STATE_STOPPING
#define HeapFree(x, y, z)
Definition: compat.h:402

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 {
355  err = mmErr(waveOutRestart(device->hwo));
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 WARN(fmt,...)
Definition: debug.h:111
Definition: devices.h:37
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSBPLAY_LOOPING
Definition: dsound.h:189
LONG HRESULT
Definition: typedefs.h:77
#define err(...)
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2402

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) {
369  err = IDsDriverBuffer_Stop(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 }
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275
#define WARN(fmt,...)
Definition: debug.h:111
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
Definition: primary.c:73
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define DSERR_BUFFERLOST
Definition: dsound.h:131
Definition: devices.h:37
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
LONG HRESULT
Definition: typedefs.h:77
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
Definition: primary.c:136
#define err(...)
#define ERR(fmt,...)
Definition: debug.h:109
#define IDsDriverBuffer_Stop(p)
Definition: dsdriver.h:204
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

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
Definition: devices.h:37
#define TRACE(s)
Definition: solgame.cpp:4
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 {
75  HRESULT hres = DS_OK;
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);
83  IDsDriver_Release(device->driver);
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 WAVE_DIRECTSOUND
Definition: mmddk.h:478
#define IDsDriver_Release(p)
Definition: dsdriver.h:157
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2541
#define IDsDriver_Close(p)
Definition: dsdriver.h:161
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN
Definition: mixer.c:1011
#define WARN(fmt,...)
Definition: debug.h:111
#define DSDDESC_DOMMSYSTEMSETFORMAT
Definition: dsdriver.h:51
#define DSDDESC_DOMMSYSTEMOPEN
Definition: dsdriver.h:50
Definition: devices.h:37
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
smooth NULL
Definition: ftsmooth.c:416
#define DS_HW_ACCEL_EMULATION
#define IDsDriver_Open(p)
Definition: dsdriver.h:160
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
uint32_t DWORD_PTR
Definition: typedefs.h:63
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define IDsDriver_GetDriverDesc(p, a)
Definition: dsdriver.h:159
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
int ds_hw_accel
Definition: dsound_main.c:77

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

◆ impl_from_IDirectSoundBuffer()

static IDirectSoundBufferImpl* impl_from_IDirectSoundBuffer ( IDirectSoundBuffer *  iface)
inlinestatic

◆ 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 WARN(fmt,...)
Definition: debug.h:111
static const IDirectSoundBufferVtbl dspbvt
Definition: primary.c:1198
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
DirectSoundDevice * device
#define S_OK
Definition: intsafe.h:59
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
IDirectSoundBuffer8 IDirectSoundBuffer8_iface

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 }
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
#define HeapFree(x, y, z)
Definition: compat.h:402

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");
472  return DSERR_PRIOLEVELNEEDED;
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) {
504  err = IDsDriverBuffer_SetFormat(device->hwbuf, device->pwfx);
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)) {
516  DWORD size = DSOUND_GetFormatSize(oldpwfx);
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 
593 done:
594  LeaveCriticalSection(&(device->mixlock));
595  RtlReleaseResource(&(device->buffer_list_lock));
596  /* **** */
597 
598  HeapFree(GetProcessHeap(), 0, oldpwfx);
599  return err;
600 }
const normfunc normfunctions[4]
#define TRUE
Definition: types.h:120
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice *device, DWORD pos) DECLSPEC_HIDDEN
Definition: mixer.c:84
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define STATE_PLAYING
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
Definition: primary.c:73
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
Definition: primary.c:58
struct pcmwaveformat_tag PCMWAVEFORMAT
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
#define DSERR_BUFFERLOST
Definition: dsound.h:131
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DSSCL_NORMAL
Definition: dsound.h:247
#define DSOUND_FREQSHIFT
#define DSDDESC_DOMMSYSTEMSETFORMAT
Definition: dsdriver.h:51
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
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define WAVE_FORMAT_PCM
Definition: constants.h:425
static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex)
Definition: primary.c:429
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: mixer.c:162
#define S_FALSE
Definition: winerror.h:2357
smooth NULL
Definition: ftsmooth.c:416
#define STATE_STOPPED
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:403
LONG HRESULT
Definition: typedefs.h:77
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
Definition: primary.c:136
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
WORD wFormatTag
Definition: mmreg.h:78
#define IDsDriverBuffer_SetFormat(p, a)
Definition: dsdriver.h:198
#define STATE_STARTING
#define DSERR_BADFORMAT
Definition: dsound.h:126
const mixfunc mixfunctions[4]
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN
Definition: mixer.c:332
#define err(...)
uint64_t DWORD64
Definition: typedefs.h:65
#define HeapReAlloc
Definition: compat.h:401
WORD cbSize
Definition: mmreg.h:84
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
Definition: primary.c:437
DWORD bpp
Definition: surface.c:181
#define STATE_STOPPING
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define HeapFree(x, y, z)
Definition: compat.h:402
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

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 {
756  ULONG ref = InterlockedIncrement(&(This->ref));
757  TRACE("(%p) ref was %d\n", This, ref - 1);
758  if(ref == 1)
759  InterlockedIncrement(&This->numIfaces);
760  return ref;
761 }
Definition: send.c:47
GLenum GLint ref
Definition: glext.h:6028
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedIncrement
Definition: armddk.h:53
unsigned int ULONG
Definition: retypes.h:1
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 dwSize
Definition: dsound.h:239
#define WARN(fmt,...)
Definition: debug.h:111
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwPlayCpuOverhead
Definition: dsound.h:243
DWORD dwFlags
Definition: dsound.h:240
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD dwUnlockTransferRate
Definition: dsound.h:242
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ PrimaryBufferImpl_GetCurrentPosition()

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

Definition at line 781 of file primary.c.

783  {
784  HRESULT hres;
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 }
#define WARN(fmt,...)
Definition: debug.h:111
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
Definition: devices.h:37
#define STATE_STOPPED
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:402
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 }
#define WARN(fmt,...)
Definition: debug.h:111
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 WARN(fmt,...)
Definition: debug.h:111
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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;
1036  DSOUND_AmpFactorToVolPan(&device->volpan);
1037  }
1038  *pan = device->volpan.lPan;
1039  return DS_OK;
1040 }
#define WARN(fmt,...)
Definition: debug.h:111
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
unsigned long DWORD
Definition: ntddk_ex.h:95
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 WARN(fmt,...)
Definition: debug.h:111
#define STATE_PLAYING
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSBSTATUS_LOOPING
Definition: dsound.h:198
#define STATE_STARTING
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
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");
677  return DSERR_CONTROLUNAVAIL;
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
#define WARN(fmt,...)
Definition: debug.h:111
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
unsigned long DWORD
Definition: ntddk_ex.h:95
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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);
1107  return DSERR_ALREADYINITIALIZED;
1108 }
#define WARN(fmt,...)
Definition: debug.h:111
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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  {
873  HRESULT hres;
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,
885  GetTickCount()
886  );
887 
888  if (!audiobytes1)
889  return DSERR_INVALIDPARAM;
890 
891  if (device->priolevel != DSSCL_WRITEPRIMARY) {
892  WARN("failed priority check!\n");
893  return DSERR_PRIOLEVELNEEDED;
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 WARN(fmt,...)
Definition: debug.h:111
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
unsigned char * LPBYTE
Definition: typedefs.h:52
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
smooth NULL
Definition: ftsmooth.c:416
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
#define DSBLOCK_FROMWRITECURSOR
Definition: dsound.h:203
if(!(yy_init))
Definition: macro.lex.yy.c:714
LONG HRESULT
Definition: typedefs.h:77
GLbitfield flags
Definition: glext.h:7161
#define DSDDESC_DONTNEEDPRIMARYLOCK
Definition: dsdriver.h:53
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204

◆ 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 }
#define WARN(fmt,...)
Definition: debug.h:111
#define STATE_PLAYING
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
#define STATE_STOPPED
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
uint8_t reserved2[12]
Definition: fsck.fat.h:58
#define DSBPLAY_LOOPING
Definition: dsound.h:189
GLbitfield flags
Definition: glext.h:7161
#define STATE_STARTING
#define STATE_STOPPING
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 IDirectSoundBuffer_AddRef(p)
Definition: dsound.h:573
#define E_NOINTERFACE
Definition: winerror.h:2364
REFIID riid
Definition: precomp.h:44
#define WARN(fmt,...)
Definition: debug.h:111
#define IDirectSound3DListener_AddRef(p)
Definition: dsound.h:980
Definition: devices.h:37
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define debugstr_guid
Definition: kernel32.h:35
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT IDirectSound3DListenerImpl_Create(DirectSoundDevice *device, IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN
Definition: sound3d.c:1034
const GUID IID_IUnknown
struct IDirectSound3DListener * LPDIRECTSOUND3DLISTENER
Definition: dsound.h:86
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ PrimaryBufferImpl_Release()

static ULONG WINAPI PrimaryBufferImpl_Release ( LPDIRECTSOUNDBUFFER  iface)
static

Definition at line 770 of file primary.c.

771 {
773  DWORD ref = InterlockedDecrement(&(This->ref));
774  TRACE("(%p) ref was %d\n", This, ref + 1);
775 
776  if (!ref && !InterlockedDecrement(&This->numIfaces))
778  return ref;
779 }
Definition: send.c:47
GLenum GLint ref
Definition: glext.h:6028
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
#define InterlockedDecrement
Definition: armddk.h:52
void primarybuffer_destroy(IDirectSoundBufferImpl *This)
Definition: primary.c:763
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 }
#define FIXME(fmt,...)
Definition: debug.h:110
#define DS_OK
Definition: dsound.h:116
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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
#define WARN(fmt,...)
Definition: debug.h:111
#define TRACE(s)
Definition: solgame.cpp:4
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 }
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
Definition: primary.c:460
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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");
704  return DSERR_CONTROLUNAVAIL;
705 }
#define WARN(fmt,...)
Definition: debug.h:111
#define TRACE(s)
Definition: solgame.cpp:4
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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;
971  HRESULT hres = DS_OK;
972  TRACE("(%p,%d)\n", iface, pan);
973 
974  if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
975  WARN("control unavailable\n");
976  return DSERR_CONTROLUNAVAIL;
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) {
998  hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
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 WARN(fmt,...)
Definition: debug.h:111
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2508
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DSBPAN_RIGHT
Definition: dsound.h:228
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define DSBPAN_LEFT
Definition: dsound.h:226
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27

◆ 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;
628  HRESULT hres = DS_OK;
629  TRACE("(%p,%d)\n", iface, vol);
630 
631  if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
632  WARN("control unavailable\n");
633  return DSERR_CONTROLUNAVAIL;
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) {
652  hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
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 DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
#define WARN(fmt,...)
Definition: debug.h:111
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define DSBVOLUME_MAX
Definition: dsound.h:229
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2508
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DSBVOLUME_MIN
Definition: dsound.h:230
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27

◆ 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 }
#define STATE_PLAYING
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
Definition: devices.h:37
#define STATE_STOPPED
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define STATE_STARTING
#define STATE_STOPPING
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

◆ 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 }
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define WARN(fmt,...)
Definition: debug.h:111
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
Definition: devices.h:37
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define DSDDESC_DONTNEEDPRIMARYLOCK
Definition: dsdriver.h:53
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605

Variable Documentation

◆ dspbvt

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

Definition at line 1198 of file primary.c.

Referenced by primarybuffer_create().