Merge pull request #20609 from oltolm/comptr

use ComPtr in WASAPIContext
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-07-10 22:40:16 +02:00
commit af883e8059
2 files changed
+20 -30

No files matched your search

+14 -23
View File
@@ -8,10 +8,13 @@
#include <thread>
#include <vector>
#include <string_view>
#include <wrl/client.h>
#include "Common/Log.h"
#include "WASAPIContext.h"
using Microsoft::WRL::ComPtr;
static std::string ConvertWStringToUTF8(const std::wstring &wstr) {
const int len = (int)wstr.size();
const int size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL);
@@ -35,7 +38,7 @@ static std::wstring ConvertUTF8ToWString(const std::string_view source) {
}
WASAPIContext::WASAPIContext() : notificationClient_(this) {
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator_);
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, IID_PPV_ARGS(&enumerator_));
if (FAILED(hr)) {
// Bad!
enumerator_ = nullptr;
@@ -51,11 +54,10 @@ WASAPIContext::~WASAPIContext() {
}
Stop();
enumerator_->UnregisterEndpointNotificationCallback(&notificationClient_);
enumerator_->Release();
}
void WASAPIContext::EnumerateDevices(std::vector<AudioDeviceDesc> *output, bool captureDevices) {
IMMDeviceCollection *collection = nullptr;
ComPtr<IMMDeviceCollection> collection;
enumerator_->EnumAudioEndpoints(captureDevices ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection);
if (!collection) {
@@ -67,10 +69,10 @@ void WASAPIContext::EnumerateDevices(std::vector<AudioDeviceDesc> *output, bool
collection->GetCount(&count);
for (UINT i = 0; i < count; ++i) {
IMMDevice *device = nullptr;
ComPtr<IMMDevice> device;
collection->Item(i, &device);
IPropertyStore *props = nullptr;
ComPtr<IPropertyStore> props;
device->OpenPropertyStore(STGM_READ, &props);
PROPVARIANT nameProp;
@@ -87,11 +89,7 @@ void WASAPIContext::EnumerateDevices(std::vector<AudioDeviceDesc> *output, bool
}
PropVariantClear(&nameProp);
props->Release();
device->Release();
}
collection->Release();
}
bool WASAPIContext::InitOutputDevice(std::string_view uniqueId, LatencyMode latencyMode, bool *revertedToDefault) {
@@ -99,7 +97,7 @@ bool WASAPIContext::InitOutputDevice(std::string_view uniqueId, LatencyMode late
*revertedToDefault = false;
IMMDevice *device = nullptr;
ComPtr<IMMDevice> device;
if (uniqueId.empty()) {
// Use the default device.
if (FAILED(enumerator_->GetDefaultAudioEndpoint(eRender, eConsole, &device))) {
@@ -141,17 +139,14 @@ bool WASAPIContext::InitOutputDevice(std::string_view uniqueId, LatencyMode late
);
if (FAILED(result)) {
printf("Error initializing shared audio stream: %08lx", result);
audioClient3_->Release();
device->Release();
audioClient3_ = nullptr;
device = nullptr;
audioClient3_.Reset();
return false;
}
actualPeriodFrames_ = minPeriodFrames;
audioClient3_->GetBufferSize(&reportedBufferSize_);
audioClient3_->SetEventHandle(audioEvent_);
audioClient3_->GetService(__uuidof(IAudioRenderClient), (void**)&renderClient_);
audioClient3_->GetService(IID_PPV_ARGS(&renderClient_));
} else {
// Fallback to IAudioClient (older OS)
device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, (void**)&audioClient_);
@@ -176,23 +171,19 @@ bool WASAPIContext::InitOutputDevice(std::string_view uniqueId, LatencyMode late
if (FAILED(hr)) {
printf("ERROR: Failed to initialize audio with all attempted buffer sizes\n");
audioClient_->Release();
device->Release();
audioClient_ = nullptr;
device = nullptr;
audioClient_.Reset();
return false;
}
audioClient_->GetBufferSize(&reportedBufferSize_);
actualPeriodFrames_ = reportedBufferSize_; // we don't have a better estimate.
audioClient_->SetEventHandle(audioEvent_);
audioClient_->GetService(__uuidof(IAudioRenderClient), (void**)&renderClient_);
audioClient_->GetService(IID_PPV_ARGS(&renderClient_));
}
latencyMode_ = latencyMode;
Start();
device->Release();
return true;
}
@@ -207,8 +198,8 @@ void WASAPIContext::Stop() {
if (audioEvent_) SetEvent(audioEvent_);
if (audioThread_.joinable()) audioThread_.join();
if (renderClient_) { renderClient_->Release(); renderClient_ = nullptr; }
if (audioClient_) { audioClient_->Release(); audioClient_ = nullptr; }
renderClient_.Reset();
audioClient_.Reset();
if (audioEvent_) { CloseHandle(audioEvent_); audioEvent_ = nullptr; }
if (format_) { CoTaskMemFree(format_); format_ = nullptr; }
}
+6 -7
View File
@@ -1,16 +1,15 @@
#pragma once
#include "Audio/AudioBackend.h"
#include <atomic>
#include "WindowsAudio.h"
#include <windows.h>
#include <mmdeviceapi.h>
#include <audioclient.h>
#include <cmath>
#include <thread>
#include <vector>
#include <string>
#include <string_view>
#include <wrl/client.h>
class WASAPIContext : public AudioBackend {
public:
@@ -72,10 +71,10 @@ private:
void AudioLoop();
// Only one of these can be non-null at a time. Check audioClient3 to determine if it's being used.
IAudioClient3 *audioClient3_ = nullptr;
IAudioClient *audioClient_ = nullptr;
Microsoft::WRL::ComPtr<IAudioClient3> audioClient3_;
Microsoft::WRL::ComPtr<IAudioClient> audioClient_;
IAudioRenderClient* renderClient_ = nullptr;
Microsoft::WRL::ComPtr<IAudioRenderClient> renderClient_;
WAVEFORMATEX *format_ = nullptr;
HANDLE audioEvent_ = nullptr;
std::thread audioThread_;
@@ -83,7 +82,7 @@ private:
std::atomic<bool> running_ = true;
UINT32 actualPeriodFrames_ = 0; // may not be the requested.
UINT32 reportedBufferSize_ = 0;
IMMDeviceEnumerator *enumerator_ = nullptr;
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> enumerator_;
DeviceNotificationClient notificationClient_;
RenderCallback callback_{};
void *userdata_ = nullptr;