| 
									
										
										
										
											2015-05-24 06:55:12 +02:00
										 |  |  | // Copyright 2010 Dolphin Emulator Project
 | 
					
						
							| 
									
										
										
										
											2015-05-18 01:08:10 +02:00
										 |  |  | // Licensed under GPLv2+
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | #include <xaudio2.h>
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "AudioCommon/AudioCommon.h"
 | 
					
						
							|  |  |  | #include "AudioCommon/XAudio2Stream.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-14 01:15:23 +02:00
										 |  |  | #include "Common/Event.h"
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | #ifndef XAUDIO2_DLL
 | 
					
						
							|  |  |  | #error You are building this module against the wrong version of DirectX. You probably need to remove DXSDK_DIR from your include path.
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct StreamingVoiceContext : public IXAudio2VoiceCallback | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	CMixer* const m_mixer; | 
					
						
							|  |  |  | 	Common::Event& m_sound_sync_event; | 
					
						
							|  |  |  | 	IXAudio2SourceVoice* m_source_voice; | 
					
						
							|  |  |  | 	std::unique_ptr<BYTE[]> xaudio_buffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void SubmitBuffer(PBYTE buf_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	StreamingVoiceContext(IXAudio2 *pXAudio2, CMixer *pMixer, Common::Event& pSyncEvent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	~StreamingVoiceContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void StreamingVoiceContext::Stop(); | 
					
						
							|  |  |  | 	void StreamingVoiceContext::Play(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) {} | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {} | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnVoiceProcessingPassEnd) () {} | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnBufferStart) (void*) {} | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnLoopEnd) (void*) {} | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnStreamEnd) () {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	STDMETHOD_(void, OnBufferEnd) (void* context); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | const int NUM_BUFFERS = 3; | 
					
						
							|  |  |  | const int SAMPLES_PER_BUFFER = 96; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | const int NUM_CHANNELS = 2; | 
					
						
							|  |  |  | const int BUFFER_SIZE = SAMPLES_PER_BUFFER * NUM_CHANNELS; | 
					
						
							|  |  |  | const int BUFFER_SIZE_BYTES = BUFFER_SIZE * sizeof(s16); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | void StreamingVoiceContext::SubmitBuffer(PBYTE buf_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	XAUDIO2_BUFFER buf = {}; | 
					
						
							|  |  |  | 	buf.AudioBytes = BUFFER_SIZE_BYTES; | 
					
						
							|  |  |  | 	buf.pContext = buf_data; | 
					
						
							|  |  |  | 	buf.pAudioData = buf_data; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_source_voice->SubmitSourceBuffer(&buf); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | StreamingVoiceContext::StreamingVoiceContext(IXAudio2 *pXAudio2, CMixer *pMixer, Common::Event& pSyncEvent) | 
					
						
							|  |  |  | 	: m_mixer(pMixer) | 
					
						
							|  |  |  | 	, m_sound_sync_event(pSyncEvent) | 
					
						
							|  |  |  | 	, xaudio_buffer(new BYTE[NUM_BUFFERS * BUFFER_SIZE_BYTES]()) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	WAVEFORMATEXTENSIBLE wfx = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 	wfx.Format.wFormatTag       = WAVE_FORMAT_EXTENSIBLE; | 
					
						
							|  |  |  | 	wfx.Format.nSamplesPerSec   = m_mixer->GetSampleRate(); | 
					
						
							|  |  |  | 	wfx.Format.nChannels        = 2; | 
					
						
							|  |  |  | 	wfx.Format.wBitsPerSample   = 16; | 
					
						
							|  |  |  | 	wfx.Format.nBlockAlign      = wfx.Format.nChannels*wfx.Format.wBitsPerSample / 8; | 
					
						
							|  |  |  | 	wfx.Format.nAvgBytesPerSec  = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; | 
					
						
							|  |  |  | 	wfx.Format.cbSize           = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	wfx.Samples.wValidBitsPerSample = 16; | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | 	wfx.dwChannelMask           = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; | 
					
						
							|  |  |  | 	wfx.SubFormat               = KSDATAFORMAT_SUBTYPE_PCM; | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// create source voice
 | 
					
						
							|  |  |  | 	HRESULT hr; | 
					
						
							|  |  |  | 	if (FAILED(hr = pXAudio2->CreateSourceVoice(&m_source_voice, &wfx.Format, XAUDIO2_VOICE_NOSRC, 1.0f, this))) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-06-04 13:23:58 +02:00
										 |  |  | 		PanicAlert("XAudio2 CreateSourceVoice failed: %#X", hr); | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_source_voice->Start(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	// start buffers with silence
 | 
					
						
							|  |  |  | 	for (int i = 0; i != NUM_BUFFERS; ++i) | 
					
						
							|  |  |  | 		SubmitBuffer(xaudio_buffer.get() + (i * BUFFER_SIZE_BYTES)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | StreamingVoiceContext::~StreamingVoiceContext() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_source_voice) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_source_voice->Stop(); | 
					
						
							|  |  |  | 		m_source_voice->DestroyVoice(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | void StreamingVoiceContext::Stop() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_source_voice) | 
					
						
							|  |  |  | 		m_source_voice->Stop(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | void StreamingVoiceContext::Play() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_source_voice) | 
					
						
							|  |  |  | 		m_source_voice->Start(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | void StreamingVoiceContext::OnBufferEnd(void* context) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	//  buffer end callback; gets SAMPLES_PER_BUFFER samples for a new buffer
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!m_source_voice || !context) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	//m_sound_sync_event->Wait(); // sync
 | 
					
						
							|  |  |  | 	//m_sound_sync_event->Spin(); // or tight sync
 | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_mixer->Mix(static_cast<short*>(context), SAMPLES_PER_BUFFER); | 
					
						
							|  |  |  | 	SubmitBuffer(static_cast<BYTE*>(context)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | HMODULE XAudio2::m_xaudio2_dll = nullptr; | 
					
						
							|  |  |  | typedef decltype(&XAudio2Create) XAudio2Create_t; | 
					
						
							|  |  |  | void *XAudio2::PXAudio2Create = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool XAudio2::InitLibrary() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_xaudio2_dll) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_xaudio2_dll = ::LoadLibrary(XAUDIO2_DLL); | 
					
						
							|  |  |  | 	if (!m_xaudio2_dll) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PXAudio2Create) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PXAudio2Create = (XAudio2Create_t)::GetProcAddress(m_xaudio2_dll, "XAudio2Create"); | 
					
						
							|  |  |  | 		if (!PXAudio2Create) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			::FreeLibrary(m_xaudio2_dll); | 
					
						
							|  |  |  | 			m_xaudio2_dll = nullptr; | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-24 04:13:02 -04:00
										 |  |  | XAudio2::XAudio2() | 
					
						
							|  |  |  | 	: m_mastering_voice(nullptr) | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | 	, m_volume(1.0f) | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 	, m_cleanup_com(SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED))) | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | XAudio2::~XAudio2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Stop(); | 
					
						
							|  |  |  | 	if (m_cleanup_com) | 
					
						
							|  |  |  | 		CoUninitialize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | bool XAudio2::Start() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	HRESULT hr; | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 21:28:27 -05:00
										 |  |  | 	// callback doesn't seem to run on a specific CPU anyways
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	IXAudio2* xaudptr; | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | 	if (FAILED(hr = ((XAudio2Create_t)PXAudio2Create)(&xaudptr, 0, XAUDIO2_DEFAULT_PROCESSOR))) | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-06-04 13:23:58 +02:00
										 |  |  | 		PanicAlert("XAudio2 init failed: %#X", hr); | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 		Stop(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	m_xaudio2 = std::unique_ptr<IXAudio2, Releaser>(xaudptr); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	// XAudio2 master voice
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 	// XAUDIO2_DEFAULT_CHANNELS instead of 2 for expansion?
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	if (FAILED(hr = m_xaudio2->CreateMasteringVoice(&m_mastering_voice, 2, m_mixer->GetSampleRate()))) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-06-04 13:23:58 +02:00
										 |  |  | 		PanicAlert("XAudio2 master voice creation failed: %#X", hr); | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 		Stop(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Volume
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_mastering_voice->SetVolume(m_volume); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_voice_context = std::unique_ptr<StreamingVoiceContext> | 
					
						
							| 
									
										
										
										
											2015-05-24 04:13:02 -04:00
										 |  |  | 		(new StreamingVoiceContext(m_xaudio2.get(), m_mixer.get(), m_sound_sync_event)); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XAudio2::SetVolume(int volume) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	//linear 1- .01
 | 
					
						
							| 
									
										
										
										
											2010-12-29 13:07:00 +00:00
										 |  |  | 	m_volume = (float)volume / 100.f; | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	if (m_mastering_voice) | 
					
						
							|  |  |  | 		m_mastering_voice->SetVolume(m_volume); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XAudio2::Update() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	//m_sound_sync_event.Set();
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	//static int xi = 0;
 | 
					
						
							|  |  |  | 	//if (100000 == ++xi)
 | 
					
						
							|  |  |  | 	//{
 | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 	//    xi = 0;
 | 
					
						
							|  |  |  | 	//    XAUDIO2_PERFORMANCE_DATA perfData;
 | 
					
						
							|  |  |  | 	//    pXAudio2->GetPerformanceData(&perfData);
 | 
					
						
							|  |  |  | 	//    NOTICE_LOG(DSPHLE, "XAudio2 latency (samples): %i", perfData.CurrentLatencyInSamples);
 | 
					
						
							|  |  |  | 	//    NOTICE_LOG(DSPHLE, "XAudio2 total glitches: %i", perfData.GlitchesSinceEngineStarted);
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 	//}
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XAudio2::Clear(bool mute) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_muted = mute; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	if (m_voice_context) | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (m_muted) | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 			m_voice_context->Stop(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 			m_voice_context->Play(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XAudio2::Stop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	//m_sound_sync_event.Set();
 | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	m_voice_context.reset(); | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 23:09:12 +00:00
										 |  |  | 	if (m_mastering_voice) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_mastering_voice->DestroyVoice(); | 
					
						
							|  |  |  | 		m_mastering_voice = nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 23:51:41 -05:00
										 |  |  | 	m_xaudio2.reset(); // release interface
 | 
					
						
							| 
									
										
										
										
											2013-10-19 02:27:57 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (m_xaudio2_dll) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		::FreeLibrary(m_xaudio2_dll); | 
					
						
							|  |  |  | 		m_xaudio2_dll = nullptr; | 
					
						
							|  |  |  | 		PXAudio2Create = nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-11-14 23:56:26 +00:00
										 |  |  | } |