ReactOS  0.4.14-dev-317-g96040ec
primary.c
Go to the documentation of this file.
1 /* DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2002 TransGaming Technologies, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * TODO:
22  * When PrimarySetFormat (via ReopenDevice or PrimaryOpen) fails,
23  * it leaves dsound in unusable (not really open) state.
24  */
25 
26 #include "dsound_private.h"
27 
36 DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
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 }
57 
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 }
72 
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 }
135 
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 }
273 
274 
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 }
303 
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 }
320 
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 }
344 
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 }
362 
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 }
401 
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 }
428 
430 {
431  if (wfex->wFormatTag == WAVE_FORMAT_PCM)
432  return sizeof(WAVEFORMATEX);
433  else
434  return sizeof(WAVEFORMATEX) + wfex->cbSize;
435 }
436 
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 }
459 
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 }
601 
602 /*******************************************************************************
603  * PrimaryBuffer
604  */
605 static inline IDirectSoundBufferImpl *impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
606 {
607  /* IDirectSoundBuffer and IDirectSoundBuffer8 use the same iface. */
608  return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface);
609 }
610 
611 /* This sets this format for the <em>Primary Buffer Only</em> */
612 /* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
614  LPDIRECTSOUNDBUFFER iface,
615  LPCWAVEFORMATEX wfex)
616 {
618  TRACE("(%p,%p)\n", iface, wfex);
619  return primarybuffer_SetFormat(This->device, wfex);
620 }
621 
623  LPDIRECTSOUNDBUFFER iface,LONG vol
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 }
666 
668  LPDIRECTSOUNDBUFFER iface,LPLONG vol
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 }
695 
697  LPDIRECTSOUNDBUFFER iface,DWORD freq
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 }
706 
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 }
732 
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 }
752 
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 }
762 
764 {
765  This->device->primary = NULL;
767  TRACE("(%p) released\n", This);
768 }
769 
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 }
780 
782  LPDIRECTSOUNDBUFFER iface,LPDWORD playpos,LPDWORD writepos
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 }
811 
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 }
832 
833 
835  LPDIRECTSOUNDBUFFER iface,
836  LPWAVEFORMATEX lpwf,
837  DWORD wfsize,
838  LPDWORD wfwritten)
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 }
869 
871  LPDIRECTSOUNDBUFFER iface,DWORD writecursor,DWORD writebytes,LPVOID *lplpaudioptr1,LPDWORD audiobytes1,LPVOID *lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
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 }
953 
955  LPDIRECTSOUNDBUFFER iface,DWORD newpos
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 }
964 
966  LPDIRECTSOUNDBUFFER iface,LONG pan
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 }
1012 
1014  LPDIRECTSOUNDBUFFER iface,LPLONG pan
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 }
1041 
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 }
1070 
1072  LPDIRECTSOUNDBUFFER iface
1073 ) {
1075  FIXME("(%p):stub\n",This);
1076  return DS_OK;
1077 }
1078 
1080  LPDIRECTSOUNDBUFFER iface,LPDWORD freq
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 }
1101 
1104 ) {
1106  WARN("(%p) already initialized\n", This);
1107  return DSERR_ALREADYINITIALIZED;
1108 }
1109 
1111  LPDIRECTSOUNDBUFFER iface,LPDSBCAPS caps
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 }
1136 
1138  LPDIRECTSOUNDBUFFER iface,REFIID riid,LPVOID *ppobj
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 }
1197 
1198 static const IDirectSoundBufferVtbl dspbvt =
1199 {
1221 };
1222 
1224  const DSBUFFERDESC *dsbd)
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 WAVE_DIRECTSOUND
Definition: mmddk.h:478
const normfunc normfunctions[4]
int ds_snd_queue_min
Definition: dsound_main.c:75
static HRESULT WINAPI PrimaryBufferImpl_Play(LPDIRECTSOUNDBUFFER iface, DWORD reserved1, DWORD reserved2, DWORD flags)
Definition: primary.c:707
#define IDirectSoundBuffer_AddRef(p)
Definition: dsound.h:573
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
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
#define IDsDriver_Release(p)
Definition: dsdriver.h:157
#define DSERR_INVALIDCALL
Definition: dsound.h:122
static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:753
DWORD dwSize
Definition: dsound.h:239
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2541
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275
#define IDsDriverBuffer_Play(p, a, b, c)
Definition: dsdriver.h:203
REFIID riid
Definition: precomp.h:44
#define IDsDriver_Close(p)
Definition: dsdriver.h:161
static HRESULT WINAPI PrimaryBufferImpl_GetVolume(LPDIRECTSOUNDBUFFER iface, LPLONG vol)
Definition: primary.c:667
#define DSDDESC_DONTNEEDWRITELEAD
Definition: dsdriver.h:55
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice *device, DWORD pos) DECLSPEC_HIDDEN
Definition: mixer.c:84
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN
Definition: mixer.c:1011
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define STATE_PLAYING
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
static HRESULT WINAPI PrimaryBufferImpl_SetVolume(LPDIRECTSOUNDBUFFER iface, LONG vol)
Definition: primary.c:622
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
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
vector< Header * > headers
Definition: sdkparse.cpp:39
static const IDirectSoundBufferVtbl dspbvt
Definition: primary.c:1198
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
Definition: primary.c:304
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
Definition: primary.c:58
#define DSBVOLUME_MAX
Definition: dsound.h:229
struct pcmwaveformat_tag PCMWAVEFORMAT
#define DWORD
Definition: nt_native.h:44
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
#define DSERR_BUFFERLOST
Definition: dsound.h:131
Definition: send.c:47
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DSSCL_NORMAL
Definition: dsound.h:247
#define DSOUND_FREQSHIFT
#define DSDDESC_DOMMSYSTEMSETFORMAT
Definition: dsdriver.h:51
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
#define DSDDESC_DOMMSYSTEMOPEN
Definition: dsdriver.h:50
#define IDirectSound3DListener_AddRef(p)
Definition: dsound.h:980
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
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define WAVE_FORMAT_PCM
Definition: constants.h:425
unsigned char * LPBYTE
Definition: typedefs.h:52
static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(LPDIRECTSOUNDBUFFER iface, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:781
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
long LONG
Definition: pedump.c:60
Definition: devices.h:37
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: mixer.c:162
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static HRESULT WINAPI PrimaryBufferImpl_GetStatus(LPDIRECTSOUNDBUFFER iface, LPDWORD status)
Definition: primary.c:812
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(LPDIRECTSOUNDBUFFER iface, LPDWORD freq)
Definition: primary.c:1079
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2508
#define DS_HW_ACCEL_EMULATION
static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(LPDIRECTSOUNDBUFFER iface, DWORD newpos)
Definition: primary.c:954
#define IDsDriver_Open(p)
Definition: dsdriver.h:160
static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:770
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define STATE_STOPPED
static HRESULT WINAPI PrimaryBufferImpl_Unlock(LPDIRECTSOUNDBUFFER iface, LPVOID p1, DWORD x1, LPVOID p2, DWORD x2)
Definition: primary.c:1042
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
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 DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
#define DSBSTATUS_LOOPING
Definition: dsound.h:198
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
uint8_t reserved2[12]
Definition: fsck.fat.h:58
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define DSBLOCK_FROMWRITECURSOR
Definition: dsound.h:203
HRESULT IDirectSound3DListenerImpl_Create(DirectSoundDevice *device, IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN
Definition: sound3d.c:1034
static HRESULT WINAPI PrimaryBufferImpl_Restore(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:1071
#define DSBPLAY_LOOPING
Definition: dsound.h:189
if(!(yy_init))
Definition: macro.lex.yy.c:714
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
DWORD dwPlayCpuOverhead
Definition: dsound.h:243
static HRESULT WINAPI PrimaryBufferImpl_GetCaps(LPDIRECTSOUNDBUFFER iface, LPDSBCAPS caps)
Definition: primary.c:1110
LONG HRESULT
Definition: typedefs.h:77
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
DWORD dwFlags
Definition: dsound.h:240
const GUID IID_IUnknown
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
DWORD dwBufferBytes
Definition: dsound.h:241
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
#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
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
GLbitfield flags
Definition: glext.h:7161
#define DSBPAN_RIGHT
Definition: dsound.h:228
WORD wFormatTag
Definition: mmreg.h:78
#define IDsDriverBuffer_SetFormat(p, a)
Definition: dsdriver.h:198
#define STATE_STARTING
struct IDirectSound3DListener * LPDIRECTSOUND3DLISTENER
Definition: dsound.h:86
#define InterlockedDecrement
Definition: armddk.h:52
#define DSBVOLUME_MIN
Definition: dsound.h:230
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
#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
DirectSoundDevice * device
#define err(...)
uint32_t DWORD_PTR
Definition: typedefs.h:63
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(LPDIRECTSOUNDBUFFER iface, REFIID riid, LPVOID *ppobj)
Definition: primary.c:1137
#define ERR(fmt,...)
Definition: debug.h:109
int ds_hel_buflen
Definition: dsound_main.c:73
HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, const DSBUFFERDESC *dsbd)
Definition: primary.c:1223
#define S_OK
Definition: intsafe.h:59
int32_t * LPLONG
Definition: typedefs.h:56
#define IDsDriverBuffer_GetPosition(p, a, b)
Definition: dsdriver.h:202
#define InterlockedIncrement
Definition: armddk.h:53
uint64_t DWORD64
Definition: typedefs.h:65
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
Definition: primary.c:460
void primarybuffer_destroy(IDirectSoundBufferImpl *This)
Definition: primary.c:763
#define DSDDESC_DONTNEEDPRIMARYLOCK
Definition: dsdriver.h:53
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
Definition: primary.c:36
static HRESULT WINAPI PrimaryBufferImpl_SetFormat(LPDIRECTSOUNDBUFFER iface, LPCWAVEFORMATEX wfex)
Definition: primary.c:613
#define HeapReAlloc
Definition: compat.h:393
WORD cbSize
Definition: mmreg.h:84
static HRESULT WINAPI PrimaryBufferImpl_Initialize(LPDIRECTSOUNDBUFFER iface, LPDIRECTSOUND dsound, LPCDSBUFFERDESC dbsd)
Definition: primary.c:1102
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device)
Definition: primary.c:345
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define IDsDriver_GetDriverDesc(p, a)
Definition: dsdriver.h:159
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
int ds_snd_queue_max
Definition: dsound_main.c:74
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static HRESULT WINAPI PrimaryBufferImpl_GetPan(LPDIRECTSOUNDBUFFER iface, LPLONG pan)
Definition: primary.c:1013
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
IDirectSoundBuffer8 IDirectSoundBuffer8_iface
DWORD nSamplesPerSec
Definition: mmreg.h:80
struct IDirectSound * LPDIRECTSOUND
Definition: dsound.h:70
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2402
WORD nBlockAlign
Definition: mmreg.h:82
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device)
Definition: primary.c:363
uint32_t * LPDWORD
Definition: typedefs.h:57
WORD wBitsPerSample
Definition: mmreg.h:83
#define c
Definition: ke_i.h:80
DWORD dwUnlockTransferRate
Definition: dsound.h:242
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:402
unsigned int ULONG
Definition: retypes.h:1
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
Definition: primary.c:437
DWORD bpp
Definition: surface.c:181
#define IDsDriverBuffer_Stop(p)
Definition: dsdriver.h:204
#define STATE_STOPPING
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define DSBPAN_LEFT
Definition: dsound.h:226
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
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
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define HeapFree(x, y, z)
Definition: compat.h:394
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
Definition: primary.c:321
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27
int ds_hw_accel
Definition: dsound_main.c:77
Definition: ps.c:97
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)