mirror of
https://github.com/esuo1198/TaikoArcadeLoader.git
synced 2026-10-12 09:08:10 +03:00
Several fix & optimize
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
#include "MinimumLatencyAudioClient.h"
|
||||
|
||||
#include <Audioclient.h>
|
||||
#include <mmdeviceapi.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace miniant::Windows;
|
||||
using namespace miniant::Windows::WasapiLatency;
|
||||
|
||||
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||
const IID IID_IAudioClient3 = __uuidof(IAudioClient3);
|
||||
|
||||
MinimumLatencyAudioClient::MinimumLatencyAudioClient(MinimumLatencyAudioClient&& other) noexcept {
|
||||
assert(other.m_pAudioClient != nullptr);
|
||||
assert(other.m_pFormat != nullptr);
|
||||
|
||||
m_pAudioClient = other.m_pAudioClient;
|
||||
m_pFormat = other.m_pFormat;
|
||||
|
||||
other.m_pAudioClient = nullptr;
|
||||
other.m_pFormat = nullptr;
|
||||
}
|
||||
MinimumLatencyAudioClient::MinimumLatencyAudioClient(void* pAudioClient, void* pFormat) :
|
||||
m_pAudioClient(pAudioClient), m_pFormat(pFormat) {}
|
||||
|
||||
MinimumLatencyAudioClient::~MinimumLatencyAudioClient() {
|
||||
Uninitialise();
|
||||
}
|
||||
|
||||
MinimumLatencyAudioClient& MinimumLatencyAudioClient::operator= (MinimumLatencyAudioClient&& rhs) noexcept {
|
||||
assert(rhs.m_pAudioClient != nullptr);
|
||||
assert(rhs.m_pFormat != nullptr);
|
||||
|
||||
Uninitialise();
|
||||
m_pAudioClient = rhs.m_pAudioClient;
|
||||
m_pFormat = rhs.m_pFormat;
|
||||
|
||||
rhs.m_pAudioClient = nullptr;
|
||||
rhs.m_pFormat = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void MinimumLatencyAudioClient::Uninitialise() {
|
||||
if (m_pAudioClient == nullptr) {
|
||||
assert(m_pFormat == nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_pFormat != nullptr);
|
||||
|
||||
static_cast<IAudioClient3*>(m_pAudioClient)->Release();
|
||||
m_pAudioClient = nullptr;
|
||||
|
||||
CoTaskMemFree(m_pFormat);
|
||||
m_pFormat = nullptr;
|
||||
}
|
||||
|
||||
std::expected<MinimumLatencyAudioClient::Properties, WindowsError> MinimumLatencyAudioClient::GetProperties() const {
|
||||
Properties properties;
|
||||
HRESULT hr = static_cast<IAudioClient3*>(m_pAudioClient)->GetSharedModeEnginePeriod(
|
||||
static_cast<WAVEFORMATEX*>(m_pFormat),
|
||||
&properties.defaultBufferSize,
|
||||
&properties.fundamentalBufferSize,
|
||||
&properties.minimumBufferSize,
|
||||
&properties.maximumBufferSize);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
properties.sampleRate = static_cast<WAVEFORMATEX*>(m_pFormat)->nSamplesPerSec;
|
||||
properties.bitsPerSample = static_cast<WAVEFORMATEX*>(m_pFormat)->wBitsPerSample;
|
||||
properties.numChannels = static_cast<WAVEFORMATEX*>(m_pFormat)->nChannels;
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::expected<MinimumLatencyAudioClient, WindowsError> MinimumLatencyAudioClient::Start() {
|
||||
|
||||
HRESULT hr = CoInitialize (nullptr);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
IMMDeviceEnumerator* pEnumerator;
|
||||
hr = CoCreateInstance(
|
||||
CLSID_MMDeviceEnumerator, nullptr,
|
||||
CLSCTX_ALL,
|
||||
IID_IMMDeviceEnumerator,
|
||||
reinterpret_cast<void**>(&pEnumerator));
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
IMMDevice* pDevice;
|
||||
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
IAudioClient3* pAudioClient;
|
||||
hr = pDevice->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, reinterpret_cast<void**>(&pAudioClient));
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
WAVEFORMATEX* pFormat;
|
||||
hr = pAudioClient->GetMixFormat(&pFormat);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
UINT32 defaultPeriodInFrames;
|
||||
UINT32 fundamentalPeriodInFrames;
|
||||
UINT32 minPeriodInFrames;
|
||||
UINT32 maxPeriodInFrames;
|
||||
hr = pAudioClient->GetSharedModeEnginePeriod(
|
||||
pFormat,
|
||||
&defaultPeriodInFrames,
|
||||
&fundamentalPeriodInFrames,
|
||||
&minPeriodInFrames,
|
||||
&maxPeriodInFrames);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
hr = pAudioClient->InitializeSharedAudioStream(
|
||||
0,
|
||||
minPeriodInFrames,
|
||||
pFormat, nullptr);
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
hr = pAudioClient->Start();
|
||||
if (hr != S_OK) {
|
||||
return std::unexpected(WindowsError());
|
||||
}
|
||||
|
||||
return MinimumLatencyAudioClient(pAudioClient, pFormat);
|
||||
}
|
||||
Reference in New Issue
Block a user