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;
_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;
}
WAVEFORMATEX& pwfx = File.Format();
IXAudio2SourceVoice* _SourceVoice;
HRESULT hr = _Device->CreateSourceVoice( &_SourceVoice, &pwfx );
Assert(SUCCEEDED(hr), "CreateSourceVoice failed");
_ActiveSourceVoices.PushEnd(_SourceVoice);
XAUDIO2_BUFFER buffer = {0};
buffer.pAudioData = (BYTE *)File.Data().CArray();
buffer.Flags = XAUDIO2_END_OF_STREAM; buffer.AudioBytes = File.Data().Length();
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");
#endif
}