source: trunk/src/dsound/os2sndbuffer.cpp@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 25.7 KB
Line 
1/* $Id: OS2SNDBUFFER.CPP,v 1.11 2001-03-19 18:56:57 mike Exp $ */
2
3/*
4 * DirectSound SoundBuffer class
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 2001 Michal Necasek
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13
14/*@Header***********************************************************************
15* Header Files *
16*******************************************************************************/
17#define INCL_DOSMISC
18#include <os2win.h>
19
20#include <stdlib.h>
21#include <string.h>
22
23#define CINTERFACE
24#include <dsound.h>
25
26#include "OS2DSound.h"
27#include "OS2SndBuffer.h"
28#include "OS2PrimBuff.h"
29#include "OS23DListener.h"
30#include "OS23DBuffer.h"
31#include "OS2Notify.h"
32#include <misc.h>
33
34#include "DSVolume.h"
35
36WAVEFORMATEX wfxDefaultPrimaryBuf = { WAVE_FORMAT_PCM,
37 2,
38 22050,
39 44100,
40 2,
41 8,
42 0};
43
44OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::dsbroot = NULL;
45OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::primary = NULL;
46
47//******************************************************************************
48//******************************************************************************
49OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc)
50 : Referenced(0), lastError(DS_OK)
51{
52 //This is the "normal" constructor
53 lpVtbl = &Vtbl;
54 Vtbl.fnAddRef = SoundBufAddRef;
55 Vtbl.fnRelease = SoundBufRelease;
56 Vtbl.fnQueryInterface = SoundBufQueryInterface;
57 Vtbl.fnGetCaps = SoundBufGetCaps;
58 Vtbl.fnGetFormat = SoundBufGetFormat;
59 Vtbl.fnGetVolume = SoundBufGetVolume;
60 Vtbl.fnGetStatus = SoundBufGetStatus;
61 Vtbl.fnGetCurrentPosition = SoundBufGetCurrentPosition;
62 Vtbl.fnGetPan = SoundBufGetPan;
63 Vtbl.fnGetFrequency = SoundBufGetFrequency;
64 Vtbl.fnInitialize = SoundBufInitialize;
65 Vtbl.fnRestore = SoundBufRestore;
66 Vtbl.fnSetFormat = SoundBufSetFormat;
67 Vtbl.fnSetVolume = SoundBufSetVolume;
68 Vtbl.fnSetCurrentPosition = SoundBufSetCurrentPosition;
69 Vtbl.fnSetPan = SoundBufSetPan;
70 Vtbl.fnSetFrequency = SoundBufSetFrequency;
71 Vtbl.fnLock = SoundBufLock;
72 Vtbl.fnUnlock = SoundBufUnlock;
73 Vtbl.fnStop = SoundBufStop;
74 Vtbl.fnPlay = SoundBufPlay;
75
76 dprintf(("DSOUND-OS2IDirectSoundBuffer::OS2IDirectSoundBuffer (buf=%X)", this));
77
78 // get the primary buffer from the DSound instance.
79 primary = DSound->primary;
80
81 // We can still to the below logic just in case!! Should not be required thow!
82 // If the primary SoundBuffer doesn't exist by now, we have to create it!
83 if (primary == NULL) {
84 OS2PrimBuff *primbuff;
85 primbuff = new OS2PrimBuff(DSound, lpDSBufferDesc);
86
87 if (primary == NULL) {
88 lastError = DSERR_OUTOFMEMORY;
89 return;
90 }
91 }
92 // Add a reference to the primary buffer for _every_ secondary buffer; this makes
93 // sure that as long as a secondary buffer exists the primary buffer won't get
94 // destroyed; moreover if the user didn't create a primary buffer himself/herself,
95 // it will automatically get created and destroyed with the last secondary buffer
96 primary->Vtbl.fnAddRef(primary);
97
98 // Start playing the primary buffer
99 // TODO: only start playing the primary buffer when necessary!
100 OS2IDirectSoundBuffer::primary->Vtbl.fnPlay(OS2IDirectSoundBuffer::primary, 0, 0, DSBPLAY_LOOPING);
101
102 parentDS = DSound;
103 writepos = 0;
104 playpos = 0;
105 status = 0;
106 fLocked = FALSE;
107 fPrimary = FALSE;
108 volume = 255;
109 DSvolume = 0;
110 pan = 0;
111 DSpan = 0;
112 lpfxFormat= NULL;
113 fPlaying = FALSE;
114 fLoop = FALSE;
115 notify = NULL;
116 memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
117
118 // Note: this cannot be a primary buffer - those take a different route
119
120 // frequency has to be set according to the bufer format
121 frequency = bufferdesc.lpwfxFormat->nSamplesPerSec;
122
123 if (bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0) {
124 dprintf(("bufferdesc not valid!"));
125 lastError = DSERR_INVALIDPARAM;
126 return;
127 }
128
129 // Some apps pass trash in cbSize, can't rely on that!
130 lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
131 memcpy(lpfxFormat,
132 bufferdesc.lpwfxFormat,
133 /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
134
135 dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
136
137 lpSndBuffer = (SOUNDBUF*)VirtualAlloc(0, bufferdesc.dwBufferBytes + sizeof(DWORD), MEM_COMMIT, PAGE_READWRITE);
138 if (lpSndBuffer == NULL) {
139 dprintf(("VirtualAlloc failed"));
140 lpSndBuffer = NULL;
141 lastError = DSERR_OUTOFMEMORY;
142 return;
143 }
144 lpBuffer = &(lpSndBuffer->pData[0]);
145 lpSndBuffer->dwReferences = 1;
146
147 next = dsbroot;
148 dsbroot = this;
149}
150
151//******************************************************************************
152//******************************************************************************
153OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(OS2IDirectSound *DSound, OS2IDirectSoundBuffer *srcBuf)
154 : Referenced(0), lastError(DS_OK)
155{
156 //This is the constructor used for duplicating sound buffers
157 lpVtbl = &Vtbl;
158 Vtbl.fnAddRef = SoundBufAddRef;
159 Vtbl.fnRelease = SoundBufRelease;
160 Vtbl.fnQueryInterface = SoundBufQueryInterface;
161 Vtbl.fnGetCaps = SoundBufGetCaps;
162 Vtbl.fnGetFormat = SoundBufGetFormat;
163 Vtbl.fnGetVolume = SoundBufGetVolume;
164 Vtbl.fnGetStatus = SoundBufGetStatus;
165 Vtbl.fnGetCurrentPosition = SoundBufGetCurrentPosition;
166 Vtbl.fnGetPan = SoundBufGetPan;
167 Vtbl.fnGetFrequency = SoundBufGetFrequency;
168 Vtbl.fnInitialize = SoundBufInitialize;
169 Vtbl.fnRestore = SoundBufRestore;
170 Vtbl.fnSetFormat = SoundBufSetFormat;
171 Vtbl.fnSetVolume = SoundBufSetVolume;
172 Vtbl.fnSetCurrentPosition = SoundBufSetCurrentPosition;
173 Vtbl.fnSetPan = SoundBufSetPan;
174 Vtbl.fnSetFrequency = SoundBufSetFrequency;
175 Vtbl.fnLock = SoundBufLock;
176 Vtbl.fnUnlock = SoundBufUnlock;
177 Vtbl.fnStop = SoundBufStop;
178 Vtbl.fnPlay = SoundBufPlay;
179
180 dprintf(("DSOUND-OS2IDirectSoundBuffer::OS2IDirectSoundBuffer/Duplicate (buf=%X)", this));
181
182 if (srcBuf->fPrimary) {
183 dprintf(("Error: Cannot duplicate primary sound buffer!"));
184 lpBuffer = NULL;
185 lastError = DSERR_INVALIDPARAM;
186 return;
187 }
188
189 // get the primary buffer from the DSound instance.
190 primary = DSound->primary;
191
192 // No need to check if primary exists - it has to (this can't be the first
193 // secondary buffer being created)
194
195 // Add a reference to the primary buffer for _every_ secondary buffer; this makes
196 // sure that as long as a secondary buffer exists the primary buffer won't get
197 // destroyed; moreover if the user didn't create a primary buffer himself/herself,
198 // it will automatically get created and destroyed with the last secondary buffer
199 primary->Vtbl.fnAddRef(primary);
200
201 parentDS = DSound;
202 writepos = 0;
203 playpos = 0;
204 status = 0;
205 fLocked = FALSE;
206 fPrimary = FALSE;
207 volume = srcBuf->volume;
208 DSvolume = srcBuf->DSvolume;
209 pan = srcBuf->pan;
210 DSpan = srcBuf->DSpan;
211 lpBuffer = srcBuf->lpBuffer;
212 fPlaying = FALSE;
213 fLoop = srcBuf->fLoop;
214 notify = NULL;
215 memcpy(&bufferdesc, &(srcBuf->bufferdesc), sizeof(DSBUFFERDESC));
216
217 // Note: this cannot be a primary buffer - those take a different route
218
219 // frequency has to be set according to the bufer format
220 frequency = srcBuf->frequency;
221
222 lpfxFormat = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX));
223 memcpy(lpfxFormat,srcBuf->lpfxFormat,
224 sizeof(WAVEFORMATEX));
225
226 dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
227
228 // Increment reference count for the buffer memory
229 lpSndBuffer = srcBuf->lpSndBuffer;
230 lpSndBuffer->dwReferences++;
231
232 next = dsbroot;
233 dsbroot = this;
234}
235
236//******************************************************************************
237//******************************************************************************
238OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
239{
240 /* We must not run this destructor on the primary buffer! */
241 if (fPrimary)
242 return;
243
244 dprintf(("DSOUND-OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer (buf=%X)", this));
245
246 // free allocted memory - unless it's shared by a duplicated buffer
247 if (lpSndBuffer) {
248 lpSndBuffer->dwReferences--;
249 if (lpSndBuffer->dwReferences == 0)
250 VirtualFree(lpSndBuffer, 0, MEM_RELEASE);
251 }
252
253 if (lpfxFormat)
254 free(lpfxFormat);
255
256 // remove ourselves from the linked list
257 OS2IDirectSoundBuffer *cur = dsbroot;
258 OS2IDirectSoundBuffer *prev = NULL;
259
260 // release the primary buffer too
261 primary->Vtbl.fnRelease(primary);
262
263 if (this == dsbroot) // is this the first SoundBuffer?
264 dsbroot = next;
265 else { // walk the chain
266 while (cur->next != this)
267 cur = cur->next;
268
269 cur->next = next;
270 }
271
272}
273
274//******************************************************************************
275//******************************************************************************
276void OS2IDirectSoundBuffer::DestroyAllBuffers()
277{
278 dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers"));
279
280 // if any SoundBuffers still exist when the OS2IDirectSound object is
281 // being closed, just kill them all
282 OS2IDirectSoundBuffer *cur = dsbroot;
283 OS2IDirectSoundBuffer *tmp;
284
285 if (primary != NULL)
286 primary->Vtbl.fnStop(primary);
287
288 while (cur != NULL) {
289 tmp = cur->next;
290 delete cur;
291 cur = tmp;
292 }
293 dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers - %X", primary));
294 if (primary != NULL)
295 primary->Vtbl.fnRelease(primary);
296}
297
298//******************************************************************************
299//******************************************************************************
300HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
301{
302 dprintf(("DSOUND-OS2IDirectSoundBuffer::QueryInterface"));
303 if (This == NULL) {
304 return DSERR_INVALIDPARAM;
305 }
306 *ppvObj = NULL;
307
308 if (IsEqualGUID(riid, &IID_IDirectSoundBuffer)) {
309 *ppvObj = This;
310
311 SoundBufAddRef(This);
312 return DS_OK;
313 }
314
315 if (IsEqualGUID(riid, &IID_IDirectSoundNotify)) {
316 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
317 OS2IDirectSoundNotify *notify;
318
319 notify = new OS2IDirectSoundNotify(me);
320 *ppvObj = notify;
321 notify->Vtbl.fnAddRef(notify);
322 return DS_OK;
323 }
324
325 if (IsEqualGUID(riid, &IID_IDirectSound3DBuffer)) {
326 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
327 OS2IDirectSound3DBuffer *buffer3D;
328
329 buffer3D = new OS2IDirectSound3DBuffer(me);
330 *ppvObj = buffer3D;
331 buffer3D->Vtbl.fnAddRef((IDirectSound3DBuffer *)buffer3D);
332 return DS_OK;
333 }
334
335 return E_NOINTERFACE;
336}
337//******************************************************************************
338//******************************************************************************
339ULONG WIN32API SoundBufAddRef(THIS)
340{
341 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
342
343 dprintf(("DSOUND-OS2IDirectSoundBuffer::AddRef (buf=%X) %d", me, me->Referenced+1));
344 if (me == NULL) {
345 return 0;
346 }
347 return ++me->Referenced;
348}
349//******************************************************************************
350//******************************************************************************
351ULONG WIN32API SoundBufRelease(THIS)
352{
353 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
354
355 dprintf(("DSOUND-OS2IDirectSoundBuffer::Release (buf=%X) %d", me, me->Referenced-1));
356 if (me == NULL) {
357 return 0;
358 }
359 if (me->Referenced) {
360 me->Referenced--;
361 if (me->Referenced == 0) {
362 delete me;
363 return 0;
364 }
365 else
366 return me->Referenced;
367 }
368 else
369 return 0;
370}
371//******************************************************************************
372//******************************************************************************
373HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
374{
375 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
376
377 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCaps (buf=%X)", me));
378 if (me == NULL || lpDSCaps == NULL) {
379 return DSERR_INVALIDPARAM;
380 }
381 /* FIXME: fill with more realistic values */
382 lpDSCaps->dwSize = sizeof(DSBCAPS);
383 lpDSCaps->dwFlags = me->bufferdesc.dwFlags | DSBCAPS_LOCSOFTWARE;
384 lpDSCaps->dwBufferBytes = me->bufferdesc.dwBufferBytes;
385 lpDSCaps->dwUnlockTransferRate = 0; /* in KB/sec - 0 == no transfer needed */
386 lpDSCaps->dwPlayCpuOverhead = 0; /* % CPU time - let's lie */
387
388 return DS_OK;
389}
390//******************************************************************************
391//******************************************************************************
392HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,
393 LPDWORD lpdwCurrentWriteCursor)
394{
395 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
396
397 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCurrentPosition (buf=%X)", me));
398 if ( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL) {
399 dprintf((" Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
400 return DSERR_INVALIDPARAM;
401 }
402
403 dprintf((" PlayPos %d, WritePos %d", me->playpos, me->writepos));
404 *lpdwCurrentPlayCursor = me->playpos;
405 *lpdwCurrentWriteCursor = me->writepos;
406 return DS_OK;
407}
408//******************************************************************************
409//******************************************************************************
410HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX lpwfxFormat,
411 DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
412{
413 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
414 int copysize;
415
416 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFormat (buf=%X)", me));
417 if (me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0) {
418 return DSERR_INVALIDPARAM;
419 }
420 copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
421 memcpy(lpwfxFormat, me->lpfxFormat, copysize);
422
423 if (lpdwSizeWritten) {
424 *lpdwSizeWritten = copysize;
425 }
426 return DS_OK;
427}
428//******************************************************************************
429//******************************************************************************
430HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
431{
432 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
433
434 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetVolume (buf=%X)", me));
435 if (me == NULL || lplVolume == NULL) {
436 return DSERR_INVALIDPARAM;
437 }
438 *lplVolume = me->DSvolume;
439 return DS_OK;
440}
441//******************************************************************************
442//******************************************************************************
443HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
444{
445 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
446
447 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetPan (buf=%X)", me));
448 if (me == NULL || lplPan == NULL) {
449 return DSERR_INVALIDPARAM;
450 }
451 *lplPan = me->DSpan;
452 return DS_OK;
453}
454//******************************************************************************
455//******************************************************************************
456HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
457{
458 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
459
460 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFrequency (buf=%X)", me));
461 if (me == NULL || lpdwFrequency == NULL) {
462 return DSERR_INVALIDPARAM;
463 }
464 *lpdwFrequency = me->frequency;
465 return DS_OK;
466}
467//******************************************************************************
468//******************************************************************************
469HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
470{
471 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
472
473 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetStatus (buf=%X)", me));
474 if (me == NULL || lpdwStatus == NULL) {
475 return DSERR_INVALIDPARAM;
476 }
477
478 if (me->fPlaying)
479 if (me->fLoop)
480 me->status |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
481 else
482 me->status |= DSBSTATUS_PLAYING;
483 else
484 me->status &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
485
486 *lpdwStatus = me->status;
487 return DS_OK;
488}
489//******************************************************************************
490//******************************************************************************
491HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
492{
493 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
494
495 dprintf(("DSOUND-SoundBufInitialize (buf=%X)", me));
496 if (me == NULL) {
497 return DSERR_INVALIDPARAM;
498 }
499 return DSERR_ALREADYINITIALIZED; //todo: for future extensions (dx5/6 ??)
500}
501//******************************************************************************
502//******************************************************************************
503HRESULT __stdcall SoundBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
504 LPVOID lplpvAudioPtr1, LPDWORD lpdwAudioBytes1,
505 LPVOID lplpvAudioPtr2, LPDWORD lpdwAudioBytes2,
506 DWORD dwFlags)
507{
508 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
509
510 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufLock (buf=%X, %d bytes of %d)", me, dwWriteBytes, me->bufferdesc.dwBufferBytes));
511 if (me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
512 return DSERR_INVALIDPARAM;
513
514 //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
515 if(dwWriteBytes > me->bufferdesc.dwBufferBytes) {
516 dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
517 return DSERR_INVALIDPARAM;
518 }
519 if (dwFlags & DSBLOCK_FROMWRITECURSOR) {
520 dwWriteCursor = me->writepos;
521 }
522 if (dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes) {
523 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
524 *lpdwAudioBytes1 = me->bufferdesc.dwBufferBytes - dwWriteCursor;
525 if (lplpvAudioPtr2 && lpdwAudioBytes2) {
526 *(DWORD *)lplpvAudioPtr2 = (DWORD)me->lpBuffer;
527 *lpdwAudioBytes2 = dwWriteBytes - *lpdwAudioBytes1;
528 }
529 }
530 else {
531 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
532 *lpdwAudioBytes1 = dwWriteBytes;
533 if (lplpvAudioPtr2 && lpdwAudioBytes2) {
534 *(DWORD *)lplpvAudioPtr2 = 0;
535 *lpdwAudioBytes2 = 0;
536 }
537 }
538
539 me->fLocked = TRUE;
540
541 return DS_OK;
542}
543
544//******************************************************************************
545//******************************************************************************
546HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1, DWORD dwRes2, DWORD dwFlags)
547{
548 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
549
550 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufPlay (buf=%X)", me));
551 if (me == NULL) {
552 dprintf((" Invalid parms - me is NULL"));
553 return DSERR_INVALIDPARAM;
554 }
555
556 if (!me->fPlaying) {
557 me->frac = 0;
558 me->fPlaying = TRUE;
559 me->status = DSBSTATUS_PLAYING;
560 me->fLoop = dwFlags == DSBPLAY_LOOPING;
561 if (me->fLoop)
562 me->status |= DSBSTATUS_LOOPING;
563
564 dprintf((" Buffer %X: start at pos %d, loop %s",me, me->playpos, me->fLoop?"YES":"NO"));
565 }
566 else {
567 me->fLoop = dwFlags == DSBPLAY_LOOPING;
568 if (me->fLoop)
569 me->status |= DSBSTATUS_LOOPING;
570
571 dprintf((" Buffer %X: already playing, loop %s",me, me->fLoop?"YES":"NO"));
572 }
573
574 return DS_OK;
575}
576
577//******************************************************************************
578//******************************************************************************
579HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
580{
581 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
582
583 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetCurrentPosition (buf=%X) to %d", me, dwNewPosition));
584 if (me == NULL) {
585 return DSERR_INVALIDPARAM;
586 }
587 me->playpos = dwNewPosition;
588
589 return DS_OK;
590}
591
592//******************************************************************************
593//******************************************************************************
594HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX lpWaveFormatEx)
595{
596 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
597
598 // Note: this sets the format of the _primary_ buffer;
599 // since this class only handles secondary buffers, we just return error
600 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFormat (buf=%X)", me));
601
602 return DSERR_UNSUPPORTED;
603}
604
605//******************************************************************************
606//******************************************************************************
607HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
608{
609 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
610
611 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetVolume (%d, buf=%X)", lVolume, me));
612 if (me == NULL || lVolume < -10000) {
613 return DSERR_INVALIDPARAM;
614 }
615 // some apps pass positive values in lVolume, that's wrong right?!?
616 me->DSvolume = (lVolume > 0) ? 0 : lVolume;
617
618 /* = (10 ^ (1/10)) = 1dB - but the formula below gives results _very_ similar */
619 /* to 'real' DirectSound, indistinguishable for all practical purposes */
620 //me->volume = 255.0 * pow(4, me->DSvolume / 1000.0);
621
622 /* Note: for some strange reason the above code sometimes gives erroneous */
623 /* results, hence we now use a simple conversion table (in steps of 4/100 dB) */
624
625 if (me->DSvolume < -4000)
626 me->volume = 0;
627 else
628 me->volume = VolTable[-me->DSvolume / 4];
629
630 dprintf((" New volume: %d", me->volume));
631
632 return DS_OK;
633}
634//******************************************************************************
635//******************************************************************************
636HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
637{
638 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
639
640 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetPan (%d, buf=%X)", lPan, me));
641 if (me == NULL || lPan < -10000 || lPan > 10000) {
642 return DSERR_INVALIDPARAM;
643 }
644 me->DSpan = lPan;
645 if (lPan == 0) {
646 me->pan = 0;
647 return DS_OK;
648 }
649
650 /* Note: we use very similar code as for volume above */
651 if (lPan < 0)
652 if (lPan < -4000)
653 me->pan = -255;
654 else
655 me->pan = VolTable[-lPan / 4] - 255;
656 else
657 if (lPan > 4000)
658 me->pan = 255;
659 else
660 me->pan = 255 - VolTable[lPan / 4];
661
662 dprintf((" New pan: %d", me->pan));
663
664 return DS_OK;
665}
666
667//******************************************************************************
668//******************************************************************************
669HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
670{
671 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
672
673 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFrequency (buf=%X)", me));
674 if (me == NULL) {
675 return DSERR_INVALIDPARAM;
676 }
677
678 // zero means default (buffer format) frequency
679 if (dwFrequency)
680 me->frequency = dwFrequency;
681 else
682 me->frequency = me->lpfxFormat->nSamplesPerSec;
683
684 return DS_OK;
685}
686
687//******************************************************************************
688//******************************************************************************
689HRESULT __stdcall SoundBufStop(THIS )
690{
691 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
692
693 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufStop (buf=%X)", me));
694 if (me == NULL) {
695 return DSERR_INVALIDPARAM;
696 }
697
698 me->fPlaying = FALSE;
699 me->status &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
700
701 if (me->notify != NULL)
702 me->notify->CheckStop();
703
704 return DS_OK;
705}
706
707//******************************************************************************
708//******************************************************************************
709HRESULT __stdcall SoundBufUnlock(THIS_
710 LPVOID lpvAudioPtr1, DWORD dwAudioBytes1,
711 LPVOID lpvAudioPtr2, DWORD dwAudioBytes2)
712{
713 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
714
715 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufUnlock (buf=%X)", me));
716 if (me == NULL) {
717 return DSERR_INVALIDPARAM;
718 }
719
720 me->fLocked = TRUE;
721
722 return DS_OK;
723}
724
725//******************************************************************************
726//******************************************************************************
727HRESULT __stdcall SoundBufRestore(THIS )
728{
729 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
730
731 dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufRestore (buf=%X)", me));
732 if (me == NULL) {
733 return DSERR_INVALIDPARAM;
734 }
735 return DS_OK;
736}
737//******************************************************************************
738//******************************************************************************
Note: See TracBrowser for help on using the repository browser.