From edb1633fc92b5c3f3c3bdaafd0329fa3823c4397 Mon Sep 17 00:00:00 2001 From: gibbed Date: Sun, 12 Jan 2014 23:23:55 -0800 Subject: [PATCH] XAudio2 APU stub. --- src/xenia/apu/apu.cc | 21 +++- src/xenia/apu/apu.h | 3 + src/xenia/apu/sources.gypi | 1 + src/xenia/apu/xaudio2/sources.gypi | 12 ++ src/xenia/apu/xaudio2/xaudio2_apu-private.h | 31 +++++ src/xenia/apu/xaudio2/xaudio2_apu.cc | 44 +++++++ src/xenia/apu/xaudio2/xaudio2_apu.h | 33 ++++++ src/xenia/apu/xaudio2/xaudio2_audio_driver.cc | 28 +++++ src/xenia/apu/xaudio2/xaudio2_audio_driver.h | 40 +++++++ src/xenia/apu/xaudio2/xaudio2_audio_system.cc | 108 ++++++++++++++++++ src/xenia/apu/xaudio2/xaudio2_audio_system.h | 52 +++++++++ xenia.gyp | 1 + 12 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 src/xenia/apu/xaudio2/sources.gypi create mode 100644 src/xenia/apu/xaudio2/xaudio2_apu-private.h create mode 100644 src/xenia/apu/xaudio2/xaudio2_apu.cc create mode 100644 src/xenia/apu/xaudio2/xaudio2_apu.h create mode 100644 src/xenia/apu/xaudio2/xaudio2_audio_driver.cc create mode 100644 src/xenia/apu/xaudio2/xaudio2_audio_driver.h create mode 100644 src/xenia/apu/xaudio2/xaudio2_audio_system.cc create mode 100644 src/xenia/apu/xaudio2/xaudio2_audio_system.h diff --git a/src/xenia/apu/apu.cc b/src/xenia/apu/apu.cc index b9f6fea5e..7c9b84adf 100644 --- a/src/xenia/apu/apu.cc +++ b/src/xenia/apu/apu.cc @@ -17,7 +17,7 @@ using namespace xe::apu; DEFINE_string(apu, "any", - "Audio system. Use: [any, nop]"); + "Audio system. Use: [any, nop, xaudio2]"); #include @@ -26,13 +26,32 @@ AudioSystem* xe::apu::CreateNop(Emulator* emulator) { } +#if XE_PLATFORM_WIN32 +#include +AudioSystem* xe::apu::CreateXAudio2(Emulator* emulator) { + return xe::apu::xaudio2::Create(emulator); +} +#endif // WIN32 + AudioSystem* xe::apu::Create(Emulator* emulator) { if (FLAGS_apu.compare("nop") == 0) { return CreateNop(emulator); +#if XE_PLATFORM_WIN32 + } + else if (FLAGS_apu.compare("xaudio2") == 0) { + return CreateXAudio2(emulator); +#endif // WIN32 } else { // Create best available. AudioSystem* best = NULL; +#if XE_PLATFORM_WIN32 + best = CreateXAudio2(emulator); + if (best) { + return best; + } +#endif // WIN32 + // Fallback to nop. return CreateNop(emulator); } diff --git a/src/xenia/apu/apu.h b/src/xenia/apu/apu.h index de63f0756..36861efae 100644 --- a/src/xenia/apu/apu.h +++ b/src/xenia/apu/apu.h @@ -24,6 +24,9 @@ AudioSystem* Create(Emulator* emulator); AudioSystem* CreateNop(Emulator* emulator); +#if XE_PLATFORM_WIN32 +AudioSystem* CreateXAudio2(Emulator* emulator); +#endif // WIN32 } // namespace apu } // namespace xe diff --git a/src/xenia/apu/sources.gypi b/src/xenia/apu/sources.gypi index 3e6b4c244..92ea3258f 100644 --- a/src/xenia/apu/sources.gypi +++ b/src/xenia/apu/sources.gypi @@ -17,6 +17,7 @@ 'conditions': [ ['OS == "win"', { 'includes': [ + 'xaudio2/sources.gypi', ], }], ], diff --git a/src/xenia/apu/xaudio2/sources.gypi b/src/xenia/apu/xaudio2/sources.gypi new file mode 100644 index 000000000..181c4f1c0 --- /dev/null +++ b/src/xenia/apu/xaudio2/sources.gypi @@ -0,0 +1,12 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'xaudio2_apu-private.h', + 'xaudio2_apu.cc', + 'xaudio2_apu.h', + 'xaudio2_audio_driver.cc', + 'xaudio2_audio_driver.h', + 'xaudio2_audio_system.cc', + 'xaudio2_audio_system.h', + ], +} diff --git a/src/xenia/apu/xaudio2/xaudio2_apu-private.h b/src/xenia/apu/xaudio2/xaudio2_apu-private.h new file mode 100644 index 000000000..7e89a3179 --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_apu-private.h @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_PRIVATE_H_ +#define XENIA_APU_XAUDIO2_XAUDIO2_APU_PRIVATE_H_ + +#include + +#include + + +namespace xe { +namespace apu { +namespace xaudio2 { + + + + + +} // namespace xaudio2 +} // namespace apu +} // namespace xe + + +#endif // XENIA_APU_XAUDIO2_XAUDIO2_APU_PRIVATE_H_ diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.cc b/src/xenia/apu/xaudio2/xaudio2_apu.cc new file mode 100644 index 000000000..06d10e43b --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_apu.cc @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + + +using namespace xe; +using namespace xe::apu; +using namespace xe::apu::xaudio2; + + +namespace { + void InitializeIfNeeded(); + void CleanupOnShutdown(); + + void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; + } + has_initialized = true; + + // + + atexit(CleanupOnShutdown); + } + + void CleanupOnShutdown() { + } +} + + +AudioSystem* xe::apu::xaudio2::Create(Emulator* emulator) { + InitializeIfNeeded(); + return new XAudio2AudioSystem(emulator); +} diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.h b/src/xenia/apu/xaudio2/xaudio2_apu.h new file mode 100644 index 000000000..4b5a97bf7 --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_apu.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ +#define XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ + +#include + + +XEDECLARECLASS1(xe, Emulator); +XEDECLARECLASS2(xe, apu, AudioSystem); + + +namespace xe { +namespace apu { +namespace xaudio2 { + + +AudioSystem* Create(Emulator* emulator); + + +} // namespace xaudio2 +} // namespace apu +} // namespace xe + + +#endif // XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc new file mode 100644 index 000000000..4b4ac3b83 --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc @@ -0,0 +1,28 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + + +using namespace xe; +using namespace xe::apu; +using namespace xe::apu::xaudio2; + + +XAudio2AudioDriver::XAudio2AudioDriver(Memory* memory) : + AudioDriver(memory) { +} + +XAudio2AudioDriver::~XAudio2AudioDriver() { +} + +void XAudio2AudioDriver::Initialize() { +} diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.h b/src/xenia/apu/xaudio2/xaudio2_audio_driver.h new file mode 100644 index 000000000..05f1b3371 --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_ +#define XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_ + +#include + +#include +#include + + +namespace xe { +namespace apu { +namespace xaudio2 { + + +class XAudio2AudioDriver : public AudioDriver { +public: + XAudio2AudioDriver(Memory* memory); + virtual ~XAudio2AudioDriver(); + + virtual void Initialize(); + +protected: +}; + + +} // namespace xaudio2 +} // namespace apu +} // namespace xe + + +#endif // XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_ diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_system.cc b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc new file mode 100644 index 000000000..2c3b8088d --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc @@ -0,0 +1,108 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +#include + + +using namespace xe; +using namespace xe::apu; +using namespace xe::apu::xaudio2; + + +XAudio2AudioSystem::XAudio2AudioSystem(Emulator* emulator) : + audio_(0), mastering_voice_(0), pcm_voice_(0), + AudioSystem(emulator) { +} + +XAudio2AudioSystem::~XAudio2AudioSystem() { +} + +void XAudio2AudioSystem::Initialize() { + AudioSystem::Initialize(); + + HRESULT hr; + + hr = XAudio2Create(&audio_, 0, XAUDIO2_DEFAULT_PROCESSOR); + if (FAILED(hr)) { + XELOGE("XAudio2Create failed with %.8X", hr); + exit(1); + return; + } + + hr = audio_->CreateMasteringVoice(&mastering_voice_); + if (FAILED(hr)) { + XELOGE("CreateMasteringVoice failed with %.8X", hr); + exit(1); + } + + WAVEFORMATEX waveformat; + waveformat.wFormatTag = WAVE_FORMAT_PCM; + waveformat.nChannels = 1; + waveformat.nSamplesPerSec = 44100; + waveformat.nAvgBytesPerSec = 44100 * 2; + waveformat.nBlockAlign = 2; + waveformat.wBitsPerSample = 16; + waveformat.cbSize = 0; + hr = audio_->CreateSourceVoice(&pcm_voice_, &waveformat); + if (FAILED(hr)) { + XELOGE("CreateSourceVoice failed with %.8X", hr); + exit(1); + } + + pcm_voice_->Start(); + + XEASSERTNULL(driver_); + driver_ = new XAudio2AudioDriver(memory_); +} + +void XAudio2AudioSystem::Pump() { + // +} + +void XAudio2AudioSystem::SubmitFrame(uint32_t samples_ptr) { + // Process samples! They are big-endian floats. + HRESULT hr; + + auto samples = reinterpret_cast(emulator_->memory()->membase() + samples_ptr); + for (int i = 0; i < _countof(samples_); ++i) + { + samples_[i] = XESWAPF32BE(*samples++); + } + + // this is dumb and not right. + XAUDIO2_BUFFER buffer; + buffer.Flags = 0; + buffer.AudioBytes = sizeof(samples_); + buffer.pAudioData = reinterpret_cast(samples_); + buffer.PlayBegin = 0; + buffer.PlayLength = 0; + buffer.LoopBegin = 0; + buffer.LoopLength = 0; + buffer.LoopCount = 0; + buffer.pContext = 0; + hr = pcm_voice_->SubmitSourceBuffer(&buffer); + if (FAILED(hr)) { + XELOGE("SubmitSourceBuffer failed with %.8X", hr); + exit(1); + } + hr = pcm_voice_->Start(0); + if (FAILED(hr)) { + XELOGE("Start failed with %.8X", hr); + exit(1); + } +} + +void XAudio2AudioSystem::Shutdown() { + AudioSystem::Shutdown(); +} diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_system.h b/src/xenia/apu/xaudio2/xaudio2_audio_system.h new file mode 100644 index 000000000..285494da0 --- /dev/null +++ b/src/xenia/apu/xaudio2/xaudio2_audio_system.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_SYSTEM_H_ +#define XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_SYSTEM_H_ + +#include + +#include +#include + +#include + + +namespace xe { +namespace apu { +namespace xaudio2 { + + +class XAudio2AudioSystem : public AudioSystem { +public: + XAudio2AudioSystem(Emulator* emulator); + virtual ~XAudio2AudioSystem(); + + virtual void Shutdown(); + + virtual void SubmitFrame(uint32_t samples_ptr); + +protected: + virtual void Initialize(); + virtual void Pump(); + +private: + IXAudio2* audio_; + IXAudio2MasteringVoice* mastering_voice_; + IXAudio2SourceVoice* pcm_voice_; + float samples_[1536]; +}; + + +} // namespace xaudio2 +} // namespace apu +} // namespace xe + + +#endif // XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_SYSTEM_H_ diff --git a/xenia.gyp b/xenia.gyp index 6e2805599..60286fdb6 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -284,6 +284,7 @@ 'd3d11', 'd3dcompiler', 'xinput', + 'xaudio2', ], }], ['OS == "mac"', {