static void XAUDIO2_CloseDevice(_THIS) { if (_this->hidden != NULL) { IXAudio2 *ixa2 = _this->hidden->ixa2; IXAudio2SourceVoice *source = _this->hidden->source; IXAudio2MasteringVoice *mastering = _this->hidden->mastering; if (source != NULL) { source->Stop(); source->FlushSourceBuffers(); source->DestroyVoice(); } if (ixa2 != NULL) { ixa2->StopEngine(); } if (mastering != NULL) { mastering->DestroyVoice(); } if (ixa2 != NULL) { ixa2->Release(); } SDL_free(_this->hidden->mixbuf); if (_this->hidden->semaphore != NULL) { CloseHandle(_this->hidden->semaphore); } SDL_free(_this->hidden); _this->hidden = NULL; } }
void GameAudio::stopMusic(MusicTypes musicType) { if (musicRegistrationMap[musicType] == true) { IXAudio2SourceVoice *sourceVoice = musicMap[musicType]; sourceVoice->Stop(); sourceVoice->FlushSourceBuffers(); } }
void XAudio2_Output::reset() { if( !initialized || failed ) return; if( playing ) { HRESULT hr = sVoice->Stop( 0 ); ASSERT( hr == S_OK ); } sVoice->FlushSourceBuffers(); sVoice->Start( 0 ); playing = true; }
static void XAUDIO2_PlayDevice(_THIS) { XAUDIO2_BUFFER buffer; Uint8 *mixbuf = _this->hidden->mixbuf; Uint8 *nextbuf = _this->hidden->nextbuf; const int mixlen = _this->hidden->mixlen; IXAudio2SourceVoice *source = _this->hidden->source; HRESULT result = S_OK; if (!_this->enabled) { /* shutting down? */ return; } /* Submit the next filled buffer */ SDL_zero(buffer); buffer.AudioBytes = mixlen; buffer.pAudioData = nextbuf; buffer.pContext = _this; buffer.LoopCount = 1; if (nextbuf == mixbuf) { nextbuf += mixlen; } else { nextbuf = mixbuf; } _this->hidden->nextbuf = nextbuf; result = source->SubmitSourceBuffer(&buffer); if (result == XAUDIO2_E_DEVICE_INVALIDATED) { /* !!! FIXME: possibly disconnected or temporary lost. Recover? */ } if (result != S_OK) { /* uhoh, panic! */ source->FlushSourceBuffers(); _this->enabled = 0; } }
//the streaming thread procedure DWORD WINAPI StreamProc(LPVOID pContext) { //required by XAudio2 CoInitializeEx(NULL, COINIT_MULTITHREADED); if(pContext == NULL) { CoUninitialize(); return -1; } StreamContext* sc = (StreamContext*)pContext; //instantiate the voice's callback class StreamingVoiceCallback callback; //load a file for streaming, non-buffered disk reads (no system cacheing) StreamingWave inFile; if(!inFile.load(sc->filename)) { SetEvent(sc->VoiceLoadEvent); CoUninitialize(); return -3; } //create the voice IXAudio2SourceVoice* source = NULL; if(FAILED(XAudio2->CreateSourceVoice(&source, &inFile.waveFormat.Format, 0, 2.0f, &callback))) { SetEvent(sc->VoiceLoadEvent); CoUninitialize(); return -5; } //fill and queue the maximum number of buffers (except the one needed for reading new wave data) bool somethingsWrong = false; XAUDIO2_VOICE_STATE voiceState = {0}; source->GetState(&voiceState); while(voiceState.BuffersQueued < STREAMINGWAVE_BUFFER_COUNT - 1 && !somethingsWrong) { //read and fill the next buffer to present switch(inFile.prepare()) { case StreamingWave::PR_EOF: //if end of file, loop the file read inFile.resetFile(); //intentionally fall-through to loop sound case StreamingWave::PR_SUCCESS: //present the next available buffer inFile.swap(); //submit another buffer source->SubmitSourceBuffer(inFile.buffer()); source->GetState(&voiceState); break; case StreamingWave::PR_FAILURE: somethingsWrong = true; break; } } //return the created voice through the context pointer sc->pVoice = &source; //signal that the voice has prepared for streaming, and ready to start SetEvent(sc->VoiceLoadEvent); //group the events for the Wait function HANDLE Events[2] = {callback.BufferEndEvent, QuitEvent}; bool quitting = false; while(!quitting) { //wait until either the source voice is ready for another buffer, or the abort signal is set DWORD eventFired = WaitForMultipleObjects(2, Events, FALSE, INFINITE); switch(eventFired) { case 0: //buffer ended event for source voice //reset the event manually ResetEvent(Events[0]); //make sure there's a full number of buffers source->GetState(&voiceState); while(voiceState.BuffersQueued < STREAMINGWAVE_BUFFER_COUNT - 1 && !somethingsWrong) { //read and fill the next buffer to present switch(inFile.prepare()) { case StreamingWave::PR_EOF: //if end of file, loop the file read inFile.resetFile(); //intentionally fall-through to loop sound case StreamingWave::PR_SUCCESS: //present the next available buffer inFile.swap(); //submit another buffer source->SubmitSourceBuffer(inFile.buffer()); source->GetState(&voiceState); break; case StreamingWave::PR_FAILURE: somethingsWrong = true; break; } } break; default: //something's wrong... quitting = true; } } //stop and destroy the voice source->Stop(); source->FlushSourceBuffers(); source->DestroyVoice(); //close the streaming wave file; //this is done automatically in the class destructor, //so this is redundant inFile.close(); //cleanup CoUninitialize(); return 0; }
void Sound::playSoundEffect(SoundEffect effect, X3DAUDIO_EMITTER* emit) { IXAudio2SourceVoice* voice = getSFXVoice(); voice->FlushSourceBuffers(); switch (effect) { case SFX_LASER: { voice->SubmitSourceBuffer(laserBufferDetails, laserWMABuffer); break; } case SFX_CRASH: { voice->SubmitSourceBuffer(crashBufferDetails, crashWMABuffer); break; } case SFX_BOOST: { voice->SubmitSourceBuffer(boostBufferDetails, boostWMABuffer); break; } case SFX_DROPMINE: { voice->SubmitSourceBuffer(dropmineBufferDetails, dropmineWMABuffer); break; } case SFX_SCREAM: { // Now pick one of the three screams randomly int choice = std::rand() % 3; voice->SetVolume(2.0f); switch (choice) { case 0: voice->SubmitSourceBuffer(scream1BufferDetails, scream1WMABuffer); break; case 1: voice->SubmitSourceBuffer(scream2BufferDetails, scream2WMABuffer); break; case 2: voice->SubmitSourceBuffer(scream3BufferDetails, scream3WMABuffer); break; default: voice->SubmitSourceBuffer(scream1BufferDetails, scream1WMABuffer); } break; } case SFX_CAREXPLODE: { voice->SetVolume(2.0f); voice->SubmitSourceBuffer(carexplodeBufferDetails, carexplodeWMABuffer); break; } case SFX_EXPLOSION: { voice->SubmitSourceBuffer(explosionBufferDetails, explosionWMABuffer); break; } case SFX_BEEP: { voice->SubmitSourceBuffer(beepBufferDetails, beepWMABuffer); break; } case SFX_ROCKETLAUNCH: { voice->SubmitSourceBuffer(rocketlaunchBufferDetails, rocketlaunchWMABuffer); break; } case SFX_PICKUP: { voice->SetVolume(2.0f); voice->SubmitSourceBuffer(pickupBufferDetails, pickupWMABuffer); break; } case SFX_SELECT: { voice->SubmitSourceBuffer(selectBufferDetails, selectWMABuffer); break; } case SFX_SHOTGUN: { voice->SetVolume(2.5f); voice->SubmitSourceBuffer(shotgunBufferDetails, shotgunWMABuffer); break; } case SFX_TAKENLEAD: { voice->SubmitSourceBuffer(takenleadBufferDetails, takenleadWMABuffer); break; } case SFX_LOSTLEAD: { voice->SubmitSourceBuffer(lostleadBufferDetails, lostleadWMABuffer); break; } case SFX_NOAMMO: { voice->SubmitSourceBuffer(noammoBufferDetails, noammoWMABuffer); break; } case SFX_ONE: { voice->SubmitSourceBuffer(oneBufferDetails, oneWMABuffer); break; } case SFX_TWO: { voice->SubmitSourceBuffer(twoBufferDetails, twoWMABuffer); break; } case SFX_THREE: { voice->SubmitSourceBuffer(threeBufferDetails, threeWMABuffer); break; } default: break; } X3DAudioCalculate(audio3DHandle, &listener, emit, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT, &dspSettings); voice->SetOutputMatrix(smSFX, 1, details.OutputFormat.Format.nChannels, dspSettings.pMatrixCoefficients); voice->SetFrequencyRatio(dspSettings.DopplerFactor); XAUDIO2_FILTER_PARAMETERS filterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; voice->SetFilterParameters(&filterParameters); voice->Start(); }