source: branches/gcc-kmk/src/dsound/os2sndbuffer.cpp@ 21692

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

Normalize file case.

Change all uppercase filenames and extensions to lowercase (except well known cases like LICENSE.TXT and so on).

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.