rpcsx/rpcs3/Emu/Audio/XAudio2/XAudio2Backend.h

82 lines
2.8 KiB
C
Raw Normal View History

2020-12-05 13:08:24 +01:00
#pragma once
#ifndef _WIN32
#error "XAudio2 can only be built on Windows."
#endif
#include "Emu/Audio/AudioBackend.h"
2015-11-16 16:04:49 +01:00
#include <initguid.h>
#include <xaudio2.h>
#include <wrl/client.h>
#include <MMDeviceAPI.h>
class XAudio2Backend final : public AudioBackend, public IXAudio2VoiceCallback, public IXAudio2EngineCallback, public IMMNotificationClient
{
public:
XAudio2Backend();
2021-04-09 21:12:47 +02:00
~XAudio2Backend() override;
2021-04-03 18:38:02 +02:00
XAudio2Backend(const XAudio2Backend&) = delete;
XAudio2Backend& operator=(const XAudio2Backend&) = delete;
2021-11-29 12:52:02 +01:00
std::string_view GetName() const override { return "XAudio2"sv; }
2021-12-01 22:36:01 +01:00
bool Initialized() override;
bool Operational() override;
bool DefaultDeviceChanged() override;
2024-03-26 19:39:37 +01:00
bool Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt, audio_channel_layout layout) override;
2021-04-09 21:12:47 +02:00
void Close() override;
2018-12-20 23:35:49 +01:00
f64 GetCallbackFrameLen() override;
2021-04-09 21:12:47 +02:00
void Play() override;
void Pause() override;
2018-12-20 23:35:49 +01:00
private:
static constexpr u32 INTERNAL_BUF_SIZE_MS = 25;
Microsoft::WRL::ComPtr<IXAudio2> m_xaudio2_instance{};
IXAudio2MasteringVoice* m_master_voice{};
IXAudio2SourceVoice* m_source_voice{};
bool m_com_init_success = false;
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> m_device_enumerator{};
2022-10-13 14:39:16 +02:00
// Protected by state callback mutex
std::string m_current_device{};
bool m_default_dev_changed = false;
std::vector<u8> m_data_buf{};
std::array<u8, sizeof(float) * static_cast<u32>(AudioChannelCnt::SURROUND_7_1)> m_last_sample{};
atomic_t<bool> m_reset_req = false;
// XAudio voice callbacks
void OnVoiceProcessingPassStart(UINT32 BytesRequired) override;
void OnVoiceProcessingPassEnd() override {}
void OnStreamEnd() override {}
void OnBufferStart(void* /* pBufferContext */) override {}
void OnBufferEnd(void* /* pBufferContext*/) override {}
void OnLoopEnd(void* /* pBufferContext */) override {}
void OnVoiceError(void* /* pBufferContext */, HRESULT /* Error */) override {}
// XAudio engine callbacks
void OnProcessingPassStart() override {};
void OnProcessingPassEnd() override {};
void OnCriticalError(HRESULT Error) override;
// IMMNotificationClient callbacks
IFACEMETHODIMP_(ULONG) AddRef() override { return 1; };
IFACEMETHODIMP_(ULONG) Release() override { return 1; };
IFACEMETHODIMP QueryInterface(REFIID /*iid*/, void** /*object*/) override { return E_NOINTERFACE; };
IFACEMETHODIMP OnPropertyValueChanged(LPCWSTR /*device_id*/, const PROPERTYKEY /*key*/) override { return S_OK; };
IFACEMETHODIMP OnDeviceAdded(LPCWSTR /*device_id*/) override { return S_OK; };
IFACEMETHODIMP OnDeviceRemoved(LPCWSTR /*device_id*/) override { return S_OK; };
IFACEMETHODIMP OnDeviceStateChanged(LPCWSTR /*device_id*/, DWORD /*new_state*/) override { return S_OK; };
IFACEMETHODIMP OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR new_default_device_id) override;
void CloseUnlocked();
};