ReactOS 0.4.15-dev-8002-gbbb3b00
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
36DWORD 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{
76 TRACE("(%p, %d)\n", device, forcewave);
77
78 if (device->driver)
79 {
80 IDsDriver_Close(device->driver);
81 if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
82 waveOutClose(device->hwo);
84 device->driver = NULL;
85 device->buffer = NULL;
86 device->hwo = 0;
87 }
88 else if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
89 waveOutClose(device->hwo);
90
91 /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
92 if (ds_hw_accel != DS_HW_ACCEL_EMULATION && !forcewave)
93 waveOutMessage((HWAVEOUT)(DWORD_PTR)device->drvdesc.dnDevNode, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0);
94
95 /* Get driver description */
96 if (device->driver) {
97 DWORD wod = device->drvdesc.dnDevNode;
98 hres = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc));
99 device->drvdesc.dnDevNode = wod;
100 if (FAILED(hres)) {
101 WARN("IDsDriver_GetDriverDesc failed: %08x\n", hres);
102 IDsDriver_Release(device->driver);
103 device->driver = NULL;
104 }
105 }
106
107 /* if no DirectSound interface available, use WINMM API instead */
108 if (!device->driver)
110
111 if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
112 {
114
115 if (device->driver)
117
118 hres = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD_PTR)device, flags));
119 if (FAILED(hres)) {
120 WARN("waveOutOpen failed\n");
121 if (device->driver)
122 {
123 IDsDriver_Release(device->driver);
124 device->driver = NULL;
125 }
126 return hres;
127 }
128 }
129
130 if (device->driver)
131 hres = IDsDriver_Open(device->driver);
132
133 return hres;
134}
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)
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 {
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) {
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");
473 }
474
475 /* Let's be pedantic! */
476 if (wfex == NULL) {
477 WARN("invalid parameter: wfex==NULL!\n");
478 return DSERR_INVALIDPARAM;
479 }
480 TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
481 "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
482 wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
483 wfex->nAvgBytesPerSec, wfex->nBlockAlign,
484 wfex->wBitsPerSample, wfex->cbSize);
485
486 /* **** */
487 RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
488 EnterCriticalSection(&(device->mixlock));
489
490 nSamplesPerSec = device->pwfx->nSamplesPerSec;
491 bpp = device->pwfx->wBitsPerSample;
492 chans = device->pwfx->nChannels;
493
494 oldpwfx = device->pwfx;
495 device->pwfx = DSOUND_CopyFormat(wfex);
496 if (device->pwfx == NULL) {
497 device->pwfx = oldpwfx;
498 oldpwfx = NULL;
500 goto done;
501 }
502
503 if (!(device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) && device->hwbuf) {
505
506 /* On bad format, try to re-create, big chance it will work then, only do this if we <HAVE> to */
507 if (forced && (device->pwfx->nSamplesPerSec/100 != wfex->nSamplesPerSec/100 || err == DSERR_BADFORMAT))
508 {
509 DWORD cp_size = wfex->wFormatTag == WAVE_FORMAT_PCM ?
510 sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX) + wfex->cbSize;
512 CopyMemory(device->pwfx, wfex, cp_size);
513 }
514
515 if (err != DSERR_BUFFERLOST && FAILED(err)) {
517 WARN("IDsDriverBuffer_SetFormat failed\n");
518 if (!forced) {
519 CopyMemory(device->pwfx, oldpwfx, size);
520 err = DS_OK;
521 }
522 goto done;
523 }
524
525 if (err == S_FALSE)
526 {
527 /* ALSA specific: S_FALSE tells that recreation was successful,
528 * but size and location may be changed, and buffer has to be restarted
529 * I put it here, so if frequency doesn't match the error will be changed to DSERR_BUFFERLOST
530 * and the entire re-initialization will occur anyway
531 */
532 IDsDriverBuffer_Lock(device->hwbuf, (LPVOID *)&device->buffer, &device->buflen, NULL, NULL, 0, 0, DSBLOCK_ENTIREBUFFER);
533 IDsDriverBuffer_Unlock(device->hwbuf, device->buffer, 0, NULL, 0);
534
535 if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
536 else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
537 device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
538 err = DS_OK;
539 }
541 }
542
543 if (err == DSERR_BUFFERLOST)
544 {
546
548 if (FAILED(err))
549 {
550 WARN("DSOUND_ReopenDevice failed: %08x\n", err);
551 goto done;
552 }
554 if (err != DS_OK) {
555 WARN("DSOUND_PrimaryOpen failed\n");
556 goto done;
557 }
558
559 if (wfex->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
560 {
562 device->pwfx->nSamplesPerSec = wfex->nSamplesPerSec;
564 if (FAILED(err))
565 WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
566 else if (FAILED((err = DSOUND_PrimaryOpen(device))))
567 WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
568 }
569 }
570
571 device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
572 device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
573 FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
574 device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
575 device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
576
577 if (nSamplesPerSec != device->pwfx->nSamplesPerSec || bpp != device->pwfx->wBitsPerSample || chans != device->pwfx->nChannels) {
578 IDirectSoundBufferImpl** dsb = device->buffers;
579 for (i = 0; i < device->nrofbuffers; i++, dsb++) {
580 /* **** */
581 RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);
582
583 (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
584 DSOUND_RecalcFormat((*dsb));
585 DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
586 (*dsb)->primary_mixpos = 0;
587
588 RtlReleaseResource(&(*dsb)->lock);
589 /* **** */
590 }
591 }
592
593done:
594 LeaveCriticalSection(&(device->mixlock));
595 RtlReleaseResource(&(device->buffer_list_lock));
596 /* **** */
597
598 HeapFree(GetProcessHeap(), 0, oldpwfx);
599 return err;
600}
601
602/*******************************************************************************
603 * PrimaryBuffer
604 */
605static 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 */
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;
629 TRACE("(%p,%d)\n", iface, vol);
630
631 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
632 WARN("control unavailable\n");
634 }
635
636 if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {
637 WARN("invalid parameter: vol = %d\n", vol);
638 return DSERR_INVALIDPARAM;
639 }
640
641 /* **** */
642 EnterCriticalSection(&(device->mixlock));
643
644 waveOutGetVolume(device->hwo, &ampfactors);
645 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
646 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
648 if (vol != device->volpan.lVolume) {
649 device->volpan.lVolume=vol;
650 DSOUND_RecalcVolPan(&device->volpan);
651 if (device->hwbuf) {
653 if (hres != DS_OK)
654 WARN("IDsDriverBuffer_SetVolumePan failed\n");
655 } else {
656 ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
657 waveOutSetVolume(device->hwo, ampfactors);
658 }
659 }
660
661 LeaveCriticalSection(&(device->mixlock));
662 /* **** */
663
664 return hres;
665}
666
669) {
671 DirectSoundDevice *device = This->device;
672 DWORD ampfactors;
673 TRACE("(%p,%p)\n", iface, vol);
674
675 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
676 WARN("control unavailable\n");
678 }
679
680 if (vol == NULL) {
681 WARN("invalid parameter: vol = NULL\n");
682 return DSERR_INVALIDPARAM;
683 }
684
685 if (!device->hwbuf)
686 {
687 waveOutGetVolume(device->hwo, &ampfactors);
688 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
689 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
691 }
692 *vol = device->volpan.lVolume;
693 return DS_OK;
694}
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");
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{
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{
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) {
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
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) {
875 DirectSoundDevice *device = This->device;
876 TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n",
877 iface,
878 writecursor,
879 writebytes,
880 lplpaudioptr1,
881 audiobytes1,
882 lplpaudioptr2,
883 audiobytes2,
884 flags,
886 );
887
888 if (!audiobytes1)
889 return DSERR_INVALIDPARAM;
890
891 if (device->priolevel != DSSCL_WRITEPRIMARY) {
892 WARN("failed priority check!\n");
894 }
895
896 /* when this flag is set, writecursor is meaningless and must be calculated */
898 /* GetCurrentPosition does too much magic to duplicate here */
899 hres = IDirectSoundBuffer_GetCurrentPosition(iface, NULL, &writecursor);
900 if (hres != DS_OK) {
901 WARN("IDirectSoundBuffer_GetCurrentPosition failed\n");
902 return hres;
903 }
904 }
905
906 /* when this flag is set, writebytes is meaningless and must be set */
908 writebytes = device->buflen;
909
910 if (writecursor >= device->buflen) {
911 WARN("Invalid parameter, writecursor: %u >= buflen: %u\n",
912 writecursor, device->buflen);
913 return DSERR_INVALIDPARAM;
914 }
915
916 if (writebytes > device->buflen) {
917 WARN("Invalid parameter, writebytes: %u > buflen: %u\n",
918 writebytes, device->buflen);
919 return DSERR_INVALIDPARAM;
920 }
921
922 if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
924 lplpaudioptr1, audiobytes1,
925 lplpaudioptr2, audiobytes2,
926 writecursor, writebytes,
927 0);
928 if (hres != DS_OK) {
929 WARN("IDsDriverBuffer_Lock failed\n");
930 return hres;
931 }
932 } else {
933 if (writecursor+writebytes <= device->buflen) {
934 *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
935 *audiobytes1 = writebytes;
936 if (lplpaudioptr2)
937 *(LPBYTE*)lplpaudioptr2 = NULL;
938 if (audiobytes2)
939 *audiobytes2 = 0;
940 TRACE("->%d.0\n",writebytes);
941 } else {
942 *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
943 *audiobytes1 = device->buflen-writecursor;
944 if (lplpaudioptr2)
945 *(LPBYTE*)lplpaudioptr2 = device->buffer;
946 if (audiobytes2)
947 *audiobytes2 = writebytes-(device->buflen-writecursor);
948 TRACE("->%d.%d\n",*audiobytes1,audiobytes2?*audiobytes2:0);
949 }
950 }
951 return DS_OK;
952}
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;
972 TRACE("(%p,%d)\n", iface, pan);
973
974 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
975 WARN("control unavailable\n");
977 }
978
979 if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
980 WARN("invalid parameter: pan = %d\n", pan);
981 return DSERR_INVALIDPARAM;
982 }
983
984 /* **** */
985 EnterCriticalSection(&(device->mixlock));
986
987 if (!device->hwbuf)
988 {
989 waveOutGetVolume(device->hwo, &ampfactors);
990 device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
991 device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
993 }
994 if (pan != device->volpan.lPan) {
995 device->volpan.lPan=pan;
996 DSOUND_RecalcVolPan(&device->volpan);
997 if (device->hwbuf) {
999 if (hres != DS_OK)
1000 WARN("IDsDriverBuffer_SetVolumePan failed\n");
1001 } else {
1002 ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
1003 waveOutSetVolume(device->hwo, ampfactors);
1004 }
1005 }
1006
1007 LeaveCriticalSection(&(device->mixlock));
1008 /* **** */
1009
1010 return hres;
1011}
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;
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
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);
1108}
1109
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
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
1198static 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 InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WAVE_FORMAT_PCM
Definition: constants.h:425
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define IDsDriverBuffer_Stop(p)
Definition: dsdriver.h:204
#define IDsDriverBuffer_SetFormat(p, a)
Definition: dsdriver.h:198
#define IDsDriver_CreateSoundBuffer(p, a, b, c, d, e, f)
Definition: dsdriver.h:163
#define IDsDriverBuffer_Play(p, a, b, c)
Definition: dsdriver.h:203
#define IDsDriver_Close(p)
Definition: dsdriver.h:161
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
#define DSDDESC_DONTNEEDPRIMARYLOCK
Definition: dsdriver.h:53
#define DSDDESC_DONTNEEDWRITELEAD
Definition: dsdriver.h:55
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
#define DSDDESC_DOMMSYSTEMOPEN
Definition: dsdriver.h:50
#define IDsDriver_GetDriverDesc(p, a)
Definition: dsdriver.h:159
#define IDsDriver_Open(p)
Definition: dsdriver.h:160
#define DSDDESC_DOMMSYSTEMSETFORMAT
Definition: dsdriver.h:51
#define IDsDriverBuffer_GetPosition(p, a, b)
Definition: dsdriver.h:202
#define IDsDriver_Release(p)
Definition: dsdriver.h:157
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
#define DSERR_BADFORMAT
Definition: dsound.h:126
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
#define IDirectSoundBuffer_AddRef(p)
Definition: dsound.h:573
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define DSBPAN_LEFT
Definition: dsound.h:226
#define DSBLOCK_FROMWRITECURSOR
Definition: dsound.h:203
#define DSBSTATUS_LOOPING
Definition: dsound.h:198
#define DSBVOLUME_MAX
Definition: dsound.h:229
#define DSSCL_NORMAL
Definition: dsound.h:247
struct IDirectSound3DListener * LPDIRECTSOUND3DLISTENER
Definition: dsound.h:86
#define DSERR_INVALIDCALL
Definition: dsound.h:122
#define DSSCL_WRITEPRIMARY
Definition: dsound.h:250
struct IDirectSound * LPDIRECTSOUND
Definition: dsound.h:70
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
#define DS_OK
Definition: dsound.h:116
#define DSBVOLUME_MIN
Definition: dsound.h:230
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
#define DSBPLAY_LOOPING
Definition: dsound.h:189
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define IDirectSound3DListener_AddRef(p)
Definition: dsound.h:980
#define DSERR_BUFFERLOST
Definition: dsound.h:131
#define DSBPAN_RIGHT
Definition: dsound.h:228
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
const mixfunc mixfunctions[4]
const normfunc normfunctions[4]
int ds_snd_queue_min
Definition: dsound_main.c:76
int ds_hw_accel
Definition: dsound_main.c:78
HRESULT mmErr(UINT err)
Definition: dsound_main.c:44
int ds_snd_queue_max
Definition: dsound_main.c:75
int ds_hel_buflen
Definition: dsound_main.c:74
#define STATE_STOPPING
#define STATE_PLAYING
#define STATE_STARTING
DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice *device, DWORD pos) DECLSPEC_HIDDEN
Definition: mixer.c:84
#define STATE_STOPPED
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:46
#define DSOUND_FREQSHIFT
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN
Definition: mixer.c:1011
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN
Definition: mixer.c:332
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27
HRESULT IDirectSound3DListenerImpl_Create(DirectSoundDevice *device, IDirectSound3DListenerImpl **pdsl) DECLSPEC_HIDDEN
Definition: sound3d.c:1034
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: mixer.c:162
#define DS_HW_ACCEL_EMULATION
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint8_t reserved2[12]
Definition: fsck.fat.h:23
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
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
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
if(dx< 0)
Definition: linetemp.h:194
struct pcmwaveformat_tag PCMWAVEFORMAT
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
HRESULT hres
Definition: protocol.c:465
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define err(...)
#define WAVE_DIRECTSOUND
Definition: mmddk.h:482
vector< Header * > headers
Definition: sdkparse.cpp:39
#define TRACE(s)
Definition: solgame.cpp:4
DirectSoundDevice * device
IDirectSoundBuffer8 IDirectSoundBuffer8_iface
DWORD dwUnlockTransferRate
Definition: dsound.h:242
DWORD dwPlayCpuOverhead
Definition: dsound.h:243
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD dwFlags
Definition: dsound.h:240
DWORD dwSize
Definition: dsound.h:239
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
Definition: devices.h:37
Definition: send.c:48
Definition: ps.c:97
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t DWORD64
Definition: typedefs.h:67
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t * LPLONG
Definition: typedefs.h:58
uint32_t * LPDWORD
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define CopyMemory
Definition: winbase.h:1710
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
#define WINAPI
Definition: msvc.h:6
static HRESULT WINAPI PrimaryBufferImpl_Unlock(LPDIRECTSOUNDBUFFER iface, LPVOID p1, DWORD x1, LPVOID p2, DWORD x2)
Definition: primary.c:1042
static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(LPDIRECTSOUNDBUFFER iface, LPDWORD freq)
Definition: primary.c:1079
static HRESULT WINAPI PrimaryBufferImpl_GetFormat(LPDIRECTSOUNDBUFFER iface, LPWAVEFORMATEX lpwf, DWORD wfsize, LPDWORD wfwritten)
Definition: primary.c:834
static const IDirectSoundBufferVtbl dspbvt
Definition: primary.c:1198
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
Definition: primary.c:605
static HRESULT WINAPI PrimaryBufferImpl_GetVolume(LPDIRECTSOUNDBUFFER iface, LPLONG vol)
Definition: primary.c:667
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device)
Definition: primary.c:345
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
Definition: primary.c:460
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
Definition: primary.c:437
void primarybuffer_destroy(IDirectSoundBufferImpl *This)
Definition: primary.c:763
static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(LPDIRECTSOUNDBUFFER iface, DWORD newpos)
Definition: primary.c:954
static HRESULT WINAPI PrimaryBufferImpl_Play(LPDIRECTSOUNDBUFFER iface, DWORD reserved1, DWORD reserved2, DWORD flags)
Definition: primary.c:707
static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(LPDIRECTSOUNDBUFFER iface, DWORD freq)
Definition: primary.c:696
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device)
Definition: primary.c:363
static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:770
static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(LPDIRECTSOUNDBUFFER iface, REFIID riid, LPVOID *ppobj)
Definition: primary.c:1137
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
Definition: primary.c:275
static HRESULT WINAPI PrimaryBufferImpl_SetPan(LPDIRECTSOUNDBUFFER iface, LONG pan)
Definition: primary.c:965
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
Definition: primary.c:36
static HRESULT WINAPI PrimaryBufferImpl_SetFormat(LPDIRECTSOUNDBUFFER iface, LPCWAVEFORMATEX wfex)
Definition: primary.c:613
static HRESULT WINAPI PrimaryBufferImpl_GetCaps(LPDIRECTSOUNDBUFFER iface, LPDSBCAPS caps)
Definition: primary.c:1110
static HRESULT WINAPI PrimaryBufferImpl_Initialize(LPDIRECTSOUNDBUFFER iface, LPDIRECTSOUND dsound, LPCDSBUFFERDESC dbsd)
Definition: primary.c:1102
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:402
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
Definition: primary.c:321
static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex)
Definition: primary.c:429
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
Definition: primary.c:58
static HRESULT WINAPI PrimaryBufferImpl_SetVolume(LPDIRECTSOUNDBUFFER iface, LONG vol)
Definition: primary.c:622
static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:733
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
Definition: primary.c:136
static HRESULT WINAPI PrimaryBufferImpl_GetStatus(LPDIRECTSOUNDBUFFER iface, LPDWORD status)
Definition: primary.c:812
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
Definition: primary.c:73
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
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
Definition: primary.c:304
static HRESULT WINAPI PrimaryBufferImpl_Restore(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:1071
HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, const DSBUFFERDESC *dsbd)
Definition: primary.c:1223
static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface)
Definition: primary.c:753
static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(LPDIRECTSOUNDBUFFER iface, LPDWORD playpos, LPDWORD writepos)
Definition: primary.c:781
static HRESULT WINAPI PrimaryBufferImpl_GetPan(LPDIRECTSOUNDBUFFER iface, LPLONG pan)
Definition: primary.c:1013
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2505
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2399
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2371
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2538
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2485
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257