mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
Make XAudio2 available in all Windows OSD builds, plus use 2.9 if available, plus code cleanup.
This commit is contained in:
parent
c5b4ff95b0
commit
88412da862
5
makefile
5
makefile
@ -25,7 +25,6 @@
|
||||
|
||||
# USE_DISPATCH_GL = 0
|
||||
# MODERN_WIN_API = 0
|
||||
# USE_XAUDIO2 = 0
|
||||
# DIRECTINPUT = 7
|
||||
# USE_SDL = 1
|
||||
# SDL_INI_PATH = .;$HOME/.mame/;ini;
|
||||
@ -577,10 +576,6 @@ ifdef MODERN_WIN_API
|
||||
PARAMS += --MODERN_WIN_API='$(MODERN_WIN_API)'
|
||||
endif
|
||||
|
||||
ifdef USE_XAUDIO2
|
||||
PARAMS += --USE_XAUDIO2='$(USE_XAUDIO2)'
|
||||
endif
|
||||
|
||||
ifdef DIRECTINPUT
|
||||
PARAMS += --DIRECTINPUT='$(DIRECTINPUT)'
|
||||
endif
|
||||
|
@ -86,6 +86,11 @@ function osdmodulesbuild()
|
||||
MAME_DIR .. "src/osd/modules/input/input_xinput.cpp",
|
||||
}
|
||||
|
||||
configuration { "mingw*"}
|
||||
includedirs {
|
||||
MAME_DIR .. "3rdparty/compat/mingw",
|
||||
}
|
||||
|
||||
if _OPTIONS["targetos"]=="windows" then
|
||||
includedirs {
|
||||
MAME_DIR .. "3rdparty/winpcap/Include",
|
||||
@ -431,31 +436,6 @@ newoption {
|
||||
},
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "USE_XAUDIO2",
|
||||
description = "Use XAudio2 API for audio",
|
||||
allowed = {
|
||||
{ "0", "Disable XAudio2" },
|
||||
{ "1", "Enable XAudio2" },
|
||||
},
|
||||
}
|
||||
|
||||
if _OPTIONS["USE_XAUDIO2"]=="1" then
|
||||
_OPTIONS["MODERN_WIN_API"] = "1",
|
||||
defines {
|
||||
"USE_XAUDIO2=1",
|
||||
},
|
||||
configuration { "mingw*"}
|
||||
includedirs {
|
||||
MAME_DIR .. "3rdparty/compat/mingw",
|
||||
}
|
||||
configuration { }
|
||||
else
|
||||
defines {
|
||||
"USE_XAUDIO2=0",
|
||||
}
|
||||
end
|
||||
|
||||
newoption {
|
||||
trigger = "USE_QTDEBUG",
|
||||
description = "Use QT debugger",
|
||||
|
@ -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,14 +28,8 @@
|
||||
// MAME headers
|
||||
#include "emu.h"
|
||||
#include "osdepend.h"
|
||||
#include "emuopts.h"
|
||||
#if !defined(XAUDIO2_DLL)
|
||||
#if defined(UNICODE)
|
||||
#define XAUDIO2_DLL L"xaudio2_8.dll"
|
||||
#else
|
||||
#define XAUDIO2_DLL "xaudio2_8.dll"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "winutil.h"
|
||||
|
||||
//============================================================
|
||||
// Constants
|
||||
@ -140,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
|
||||
@ -203,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;
|
||||
@ -219,10 +206,10 @@ private:
|
||||
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() :
|
||||
@ -236,56 +223,74 @@ 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_xaudio2_module(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
|
||||
@ -310,9 +315,9 @@ int sound_xaudio2::init(osd_options const &options)
|
||||
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));
|
||||
@ -420,7 +425,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);
|
||||
@ -453,40 +458,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
|
||||
//============================================================
|
||||
@ -517,9 +488,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;
|
||||
@ -615,7 +586,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);
|
||||
|
||||
@ -630,7 +601,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user