[5331] | 1 | /* $Id: OS2SNDBUFFER.CPP,v 1.11 2001-03-19 18:56:57 mike Exp $ */
|
---|
[97] | 2 |
|
---|
[4] | 3 | /*
|
---|
| 4 | * DirectSound SoundBuffer class
|
---|
| 5 | *
|
---|
| 6 | * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
|
---|
[5292] | 7 | * Copyright 2001 Michal Necasek
|
---|
[4] | 8 | *
|
---|
| 9 | * Project Odin Software License can be found in LICENSE.TXT
|
---|
| 10 | *
|
---|
| 11 | */
|
---|
| 12 |
|
---|
| 13 |
|
---|
| 14 | /*@Header***********************************************************************
|
---|
| 15 | * Header Files *
|
---|
| 16 | *******************************************************************************/
|
---|
[1744] | 17 | #define INCL_DOSMISC
|
---|
[1421] | 18 | #include <os2win.h>
|
---|
[3099] | 19 |
|
---|
[4] | 20 | #include <stdlib.h>
|
---|
| 21 | #include <string.h>
|
---|
| 22 |
|
---|
[21479] | 23 | #define CINTERFACE
|
---|
[4] | 24 | #include <dsound.h>
|
---|
| 25 |
|
---|
[3099] | 26 | #include "OS2DSound.h"
|
---|
| 27 | #include "OS2SndBuffer.h"
|
---|
| 28 | #include "OS2PrimBuff.h"
|
---|
| 29 | #include "OS23DListener.h"
|
---|
| 30 | #include "OS23DBuffer.h"
|
---|
| 31 | #include "OS2Notify.h"
|
---|
[1744] | 32 | #include <misc.h>
|
---|
[4] | 33 |
|
---|
[3099] | 34 | #include "DSVolume.h"
|
---|
[4] | 35 |
|
---|
[1744] | 36 | WAVEFORMATEX wfxDefaultPrimaryBuf = { WAVE_FORMAT_PCM,
|
---|
| 37 | 2,
|
---|
| 38 | 22050,
|
---|
| 39 | 44100,
|
---|
| 40 | 2,
|
---|
| 41 | 8,
|
---|
| 42 | 0};
|
---|
| 43 |
|
---|
[3099] | 44 | OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::dsbroot = NULL;
|
---|
| 45 | OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::primary = NULL;
|
---|
| 46 |
|
---|
[4] | 47 | //******************************************************************************
|
---|
| 48 | //******************************************************************************
|
---|
[3099] | 49 | OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc)
|
---|
[4] | 50 | : Referenced(0), lastError(DS_OK)
|
---|
| 51 | {
|
---|
[5292] | 52 | //This is the "normal" constructor
|
---|
[3099] | 53 | lpVtbl = &Vtbl;
|
---|
[21479] | 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;
|
---|
[4] | 75 |
|
---|
[3099] | 76 | dprintf(("DSOUND-OS2IDirectSoundBuffer::OS2IDirectSoundBuffer (buf=%X)", this));
|
---|
[4] | 77 |
|
---|
[3555] | 78 | // get the primary buffer from the DSound instance.
|
---|
| 79 | primary = DSound->primary;
|
---|
[5285] | 80 |
|
---|
[3555] | 81 | // We can still to the below logic just in case!! Should not be required thow!
|
---|
[3099] | 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);
|
---|
[1744] | 86 |
|
---|
[3099] | 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
|
---|
[21479] | 96 | primary->Vtbl.fnAddRef(primary);
|
---|
[1744] | 97 |
|
---|
[3099] | 98 | // Start playing the primary buffer
|
---|
| 99 | // TODO: only start playing the primary buffer when necessary!
|
---|
[21479] | 100 | OS2IDirectSoundBuffer::primary->Vtbl.fnPlay(OS2IDirectSoundBuffer::primary, 0, 0, DSBPLAY_LOOPING);
|
---|
[3099] | 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) {
|
---|
[1744] | 124 | dprintf(("bufferdesc not valid!"));
|
---|
| 125 | lastError = DSERR_INVALIDPARAM;
|
---|
| 126 | return;
|
---|
[3099] | 127 | }
|
---|
[1744] | 128 |
|
---|
[3099] | 129 | // Some apps pass trash in cbSize, can't rely on that!
|
---|
| 130 | lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
|
---|
| 131 | memcpy(lpfxFormat,
|
---|
[1744] | 132 | bufferdesc.lpwfxFormat,
|
---|
[3099] | 133 | /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
|
---|
[1744] | 134 |
|
---|
[3099] | 135 | dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
|
---|
[2637] | 136 |
|
---|
[5292] | 137 | lpSndBuffer = (SOUNDBUF*)VirtualAlloc(0, bufferdesc.dwBufferBytes + sizeof(DWORD), MEM_COMMIT, PAGE_READWRITE);
|
---|
| 138 | if (lpSndBuffer == NULL) {
|
---|
[1744] | 139 | dprintf(("VirtualAlloc failed"));
|
---|
[5292] | 140 | lpSndBuffer = NULL;
|
---|
[1744] | 141 | lastError = DSERR_OUTOFMEMORY;
|
---|
| 142 | return;
|
---|
[3099] | 143 | }
|
---|
[5292] | 144 | lpBuffer = &(lpSndBuffer->pData[0]);
|
---|
| 145 | lpSndBuffer->dwReferences = 1;
|
---|
[2637] | 146 |
|
---|
[3099] | 147 | next = dsbroot;
|
---|
| 148 | dsbroot = this;
|
---|
[4] | 149 | }
|
---|
[3099] | 150 |
|
---|
[4] | 151 | //******************************************************************************
|
---|
| 152 | //******************************************************************************
|
---|
[5292] | 153 | OS2IDirectSoundBuffer::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;
|
---|
[21479] | 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;
|
---|
[5292] | 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
|
---|
[21479] | 199 | primary->Vtbl.fnAddRef(primary);
|
---|
[5292] | 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 | //******************************************************************************
|
---|
[4] | 238 | OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
|
---|
| 239 | {
|
---|
[3099] | 240 | /* We must not run this destructor on the primary buffer! */
|
---|
| 241 | if (fPrimary)
|
---|
| 242 | return;
|
---|
[4] | 243 |
|
---|
[3099] | 244 | dprintf(("DSOUND-OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer (buf=%X)", this));
|
---|
| 245 |
|
---|
[5292] | 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 | }
|
---|
[3099] | 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
|
---|
[21479] | 261 | primary->Vtbl.fnRelease(primary);
|
---|
[3099] | 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 |
|
---|
[4] | 272 | }
|
---|
[3099] | 273 |
|
---|
[4] | 274 | //******************************************************************************
|
---|
| 275 | //******************************************************************************
|
---|
[3099] | 276 | void 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)
|
---|
[21479] | 286 | primary->Vtbl.fnStop(primary);
|
---|
[3099] | 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)
|
---|
[21479] | 295 | primary->Vtbl.fnRelease(primary);
|
---|
[3099] | 296 | }
|
---|
| 297 |
|
---|
| 298 | //******************************************************************************
|
---|
| 299 | //******************************************************************************
|
---|
[1421] | 300 | HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
|
---|
[4] | 301 | {
|
---|
[3099] | 302 | dprintf(("DSOUND-OS2IDirectSoundBuffer::QueryInterface"));
|
---|
| 303 | if (This == NULL) {
|
---|
| 304 | return DSERR_INVALIDPARAM;
|
---|
| 305 | }
|
---|
| 306 | *ppvObj = NULL;
|
---|
[4] | 307 |
|
---|
[21479] | 308 | if (IsEqualGUID(riid, &IID_IDirectSoundBuffer)) {
|
---|
[3099] | 309 | *ppvObj = This;
|
---|
[4] | 310 |
|
---|
[3099] | 311 | SoundBufAddRef(This);
|
---|
| 312 | return DS_OK;
|
---|
| 313 | }
|
---|
[4] | 314 |
|
---|
[21479] | 315 | if (IsEqualGUID(riid, &IID_IDirectSoundNotify)) {
|
---|
[3099] | 316 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
| 317 | OS2IDirectSoundNotify *notify;
|
---|
| 318 |
|
---|
| 319 | notify = new OS2IDirectSoundNotify(me);
|
---|
| 320 | *ppvObj = notify;
|
---|
[21479] | 321 | notify->Vtbl.fnAddRef(notify);
|
---|
[3099] | 322 | return DS_OK;
|
---|
| 323 | }
|
---|
| 324 |
|
---|
[21479] | 325 | if (IsEqualGUID(riid, &IID_IDirectSound3DBuffer)) {
|
---|
[3099] | 326 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
| 327 | OS2IDirectSound3DBuffer *buffer3D;
|
---|
| 328 |
|
---|
| 329 | buffer3D = new OS2IDirectSound3DBuffer(me);
|
---|
| 330 | *ppvObj = buffer3D;
|
---|
[21479] | 331 | buffer3D->Vtbl.fnAddRef((IDirectSound3DBuffer *)buffer3D);
|
---|
[3099] | 332 | return DS_OK;
|
---|
| 333 | }
|
---|
| 334 |
|
---|
| 335 | return E_NOINTERFACE;
|
---|
[4] | 336 | }
|
---|
| 337 | //******************************************************************************
|
---|
| 338 | //******************************************************************************
|
---|
| 339 | ULONG WIN32API SoundBufAddRef(THIS)
|
---|
| 340 | {
|
---|
[3099] | 341 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 342 |
|
---|
[3099] | 343 | dprintf(("DSOUND-OS2IDirectSoundBuffer::AddRef (buf=%X) %d", me, me->Referenced+1));
|
---|
| 344 | if (me == NULL) {
|
---|
| 345 | return 0;
|
---|
| 346 | }
|
---|
| 347 | return ++me->Referenced;
|
---|
[4] | 348 | }
|
---|
| 349 | //******************************************************************************
|
---|
| 350 | //******************************************************************************
|
---|
| 351 | ULONG WIN32API SoundBufRelease(THIS)
|
---|
| 352 | {
|
---|
[3099] | 353 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 354 |
|
---|
[3099] | 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;
|
---|
[4] | 370 | }
|
---|
| 371 | //******************************************************************************
|
---|
| 372 | //******************************************************************************
|
---|
| 373 | HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
|
---|
| 374 | {
|
---|
[3099] | 375 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 376 |
|
---|
[3099] | 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;
|
---|
[4] | 389 | }
|
---|
| 390 | //******************************************************************************
|
---|
| 391 | //******************************************************************************
|
---|
| 392 | HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,
|
---|
| 393 | LPDWORD lpdwCurrentWriteCursor)
|
---|
| 394 | {
|
---|
[3099] | 395 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 396 |
|
---|
[3099] | 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 | }
|
---|
[1744] | 402 |
|
---|
[3099] | 403 | dprintf((" PlayPos %d, WritePos %d", me->playpos, me->writepos));
|
---|
| 404 | *lpdwCurrentPlayCursor = me->playpos;
|
---|
| 405 | *lpdwCurrentWriteCursor = me->writepos;
|
---|
| 406 | return DS_OK;
|
---|
[4] | 407 | }
|
---|
| 408 | //******************************************************************************
|
---|
| 409 | //******************************************************************************
|
---|
| 410 | HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX lpwfxFormat,
|
---|
| 411 | DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
|
---|
| 412 | {
|
---|
[3099] | 413 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
| 414 | int copysize;
|
---|
[4] | 415 |
|
---|
[3099] | 416 | dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFormat (buf=%X)", me));
|
---|
| 417 | if (me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0) {
|
---|
| 418 | return DSERR_INVALIDPARAM;
|
---|
| 419 | }
|
---|
[5292] | 420 | copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
|
---|
[3099] | 421 | memcpy(lpwfxFormat, me->lpfxFormat, copysize);
|
---|
[4] | 422 |
|
---|
[3099] | 423 | if (lpdwSizeWritten) {
|
---|
| 424 | *lpdwSizeWritten = copysize;
|
---|
| 425 | }
|
---|
| 426 | return DS_OK;
|
---|
[4] | 427 | }
|
---|
| 428 | //******************************************************************************
|
---|
| 429 | //******************************************************************************
|
---|
| 430 | HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
|
---|
| 431 | {
|
---|
[3099] | 432 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 433 |
|
---|
[3099] | 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;
|
---|
[4] | 440 | }
|
---|
| 441 | //******************************************************************************
|
---|
| 442 | //******************************************************************************
|
---|
| 443 | HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
|
---|
| 444 | {
|
---|
[3099] | 445 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 446 |
|
---|
[3099] | 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;
|
---|
[4] | 453 | }
|
---|
| 454 | //******************************************************************************
|
---|
| 455 | //******************************************************************************
|
---|
| 456 | HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
|
---|
| 457 | {
|
---|
[3099] | 458 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 459 |
|
---|
[3099] | 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;
|
---|
[4] | 466 | }
|
---|
| 467 | //******************************************************************************
|
---|
| 468 | //******************************************************************************
|
---|
| 469 | HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
|
---|
| 470 | {
|
---|
[3099] | 471 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 472 |
|
---|
[3099] | 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;
|
---|
[4] | 488 | }
|
---|
| 489 | //******************************************************************************
|
---|
| 490 | //******************************************************************************
|
---|
| 491 | HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
|
---|
| 492 | {
|
---|
[3099] | 493 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 494 |
|
---|
[3099] | 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 ??)
|
---|
[4] | 500 | }
|
---|
| 501 | //******************************************************************************
|
---|
| 502 | //******************************************************************************
|
---|
| 503 | HRESULT __stdcall SoundBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
|
---|
| 504 | LPVOID lplpvAudioPtr1, LPDWORD lpdwAudioBytes1,
|
---|
| 505 | LPVOID lplpvAudioPtr2, LPDWORD lpdwAudioBytes2,
|
---|
| 506 | DWORD dwFlags)
|
---|
| 507 | {
|
---|
[3099] | 508 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 509 |
|
---|
[3099] | 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;
|
---|
[4] | 542 | }
|
---|
[3099] | 543 |
|
---|
[4] | 544 | //******************************************************************************
|
---|
| 545 | //******************************************************************************
|
---|
[3099] | 546 | HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1, DWORD dwRes2, DWORD dwFlags)
|
---|
[4] | 547 | {
|
---|
[3099] | 548 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 549 |
|
---|
[3099] | 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;
|
---|
[4] | 575 | }
|
---|
[3099] | 576 |
|
---|
[4] | 577 | //******************************************************************************
|
---|
| 578 | //******************************************************************************
|
---|
| 579 | HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
|
---|
| 580 | {
|
---|
[3099] | 581 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 582 |
|
---|
[3099] | 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;
|
---|
[4] | 590 | }
|
---|
[3099] | 591 |
|
---|
[4] | 592 | //******************************************************************************
|
---|
| 593 | //******************************************************************************
|
---|
[3099] | 594 | HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX lpWaveFormatEx)
|
---|
[4] | 595 | {
|
---|
[3099] | 596 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 597 |
|
---|
[3099] | 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;
|
---|
[4] | 603 | }
|
---|
[3099] | 604 |
|
---|
[4] | 605 | //******************************************************************************
|
---|
| 606 | //******************************************************************************
|
---|
| 607 | HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
|
---|
| 608 | {
|
---|
[3099] | 609 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 610 |
|
---|
[3099] | 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;
|
---|
[4] | 633 | }
|
---|
| 634 | //******************************************************************************
|
---|
| 635 | //******************************************************************************
|
---|
| 636 | HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
|
---|
| 637 | {
|
---|
[3099] | 638 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 639 |
|
---|
[3099] | 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;
|
---|
[4] | 665 | }
|
---|
[3099] | 666 |
|
---|
[4] | 667 | //******************************************************************************
|
---|
| 668 | //******************************************************************************
|
---|
| 669 | HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
|
---|
| 670 | {
|
---|
[3099] | 671 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 672 |
|
---|
[3099] | 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;
|
---|
[4] | 685 | }
|
---|
[3099] | 686 |
|
---|
[4] | 687 | //******************************************************************************
|
---|
| 688 | //******************************************************************************
|
---|
| 689 | HRESULT __stdcall SoundBufStop(THIS )
|
---|
| 690 | {
|
---|
[3099] | 691 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 692 |
|
---|
[3099] | 693 | dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufStop (buf=%X)", me));
|
---|
| 694 | if (me == NULL) {
|
---|
| 695 | return DSERR_INVALIDPARAM;
|
---|
| 696 | }
|
---|
[1744] | 697 |
|
---|
[3099] | 698 | me->fPlaying = FALSE;
|
---|
| 699 | me->status &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
|
---|
[1744] | 700 |
|
---|
[3099] | 701 | if (me->notify != NULL)
|
---|
| 702 | me->notify->CheckStop();
|
---|
[1744] | 703 |
|
---|
[3099] | 704 | return DS_OK;
|
---|
| 705 | }
|
---|
[1744] | 706 |
|
---|
[4] | 707 | //******************************************************************************
|
---|
| 708 | //******************************************************************************
|
---|
[3099] | 709 | HRESULT __stdcall SoundBufUnlock(THIS_
|
---|
| 710 | LPVOID lpvAudioPtr1, DWORD dwAudioBytes1,
|
---|
| 711 | LPVOID lpvAudioPtr2, DWORD dwAudioBytes2)
|
---|
[4] | 712 | {
|
---|
[3099] | 713 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 714 |
|
---|
[3099] | 715 | dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufUnlock (buf=%X)", me));
|
---|
| 716 | if (me == NULL) {
|
---|
| 717 | return DSERR_INVALIDPARAM;
|
---|
| 718 | }
|
---|
[2637] | 719 |
|
---|
[3099] | 720 | me->fLocked = TRUE;
|
---|
| 721 |
|
---|
| 722 | return DS_OK;
|
---|
[4] | 723 | }
|
---|
[3099] | 724 |
|
---|
[4] | 725 | //******************************************************************************
|
---|
| 726 | //******************************************************************************
|
---|
| 727 | HRESULT __stdcall SoundBufRestore(THIS )
|
---|
| 728 | {
|
---|
[3099] | 729 | OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
|
---|
[4] | 730 |
|
---|
[3099] | 731 | dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufRestore (buf=%X)", me));
|
---|
| 732 | if (me == NULL) {
|
---|
| 733 | return DSERR_INVALIDPARAM;
|
---|
| 734 | }
|
---|
| 735 | return DS_OK;
|
---|
[4] | 736 | }
|
---|
| 737 | //******************************************************************************
|
---|
| 738 | //******************************************************************************
|
---|