annotate src/win32/DirectSound.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 #include "stdafx.h"
rlm@1 2 #include <mmreg.h>
rlm@1 3 #include <dsound.h>
rlm@1 4
rlm@1 5 #include "resource.h"
rlm@1 6 #include "AVIWrite.h"
rlm@1 7 #include "Sound.h"
rlm@1 8 #include "WavWriter.h"
rlm@1 9 #include "VBA.h"
rlm@1 10
rlm@1 11 #include "../gba/GBAGlobals.h"
rlm@1 12 #include "../gba/GBASound.h"
rlm@1 13 #include "../common/nesvideos-piece.h"
rlm@1 14
rlm@1 15 extern void directXMessage(const char *);
rlm@1 16
rlm@1 17 class DirectSound : public ISound
rlm@1 18 {
rlm@1 19 private:
rlm@1 20 HINSTANCE dsoundDLL;
rlm@1 21 LPDIRECTSOUND pDirectSound;
rlm@1 22 LPDIRECTSOUNDBUFFER dsbPrimary;
rlm@1 23 LPDIRECTSOUNDBUFFER dsbSecondary;
rlm@1 24 LPDIRECTSOUNDNOTIFY dsbNotify;
rlm@1 25 HANDLE dsbEvent;
rlm@1 26 WAVEFORMATEX wfx;
rlm@1 27 float curRate;
rlm@1 28 public:
rlm@1 29 DirectSound();
rlm@1 30 virtual ~DirectSound();
rlm@1 31
rlm@1 32 bool init();
rlm@1 33 void pause();
rlm@1 34 void reset();
rlm@1 35 void resume();
rlm@1 36 void write();
rlm@1 37 void setSpeed(float rate);
rlm@1 38 bool isPlaying();
rlm@1 39 void clearAudioBuffer();
rlm@1 40 };
rlm@1 41
rlm@1 42 DirectSound::DirectSound()
rlm@1 43 {
rlm@1 44 dsoundDLL = NULL;
rlm@1 45 pDirectSound = NULL;
rlm@1 46 dsbPrimary = NULL;
rlm@1 47 dsbSecondary = NULL;
rlm@1 48 dsbNotify = NULL;
rlm@1 49 dsbEvent = NULL;
rlm@1 50 }
rlm@1 51
rlm@1 52 DirectSound::~DirectSound()
rlm@1 53 {
rlm@1 54 if (theApp.aviRecorder != NULL)
rlm@1 55 {
rlm@1 56 delete theApp.aviRecorder;
rlm@1 57 theApp.aviRecorder = NULL;
rlm@1 58 theApp.aviRecording = false;
rlm@1 59 }
rlm@1 60
rlm@1 61 if (theApp.soundRecording)
rlm@1 62 {
rlm@1 63 if (theApp.soundRecorder != NULL)
rlm@1 64 {
rlm@1 65 delete theApp.soundRecorder;
rlm@1 66 theApp.soundRecorder = NULL;
rlm@1 67 }
rlm@1 68 theApp.soundRecording = false;
rlm@1 69 }
rlm@1 70
rlm@1 71 if (dsbNotify != NULL)
rlm@1 72 {
rlm@1 73 dsbNotify->Release();
rlm@1 74 dsbNotify = NULL;
rlm@1 75 }
rlm@1 76
rlm@1 77 if (dsbEvent != NULL)
rlm@1 78 {
rlm@1 79 CloseHandle(dsbEvent);
rlm@1 80 dsbEvent = NULL;
rlm@1 81 }
rlm@1 82
rlm@1 83 if (pDirectSound != NULL)
rlm@1 84 {
rlm@1 85 if (dsbPrimary != NULL)
rlm@1 86 {
rlm@1 87 dsbPrimary->Release();
rlm@1 88 dsbPrimary = NULL;
rlm@1 89 }
rlm@1 90
rlm@1 91 if (dsbSecondary != NULL)
rlm@1 92 {
rlm@1 93 dsbSecondary->Release();
rlm@1 94 dsbSecondary = NULL;
rlm@1 95 }
rlm@1 96
rlm@1 97 pDirectSound->Release();
rlm@1 98 pDirectSound = NULL;
rlm@1 99 }
rlm@1 100
rlm@1 101 if (dsoundDLL != NULL)
rlm@1 102 {
rlm@1 103 FreeLibrary(dsoundDLL);
rlm@1 104 dsoundDLL = NULL;
rlm@1 105 }
rlm@1 106 }
rlm@1 107
rlm@1 108 bool DirectSound::init()
rlm@1 109 {
rlm@1 110 HRESULT hr;
rlm@1 111
rlm@1 112 dsoundDLL = LoadLibrary("DSOUND.DLL");
rlm@1 113 HRESULT (WINAPI *DSoundCreate)(LPCGUID, LPDIRECTSOUND *, IUnknown *);
rlm@1 114 if (dsoundDLL != NULL)
rlm@1 115 {
rlm@1 116 DSoundCreate = (HRESULT (WINAPI *)(LPCGUID, LPDIRECTSOUND *, IUnknown *))
rlm@1 117 GetProcAddress(dsoundDLL, "DirectSoundCreate");
rlm@1 118
rlm@1 119 if (DSoundCreate == NULL)
rlm@1 120 {
rlm@1 121 directXMessage("DirectSoundCreate");
rlm@1 122 return false;
rlm@1 123 }
rlm@1 124 }
rlm@1 125 else
rlm@1 126 {
rlm@1 127 directXMessage("DSOUND.DLL");
rlm@1 128 return false;
rlm@1 129 }
rlm@1 130
rlm@1 131 if (FAILED(hr = DSoundCreate(NULL, &pDirectSound, NULL)))
rlm@1 132 {
rlm@1 133 // errorMessage(myLoadString(IDS_ERROR_SOUND_CREATE), hr);
rlm@1 134 systemMessage(IDS_CANNOT_CREATE_DIRECTSOUND,
rlm@1 135 "Cannot create DirectSound %08x", hr);
rlm@1 136 pDirectSound = NULL;
rlm@1 137 dsbSecondary = NULL;
rlm@1 138 return false;
rlm@1 139 }
rlm@1 140
rlm@1 141 if (FAILED(hr = pDirectSound->SetCooperativeLevel((HWND)*theApp.m_pMainWnd, DSSCL_EXCLUSIVE)))
rlm@1 142 {
rlm@1 143 // errorMessage(myLoadString(IDS_ERROR_SOUND_LEVEL), hr);
rlm@1 144 systemMessage(IDS_CANNOT_SETCOOPERATIVELEVEL,
rlm@1 145 "Cannot SetCooperativeLevel %08x", hr);
rlm@1 146 return false;
rlm@1 147 }
rlm@1 148
rlm@1 149 DSBUFFERDESC dsbdesc;
rlm@1 150 ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
rlm@1 151 dsbdesc.dwSize = sizeof(DSBUFFERDESC);
rlm@1 152 dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
rlm@1 153
rlm@1 154 if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbPrimary, NULL)))
rlm@1 155 {
rlm@1 156 // errorMessage(myLoadString(IDS_ERROR_SOUND_BUFFER),hr);
rlm@1 157 systemMessage(IDS_CANNOT_CREATESOUNDBUFFER,
rlm@1 158 "Cannot CreateSoundBuffer %08x", hr);
rlm@1 159 return false;
rlm@1 160 }
rlm@1 161
rlm@1 162 // Set primary buffer format
rlm@1 163
rlm@1 164 memset(&wfx, 0, sizeof(WAVEFORMATEX));
rlm@1 165 wfx.wFormatTag = WAVE_FORMAT_PCM;
rlm@1 166 wfx.nChannels = 2;
rlm@1 167 switch (soundQuality)
rlm@1 168 {
rlm@1 169 case 2:
rlm@1 170 wfx.nSamplesPerSec = 22050;
rlm@1 171 soundBufferLen = 736 * 2;
rlm@1 172 soundBufferTotalLen = 7360 * 2;
rlm@1 173 break;
rlm@1 174 case 4:
rlm@1 175 wfx.nSamplesPerSec = 11025;
rlm@1 176 soundBufferLen = 368 * 2;
rlm@1 177 soundBufferTotalLen = 3680 * 2;
rlm@1 178 break;
rlm@1 179 default:
rlm@1 180 soundQuality = 1;
rlm@1 181 wfx.nSamplesPerSec = 44100;
rlm@1 182 soundBufferLen = 1470 * 2;
rlm@1 183 soundBufferTotalLen = 14700 * 2;
rlm@1 184 }
rlm@1 185 wfx.wBitsPerSample = 16;
rlm@1 186 wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
rlm@1 187 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
rlm@1 188
rlm@1 189 if (FAILED(hr = dsbPrimary->SetFormat(&wfx)))
rlm@1 190 {
rlm@1 191 // errorMessage(myLoadString(IDS_ERROR_SOUND_PRIMARY),hr);
rlm@1 192 systemMessage(IDS_CANNOT_SETFORMAT_PRIMARY,
rlm@1 193 "Cannot SetFormat for primary %08x", hr);
rlm@1 194 return false;
rlm@1 195 }
rlm@1 196
rlm@1 197 ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
rlm@1 198 dsbdesc.dwSize = sizeof(DSBUFFERDESC);
rlm@1 199 dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS;
rlm@1 200 dsbdesc.dwBufferBytes = soundBufferTotalLen;
rlm@1 201 dsbdesc.lpwfxFormat = &wfx;
rlm@1 202
rlm@1 203 if (FAILED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)))
rlm@1 204 {
rlm@1 205 bool ok = false;
rlm@1 206 while (dsbdesc.dwFlags != DSBCAPS_GETCURRENTPOSITION2)
rlm@1 207 {
rlm@1 208 if (dsbdesc.dwFlags & DSBCAPS_CTRLFREQUENCY)
rlm@1 209 dsbdesc.dwFlags ^= DSBCAPS_CTRLFREQUENCY;
rlm@1 210 else if (dsbdesc.dwFlags & DSBCAPS_GLOBALFOCUS)
rlm@1 211 dsbdesc.dwFlags ^= DSBCAPS_GLOBALFOCUS;
rlm@1 212 else if (dsbdesc.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY)
rlm@1 213 dsbdesc.dwFlags ^= DSBCAPS_CTRLPOSITIONNOTIFY;
rlm@1 214 if (SUCCEEDED(hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)))
rlm@1 215 {
rlm@1 216 ok = true;
rlm@1 217 break;
rlm@1 218 }
rlm@1 219 }
rlm@1 220 if (!ok)
rlm@1 221 {
rlm@1 222 systemMessage(IDS_CANNOT_CREATESOUNDBUFFER_SEC, "Cannot CreateSoundBuffer secondary %08x", hr);
rlm@1 223 return false;
rlm@1 224 }
rlm@1 225
rlm@1 226 dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
rlm@1 227 }
rlm@1 228
rlm@1 229 dsbSecondary->SetCurrentPosition(0);
rlm@1 230
rlm@1 231 if (!theApp.useOldSync)
rlm@1 232 {
rlm@1 233 hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify,
rlm@1 234 (void * *)&dsbNotify);
rlm@1 235 if (!FAILED(hr))
rlm@1 236 {
rlm@1 237 dsbEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
rlm@1 238
rlm@1 239 DSBPOSITIONNOTIFY notify[10];
rlm@1 240
rlm@1 241 for (int i = 0; i < 10; i++)
rlm@1 242 {
rlm@1 243 notify[i].dwOffset = i * soundBufferLen;
rlm@1 244 notify[i].hEventNotify = dsbEvent;
rlm@1 245 }
rlm@1 246 if (FAILED(dsbNotify->SetNotificationPositions(10, notify)))
rlm@1 247 {
rlm@1 248 dsbNotify->Release();
rlm@1 249 dsbNotify = NULL;
rlm@1 250 CloseHandle(dsbEvent);
rlm@1 251 dsbEvent = NULL;
rlm@1 252 }
rlm@1 253 }
rlm@1 254 }
rlm@1 255
rlm@1 256 hr = dsbPrimary->Play(0, 0, DSBPLAY_LOOPING);
rlm@1 257
rlm@1 258 if (FAILED(hr))
rlm@1 259 {
rlm@1 260 // errorMessage(myLoadString(IDS_ERROR_SOUND_PLAYPRIM), hr);
rlm@1 261 systemMessage(IDS_CANNOT_PLAY_PRIMARY, "Cannot Play primary %08x", hr);
rlm@1 262 return false;
rlm@1 263 }
rlm@1 264
rlm@1 265 systemSoundOn = true;
rlm@1 266
rlm@1 267 return true;
rlm@1 268 }
rlm@1 269
rlm@1 270 void DirectSound::setSpeed(float rate)
rlm@1 271 {
rlm@1 272 if (dsbSecondary == NULL || wfx.nSamplesPerSec <= 0)
rlm@1 273 return;
rlm@1 274
rlm@1 275 if (rate != curRate)
rlm@1 276 {
rlm@1 277 curRate = rate;
rlm@1 278
rlm@1 279 if (rate > 4.0f)
rlm@1 280 rate = 4.0f;
rlm@1 281 if (rate < 0.06f)
rlm@1 282 rate = 0.06f;
rlm@1 283
rlm@1 284 dsbSecondary->SetFrequency((DWORD)((float)wfx.nSamplesPerSec * rate));
rlm@1 285 }
rlm@1 286 }
rlm@1 287
rlm@1 288 void DirectSound::pause()
rlm@1 289 {
rlm@1 290 if (dsbSecondary != NULL)
rlm@1 291 {
rlm@1 292 DWORD status = 0;
rlm@1 293 dsbSecondary->GetStatus(&status);
rlm@1 294
rlm@1 295 if (status & DSBSTATUS_PLAYING)
rlm@1 296 {
rlm@1 297 //systemScreenMessage("sound stopped (pause)!", 3);
rlm@1 298 dsbSecondary->Stop();
rlm@1 299 }
rlm@1 300 }
rlm@1 301 }
rlm@1 302
rlm@1 303 bool DirectSound::isPlaying()
rlm@1 304 {
rlm@1 305 if (dsbSecondary != NULL)
rlm@1 306 {
rlm@1 307 DWORD status = 0;
rlm@1 308 dsbSecondary->GetStatus(&status);
rlm@1 309
rlm@1 310 if (status & DSBSTATUS_PLAYING)
rlm@1 311 {
rlm@1 312 return true;
rlm@1 313 }
rlm@1 314 }
rlm@1 315 return false;
rlm@1 316 }
rlm@1 317
rlm@1 318 void DirectSound::reset()
rlm@1 319 {
rlm@1 320 if (dsbSecondary)
rlm@1 321 {
rlm@1 322 //systemScreenMessage("sound stopped (reset)!", 3);
rlm@1 323 dsbSecondary->Stop();
rlm@1 324 dsbSecondary->SetCurrentPosition(0);
rlm@1 325 }
rlm@1 326 }
rlm@1 327
rlm@1 328 void DirectSound::resume()
rlm@1 329 {
rlm@1 330 if (dsbSecondary != NULL)
rlm@1 331 {
rlm@1 332 dsbSecondary->Play(0, 0, DSBPLAY_LOOPING);
rlm@1 333 }
rlm@1 334 }
rlm@1 335
rlm@1 336 long linearFrameCount = 0;
rlm@1 337 long linearSoundByteCount = 0;
rlm@1 338 long linearSoundFrameCount = 0;
rlm@1 339
rlm@1 340 void DirectSound::write()
rlm@1 341 {
rlm@1 342 int len = soundBufferLen;
rlm@1 343 LPVOID lpvPtr1;
rlm@1 344 DWORD dwBytes1;
rlm@1 345 LPVOID lpvPtr2;
rlm@1 346 DWORD dwBytes2;
rlm@1 347
rlm@1 348 do
rlm@1 349 {
rlm@1 350 linearSoundByteCount += len;
rlm@1 351 if (wfx.nAvgBytesPerSec)
rlm@1 352 linearSoundFrameCount = 60 * linearSoundByteCount / wfx.nAvgBytesPerSec;
rlm@1 353
rlm@1 354 if (pDirectSound != NULL)
rlm@1 355 {
rlm@1 356 if (theApp.soundRecording)
rlm@1 357 {
rlm@1 358 if (dsbSecondary)
rlm@1 359 {
rlm@1 360 if (theApp.soundRecorder == NULL)
rlm@1 361 {
rlm@1 362 theApp.soundRecorder = new WavWriter;
rlm@1 363 WAVEFORMATEX format;
rlm@1 364 dsbSecondary->GetFormat(&format, sizeof(format), NULL);
rlm@1 365 if (theApp.soundRecorder->Open(theApp.soundRecordName))
rlm@1 366 theApp.soundRecorder->SetFormat(&format);
rlm@1 367 }
rlm@1 368 }
rlm@1 369
rlm@1 370 if (theApp.soundRecorder)
rlm@1 371 {
rlm@1 372 theApp.soundRecorder->AddSound((u8 *)soundFinalWave, len);
rlm@1 373 }
rlm@1 374 }
rlm@1 375
rlm@1 376 if (theApp.nvAudioLog)
rlm@1 377 {
rlm@1 378 NESVideoLoggingAudio((u8 *)soundFinalWave, wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels, len /
rlm@1 379 (wfx.nChannels * (wfx.wBitsPerSample / 8)));
rlm@1 380 }
rlm@1 381
rlm@1 382 // alternate avi record routine has been added in VBA.cpp
rlm@1 383 if (!theApp.altAviRecordMethod && theApp.aviRecording)
rlm@1 384 {
rlm@1 385 if (theApp.aviRecorder && !theApp.aviRecorder->IsPaused())
rlm@1 386 {
rlm@1 387 if (dsbSecondary)
rlm@1 388 {
rlm@1 389 if (!theApp.aviRecorder->IsSoundAdded())
rlm@1 390 {
rlm@1 391 WAVEFORMATEX format;
rlm@1 392 dsbSecondary->GetFormat(&format, sizeof(format), NULL);
rlm@1 393 theApp.aviRecorder->SetSoundFormat(&format);
rlm@1 394 }
rlm@1 395 }
rlm@1 396
rlm@1 397 theApp.aviRecorder->AddSound((u8 *)soundFinalWave, len);
rlm@1 398 }
rlm@1 399 }
rlm@1 400 }
rlm@1 401 }
rlm@1 402 while (linearSoundFrameCount <= linearFrameCount);
rlm@1 403
rlm@1 404 // arbitrarily wrap counters at 10000 frames to avoid mismatching wrap-around freeze
rlm@1 405 if (linearSoundFrameCount > 10000 && linearFrameCount > 10000)
rlm@1 406 {
rlm@1 407 linearFrameCount -= 10000;
rlm@1 408 linearSoundByteCount -= wfx.nAvgBytesPerSec * 10000 / 60;
rlm@1 409 linearSoundFrameCount = 60 * linearSoundByteCount / wfx.nAvgBytesPerSec;
rlm@1 410 }
rlm@1 411
rlm@1 412 if (!pDirectSound)
rlm@1 413 return;
rlm@1 414
rlm@1 415 HRESULT hr;
rlm@1 416
rlm@1 417 bool fastForward = speedup;
rlm@1 418 #if (defined(WIN32) && !defined(SDL))
rlm@1 419 fastForward |= theApp.frameSearchSkipping;
rlm@1 420 #endif
rlm@1 421
rlm@1 422 // slows down emulator to match up with the sound speed
rlm@1 423 if (!fastForward && synchronize && !(theApp.throttle > 100 && theApp.accuratePitchThrottle)
rlm@1 424 && theApp.throttle >= 6 && theApp.throttle <= 400)
rlm@1 425 {
rlm@1 426 DWORD status = 0;
rlm@1 427 hr = dsbSecondary->GetStatus(&status);
rlm@1 428 if (status & DSBSTATUS_PLAYING)
rlm@1 429 {
rlm@1 430 if (!soundPaused)
rlm@1 431 {
rlm@1 432 DWORD play;
rlm@1 433 while (true)
rlm@1 434 {
rlm@1 435 dsbSecondary->GetCurrentPosition(&play, NULL);
rlm@1 436
rlm@1 437 if (soundNextPosition + soundBufferLen < soundBufferTotalLen)
rlm@1 438 {
rlm@1 439 if (play < soundNextPosition
rlm@1 440 || play > soundNextPosition + soundBufferLen)
rlm@1 441 break;
rlm@1 442 }
rlm@1 443 else
rlm@1 444 {
rlm@1 445 if (play < soundNextPosition
rlm@1 446 && play > (soundNextPosition + soundBufferLen) % soundBufferTotalLen)
rlm@1 447 break;
rlm@1 448 }
rlm@1 449
rlm@1 450 if (dsbEvent)
rlm@1 451 {
rlm@1 452 WaitForSingleObject(dsbEvent, 50);
rlm@1 453 }
rlm@1 454 }
rlm@1 455 }
rlm@1 456 }
rlm@1 457 else
rlm@1 458 {
rlm@1 459 soundPaused = 1;
rlm@1 460 }
rlm@1 461 }
rlm@1 462
rlm@1 463 // Obtain memory address of write block. This will be in two parts
rlm@1 464 // if the block wraps around.
rlm@1 465 hr = dsbSecondary->Lock(soundNextPosition, soundBufferLen,
rlm@1 466 &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2,
rlm@1 467 0);
rlm@1 468
rlm@1 469 if (FAILED(hr))
rlm@1 470 {
rlm@1 471 char str [256];
rlm@1 472 sprintf(str, "Locking secondary failed with %d", hr);
rlm@1 473 systemScreenMessage(str);
rlm@1 474 }
rlm@1 475
rlm@1 476 // If DSERR_BUFFERLOST is returned, restore and retry lock.
rlm@1 477 if (DSERR_BUFFERLOST == hr)
rlm@1 478 {
rlm@1 479 dsbSecondary->Restore();
rlm@1 480 hr = dsbSecondary->Lock(soundNextPosition, soundBufferLen,
rlm@1 481 &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2,
rlm@1 482 0);
rlm@1 483 }
rlm@1 484
rlm@1 485 if (SUCCEEDED(hr))
rlm@1 486 {
rlm@1 487 if (theApp.muteFrameAdvance && theApp.winPauseNextFrame || theApp.winMuteForNow)
rlm@1 488 {
rlm@1 489 // Write 0 to pointers.
rlm@1 490 if (NULL != lpvPtr1)
rlm@1 491 ZeroMemory(lpvPtr1, dwBytes1);
rlm@1 492 if (NULL != lpvPtr2)
rlm@1 493 ZeroMemory(lpvPtr2, dwBytes2);
rlm@1 494 }
rlm@1 495 else
rlm@1 496 {
rlm@1 497 // Write to pointers.
rlm@1 498 if (NULL != lpvPtr1)
rlm@1 499 CopyMemory(lpvPtr1, soundFinalWave, dwBytes1);
rlm@1 500 if (NULL != lpvPtr2)
rlm@1 501 CopyMemory(lpvPtr2, soundFinalWave + dwBytes1, dwBytes2);
rlm@1 502 }
rlm@1 503
rlm@1 504 // Release the data back to DirectSound.
rlm@1 505 hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2,
rlm@1 506 dwBytes2);
rlm@1 507 }
rlm@1 508
rlm@1 509 soundNextPosition += soundBufferLen;
rlm@1 510 soundNextPosition %= soundBufferTotalLen;
rlm@1 511 }
rlm@1 512
rlm@1 513 void DirectSound::clearAudioBuffer()
rlm@1 514 {
rlm@1 515 LPVOID lpvPtr1;
rlm@1 516 DWORD dwBytes1;
rlm@1 517 LPVOID lpvPtr2;
rlm@1 518 DWORD dwBytes2;
rlm@1 519 HRESULT hr = dsbSecondary->Lock(0, soundBufferTotalLen, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
rlm@1 520 if (!FAILED(hr))
rlm@1 521 {
rlm@1 522 if (lpvPtr1)
rlm@1 523 memset(lpvPtr1, 0, dwBytes1);
rlm@1 524 if (lpvPtr2)
rlm@1 525 memset(lpvPtr2, 0, dwBytes2);
rlm@1 526 hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
rlm@1 527 }
rlm@1 528 }
rlm@1 529
rlm@1 530 ISound *newDirectSound()
rlm@1 531 {
rlm@1 532 return new DirectSound();
rlm@1 533 }
rlm@1 534