Path: blob/master/RSDKv5/RSDK/Audio/XAudio/XAudioDevice.cpp
1168 views
12// allows generic string literal stuff3#include <tchar.h>45uint8 AudioDevice::contextInitialized;67IXAudio2 *AudioDevice::audioContext;8IXAudio2MasteringVoice *AudioDevice::masteringVoice;9IXAudio2SourceVoice *AudioDevice::sourceVoice;10AudioDeviceCallback AudioDevice::voiceCallback;11AudioEngineCallback AudioDevice::engineCallback;1213RTL_CRITICAL_SECTION AudioDevice::criticalSection;1415int32 AudioDevice::mixBufferID = 0;16float AudioDevice::mixBuffer[3][MIX_BUFFER_SIZE];1718bool32 AudioDevice::Init()19{20if (!contextInitialized) {21contextInitialized = true;22InitAudioChannels();2324CoInitializeEx(NULL, 0);25}2627audioState = false;28if (!audioContext) {29if (SUCCEEDED(InitContext())) {30if (SUCCEEDED(audioContext->CreateMasteringVoice(&masteringVoice, 0, 0, 0, NULL, NULL))) {31WAVEFORMATEX format;32format.cbSize = 0;33format.wBitsPerSample = sizeof(SAMPLE_FORMAT) * 8;34format.nChannels = AUDIO_CHANNELS;35format.nBlockAlign = (format.nChannels * format.wBitsPerSample) / 8;36format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;37format.nSamplesPerSec = AUDIO_FREQUENCY;38format.nAvgBytesPerSec = AUDIO_FREQUENCY * AUDIO_CHANNELS * sizeof(SAMPLE_FORMAT);3940if (SUCCEEDED(audioContext->CreateSourceVoice(&sourceVoice, &format, 0, 2.0, &voiceCallback, NULL, NULL))) {41sourceVoice->Start(0, XAUDIO2_COMMIT_NOW);42InitMixBuffer();43audioState = true;44}45else {46#if RETRO_RENDERDEVICE_DIRECTX9 || RETRO_RENDERDEVICE_DIRECTX1147if (videoSettings.windowed) {48MessageBox(RenderDevice::windowHandle, _T("Unable to create source voice. Sound will not be available during this session."),49_T("AudioDevice::Init"), MB_OK);50}51#endif52}53}54else {55#if RETRO_RENDERDEVICE_DIRECTX9 || RETRO_RENDERDEVICE_DIRECTX1156if (videoSettings.windowed) {57MessageBox(RenderDevice::windowHandle, _T("Unable to create mastering voice. Sound will not be available during this session."),58_T("AudioDevice::Init"), MB_OK);59}60#endif6162if (audioContext) {63audioContext->Release();64audioContext = NULL;65}66}67}68else {69#if RETRO_RENDERDEVICE_DIRECTX9 || RETRO_RENDERDEVICE_DIRECTX1170if (videoSettings.windowed) {71MessageBox(RenderDevice::windowHandle,72_T("Error Initializing XAudio2.\n"73"You may need to install the Jun 2010 DirectX update to have the XAudio Drivers.\n"74"Sound will not be available during this session."),75_T("AudioDevice::Init"), MB_OK);76}77#endif78}79}8081return true;82}8384void AudioDevice::Release()85{86if (sourceVoice)87sourceVoice->DestroyVoice();88if (masteringVoice)89masteringVoice->DestroyVoice();90if (audioContext)91audioContext->Release();9293AudioDeviceBase::Release();9495CoUninitialize();96DeleteCriticalSection(&AudioDevice::criticalSection);97}9899void AudioDevice::FrameInit()100{101if (audioState > 2 && --audioState == 2) {102if (sourceVoice) {103sourceVoice->DestroyVoice();104sourceVoice = NULL;105}106107if (masteringVoice) {108masteringVoice->DestroyVoice();109masteringVoice = NULL;110}111112audioContext->StopEngine();113114Sleep(1000);115116if (audioContext)117audioContext->Release();118audioContext = NULL;119120Init();121}122}123124void AudioDevice::HandleStreamLoad(ChannelInfo *channel, bool32 async)125{126if (async) {127DWORD threadId;128HANDLE thread = CreateThread(NULL, 0, LoadStreamASync, channel, 0, &threadId);129CloseHandle(thread);130}131else {132LoadStream(channel);133}134}135136HRESULT AudioDevice::InitContext()137{138IXAudio2 *context = nullptr;139140HRESULT res = XAudio2Create(&context, 0, XAUDIO2_DEFAULT_PROCESSOR);141if (SUCCEEDED(res)) {142res = context->StartEngine();143if (FAILED(res))144context->Release();145else146audioContext = context;147}148149return res;150}151152void AudioDevice::InitAudioChannels()153{154InitializeCriticalSection(&AudioDevice::criticalSection);155156AudioDeviceBase::InitAudioChannels();157}158159void AudioDevice::InitMixBuffer()160{161void *mixBuffer = AudioDevice::mixBuffer[AudioDevice::mixBufferID];162163XAUDIO2_BUFFER buffer;164memset(&buffer, 0, sizeof(buffer));165buffer.pAudioData = (BYTE *)mixBuffer;166buffer.pContext = 0;167buffer.AudioBytes = MIX_BUFFER_SIZE * sizeof(SAMPLE_FORMAT);168169AudioDevice::mixBufferID = ((AudioDevice::mixBufferID) + 1) % 3;170171AudioDevice::sourceVoice->SubmitSourceBuffer(&buffer, NULL);172AudioDevice::audioContext->RegisterForCallbacks(&engineCallback);173}174175void AudioEngineCallback::OnCriticalError(HRESULT Error) { AudioDevice::audioState = 30; }176177void AudioDeviceCallback::OnBufferEnd(void *pBufferContext)178{179XAUDIO2_VOICE_STATE state;180AudioDevice::sourceVoice->GetState(&state);181182if (state.BuffersQueued < 2) {183void *mixBuffer = AudioDevice::mixBuffer[AudioDevice::mixBufferID];184185LockAudioDevice();186AudioDevice::ProcessAudioMixing(mixBuffer, MIX_BUFFER_SIZE);187UnlockAudioDevice();188189XAUDIO2_BUFFER buffer;190memset(&buffer, 0, sizeof(buffer));191buffer.pAudioData = (BYTE *)mixBuffer;192buffer.pContext = 0;193buffer.AudioBytes = MIX_BUFFER_SIZE * sizeof(SAMPLE_FORMAT);194195AudioDevice::mixBufferID = ((AudioDevice::mixBufferID) + 1) % 3;196197AudioDevice::sourceVoice->SubmitSourceBuffer(&buffer, NULL);198}199}200201