/* AudioDevice.cpp Written by Matthew Fisher AudioDevice plays wave files. */ AudioDevice::AudioDevice() { #ifdef USE_DIRECTX_AUDIO _Device = NULL; _MasteringVoice = NULL; #endif } AudioDevice::~AudioDevice() { FreeMemory(); } void AudioDevice::FreeMemory() { #ifdef USE_DIRECTX_AUDIO RemoveVoices(false); if(_MasteringVoice) { _MasteringVoice->DestroyVoice(); _MasteringVoice = NULL; } if(_Device) { _Device->Release(); _Device = NULL; } #endif } void AudioDevice::RemoveVoices(bool CompleteOnly) { #ifdef USE_DIRECTX_AUDIO XAUDIO2_VOICE_STATE State; for(int Index = 0; Index < int(_ActiveSourceVoices.Length()); Index++) { _ActiveSourceVoices[Index]->GetState( &State ); bool Running = ( State.BuffersQueued > 0); if(!Running || !CompleteOnly) { _ActiveSourceVoices[Index]->DestroyVoice(); _ActiveSourceVoices.RemoveSwap(Index); Index--; } } #endif } void AudioDevice::ResetAllSounds() { #ifdef USE_DIRECTX_AUDIO FreeMemory(); Init(); #endif } void AudioDevice::Init() { #ifdef USE_DIRECTX_AUDIO CoInitializeEx( NULL, COINIT_MULTITHREADED ); FreeMemory(); DWORD Flags = 0; //Flags |= XAUDIO2_DEBUG_ENGINE; _Device = NULL; HRESULT hr = XAudio2Create(&_Device, Flags); if(!SUCCEEDED(hr)) { Utility::MessageBox("Failed to initialize audio; try upgrading to the latest version of DirectX. Game will continue without sound."); } else { hr = _Device->CreateMasteringVoice(&_MasteringVoice); PersistentAssert(SUCCEEDED(hr), "CreateMasteringVoice failed"); } #endif } void AudioDevice::PlayWaveFile(WaveFile &File, bool LoopForever) { #ifdef USE_DIRECTX_AUDIO if(_Device == NULL) { return; } RemoveVoices(true); if(_ActiveSourceVoices.Length() > 4) { return; } // Get format of wave file WAVEFORMATEX& pwfx = File.Format(); // Create the source voice IXAudio2SourceVoice* _SourceVoice; HRESULT hr = _Device->CreateSourceVoice( &_SourceVoice, &pwfx ); Assert(SUCCEEDED(hr), "CreateSourceVoice failed"); _ActiveSourceVoices.PushEnd(_SourceVoice); // Submit the wave sample data using an XAUDIO2_BUFFER structure XAUDIO2_BUFFER buffer = {0}; buffer.pAudioData = (BYTE *)File.Data().CArray(); buffer.Flags = XAUDIO2_END_OF_STREAM; // tell the source voice not to expect any data after this buffer buffer.AudioBytes = File.Data().Length();// * sizeof(DWORD); if(LoopForever) { buffer.LoopBegin = 1; buffer.LoopLength = 0; buffer.LoopCount = XAUDIO2_LOOP_INFINITE; } hr = _SourceVoice->SubmitSourceBuffer( &buffer ); Assert(SUCCEEDED(hr), "SubmitSourceBuffer failed"); hr = _SourceVoice->Start( 0 ); Assert(SUCCEEDED(hr), "SubmitSourceBuffer failed"); //delete[] pbWaveData; //Sleep(3000); //_SourceVoice->DestroyVoice(); // Let the sound play /*BOOL isRunning = TRUE; while( SUCCEEDED( hr ) && isRunning ) { XAUDIO2_VOICE_STATE state; pSourceVoice->GetState( &state ); isRunning = ( state.BuffersQueued > 0 ) != 0; // Wait till the escape key is pressed if( GetAsyncKeyState( VK_ESCAPE ) ) break; Sleep( 10 ); } // Wait till the escape key is released while( GetAsyncKeyState( VK_ESCAPE ) ) Sleep( 10 ); pSourceVoice->DestroyVoice(); SAFE_DELETE_ARRAY( pbWaveData ); return hr;*/ #endif }