diff options
author | 2016-03-12 12:31:13 +0100 | |
---|---|---|
committer | 2016-03-12 12:31:13 +0100 | |
commit | a026a582f1a0ea8c1ede3acaddacef506ef3f3b0 (patch) | |
tree | e31573822f2359677de519f9f3b600d98e8764cd /src/osd/modules/sound/xaudio2_sound.cpp | |
parent | 477d2abd43984f076b7e45f5527591fa8fd0d241 (diff) | |
parent | dcab55bf53b94713a6f72e9633f5101c8dd6c08c (diff) |
Merge pull request #15 from mamedev/master
Sync to base master
Diffstat (limited to 'src/osd/modules/sound/xaudio2_sound.cpp')
-rw-r--r-- | src/osd/modules/sound/xaudio2_sound.cpp | 141 |
1 files changed, 55 insertions, 86 deletions
diff --git a/src/osd/modules/sound/xaudio2_sound.cpp b/src/osd/modules/sound/xaudio2_sound.cpp index 9dc3d0461be..e09d87aa6c6 100644 --- a/src/osd/modules/sound/xaudio2_sound.cpp +++ b/src/osd/modules/sound/xaudio2_sound.cpp @@ -9,26 +9,17 @@ #include "sound_module.h" #include "modules/osdmodule.h" -#if (defined(OSD_WINDOWS) && USE_XAUDIO2) +#if defined(OSD_WINDOWS) // standard windows headers #define WIN32_LEAN_AND_MEAN #include <windows.h> -#include <mutex> -#pragma warning( push ) -#pragma warning( disable: 4068 ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wattributes" // XAudio2 include #include <xaudio2.h> -#pragma GCC diagnostic pop -#pragma warning( pop ) - - -#include <mmsystem.h> // stdlib includes +#include <mutex> #include <thread> #include <queue> @@ -37,7 +28,8 @@ // MAME headers #include "emu.h" #include "osdepend.h" -#include "emuopts.h" + +#include "winutil.h" //============================================================ // Constants @@ -133,7 +125,7 @@ typedef std::unique_ptr<IXAudio2MasteringVoice, xaudio2_custom_deleter> masterin typedef std::unique_ptr<IXAudio2SourceVoice, xaudio2_custom_deleter> src_voice_ptr; // Typedef for pointer to XAudio2Create -typedef HRESULT(__stdcall* PFN_XAUDIO2CREATE)(IXAudio2**, UINT32, XAUDIO2_PROCESSOR); +typedef lazy_loaded_function_p3<HRESULT, IXAudio2**, UINT32, XAUDIO2_PROCESSOR> xaudio2_create_ptr; //============================================================ // Helper classes @@ -196,6 +188,8 @@ public: class sound_xaudio2 : public osd_module, public sound_module, public IXAudio2VoiceCallback { private: + const wchar_t* XAUDIO_DLLS[2] = { L"XAudio2_9.dll", L"XAudio2_8.dll" }; + xaudio2_ptr m_xAudio2; mastering_voice_ptr m_masterVoice; src_voice_ptr m_sourceVoice; @@ -211,11 +205,10 @@ private: std::thread m_audioThread; std::queue<xaudio2_buffer> m_queue; std::unique_ptr<bufferpool> m_buffer_pool; - HMODULE m_xaudio2_module; - PFN_XAUDIO2CREATE m_pfnxaudio2create; UINT32 m_overflows; UINT32 m_underflows; BOOL m_in_underflow; + xaudio2_create_ptr XAudio2Create; public: sound_xaudio2() : @@ -229,56 +222,73 @@ public: m_buffer_size(0), m_buffer_count(0), m_writepos(0), - m_hEventBufferCompleted(NULL), - m_hEventDataAvailable(NULL), - m_hEventExiting(NULL), + m_hEventBufferCompleted(nullptr), + m_hEventDataAvailable(nullptr), + m_hEventExiting(nullptr), m_buffer_pool(nullptr), - m_xaudio2_module(NULL), - m_pfnxaudio2create(nullptr), m_overflows(0), m_underflows(0), - m_in_underflow(FALSE) + m_in_underflow(FALSE), + XAudio2Create("XAudio2Create", XAUDIO_DLLS, ARRAY_LENGTH(XAUDIO_DLLS)) { } - virtual int init(osd_options const &options) override; - virtual void exit() override; + bool probe() override; + int init(osd_options const &options) override; + void exit() override; // sound_module - virtual void update_audio_stream(bool is_throttled, INT16 const *buffer, int samples_this_frame) override; - virtual void set_mastervolume(int attenuation) override; + void update_audio_stream(bool is_throttled, INT16 const *buffer, int samples_this_frame) override; + void set_mastervolume(int attenuation) override; // Xaudio callbacks - void OnVoiceProcessingPassStart(UINT32 bytes_required) override; - void OnVoiceProcessingPassEnd() override {} - void OnStreamEnd() override {} - void OnBufferStart(void* pBufferContext) override {} - void OnLoopEnd(void* pBufferContext) override {} - void OnVoiceError(void* pBufferContext, HRESULT error) override {} - void OnBufferEnd(void *pBufferContext) override; + void STDAPICALLTYPE OnVoiceProcessingPassStart(UINT32 bytes_required) override; + void STDAPICALLTYPE OnVoiceProcessingPassEnd() override {} + void STDAPICALLTYPE OnStreamEnd() override {} + void STDAPICALLTYPE OnBufferStart(void* pBufferContext) override {} + void STDAPICALLTYPE OnLoopEnd(void* pBufferContext) override {} + void STDAPICALLTYPE OnVoiceError(void* pBufferContext, HRESULT error) override {} + void STDAPICALLTYPE OnBufferEnd(void *pBufferContext) override; private: void create_buffers(const WAVEFORMATEX &format); HRESULT create_voices(const WAVEFORMATEX &format); void process_audio(); - void submit_buffer(std::unique_ptr<BYTE[]> audioData, DWORD audioLength); + void submit_buffer(std::unique_ptr<BYTE[]> audioData, DWORD audioLength) const; void submit_needed(); - HRESULT xaudio2_create(IXAudio2 ** xaudio2_interface); void roll_buffer(); BOOL submit_next_queued(); }; //============================================================ +// probe +//============================================================ + +bool sound_xaudio2::probe() +{ + int status = XAudio2Create.initialize(); + return status == 0; +} + +//============================================================ // init //============================================================ int sound_xaudio2::init(osd_options const &options) { - HRESULT result = S_OK; + HRESULT result; + + // Make sure our XAudio2Create entrypoint is bound + int status = XAudio2Create.initialize(); + if (status != 0) + { + osd_printf_error("Could not find XAudio2 library\n"); + return 1; + } // Create the IXAudio2 object IXAudio2 *temp_xaudio2 = nullptr; - HR_RET1(xaudio2_create(&temp_xaudio2)); + HR_RET1(this->XAudio2Create(&temp_xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)); m_xAudio2 = xaudio2_ptr(temp_xaudio2); // make a format description for what we want @@ -292,20 +302,13 @@ int sound_xaudio2::init(osd_options const &options) m_sample_bytes = format.nBlockAlign; -#if defined(_DEBUG) - XAUDIO2_DEBUG_CONFIGURATION debugConfig = { 0 }; - debugConfig.TraceMask = XAUDIO2_LOG_WARNINGS | XAUDIO2_LOG_TIMING | XAUDIO2_LOG_STREAMING; - debugConfig.LogFunctionName = TRUE; - m_xAudio2->SetDebugConfiguration(&debugConfig); -#endif - // Create the buffers create_buffers(format); // Initialize our events - m_hEventBufferCompleted = CreateEvent(NULL, FALSE, FALSE, NULL); - m_hEventDataAvailable = CreateEvent(NULL, FALSE, FALSE, NULL); - m_hEventExiting = CreateEvent(NULL, FALSE, FALSE, NULL); + m_hEventBufferCompleted = CreateEvent(nullptr, FALSE, FALSE, nullptr); + m_hEventDataAvailable = CreateEvent(nullptr, FALSE, FALSE, nullptr); + m_hEventExiting = CreateEvent(nullptr, FALSE, FALSE, nullptr); // create the voices and start them HR_RET1(create_voices(format)); @@ -413,7 +416,7 @@ void sound_xaudio2::set_mastervolume(int attenuation) // The XAudio2 voice callback triggered when a buffer finishes playing void sound_xaudio2::OnBufferEnd(void *pBufferContext) { - BYTE* completed_buffer = (BYTE*)pBufferContext; + BYTE* completed_buffer = static_cast<BYTE*>(pBufferContext); if (completed_buffer != nullptr) { std::lock_guard<std::mutex> lock(m_buffer_lock); @@ -447,40 +450,6 @@ void sound_xaudio2::OnVoiceProcessingPassStart(UINT32 bytes_required) } //============================================================ -// xaudio2_create -//============================================================ - -// Dynamically loads the XAudio2 DLL and calls the exported XAudio2Create() -HRESULT sound_xaudio2::xaudio2_create(IXAudio2 ** ppxaudio2_interface) -{ - HRESULT result; - - if (nullptr == m_pfnxaudio2create) - { - if (nullptr == m_xaudio2_module) - { - m_xaudio2_module = LoadLibrary(XAUDIO2_DLL); - if (nullptr == m_xaudio2_module) - { - osd_printf_error("Failed to load module '%S', error: 0x%X\n", XAUDIO2_DLL, (unsigned int)GetLastError()); - HR_RETHR(E_FAIL); - } - } - - m_pfnxaudio2create = (PFN_XAUDIO2CREATE)GetProcAddress(m_xaudio2_module, "XAudio2Create"); - if (nullptr == m_pfnxaudio2create) - { - osd_printf_error("Failed to get adddress of exported function XAudio2Create, error: 0x%X\n", (unsigned int)GetLastError()); - HR_RETHR(E_FAIL); - } - } - - HR_RETHR(m_pfnxaudio2create(ppxaudio2_interface, 0, XAUDIO2_DEFAULT_PROCESSOR)); - - return S_OK; -} - -//============================================================ // create_buffers //============================================================ @@ -510,9 +479,9 @@ void sound_xaudio2::create_buffers(const WAVEFORMATEX &format) osd_printf_verbose( "Sound: XAudio2 created initial buffers. total size: %u, count %u, size each %u\n", - (unsigned int)total_buffer_size, - (unsigned int)m_buffer_count, - (unsigned int)m_buffer_size); + static_cast<unsigned int>(total_buffer_size), + static_cast<unsigned int>(m_buffer_count), + static_cast<unsigned int>(m_buffer_size)); // reset buffer states m_writepos = 0; @@ -608,7 +577,7 @@ void sound_xaudio2::submit_needed() // submit_buffer //============================================================ -void sound_xaudio2::submit_buffer(std::unique_ptr<BYTE[]> audioData, DWORD audioLength) +void sound_xaudio2::submit_buffer(std::unique_ptr<BYTE[]> audioData, DWORD audioLength) const { assert(audioLength != 0); @@ -623,7 +592,7 @@ void sound_xaudio2::submit_buffer(std::unique_ptr<BYTE[]> audioData, DWORD audio HRESULT result; if (FAILED(result = m_sourceVoice->SubmitSourceBuffer(&buf))) { - osd_printf_verbose("Sound: XAudio2 failed to submit source buffer (non-fatal). Error: 0x%X\n", (unsigned int)result); + osd_printf_verbose("Sound: XAudio2 failed to submit source buffer (non-fatal). Error: 0x%X\n", static_cast<unsigned int>(result)); m_buffer_pool->return_to_pool(audioData.release()); return; } |