mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-21 02:09:05 +02:00
Merge pull request #20609 from oltolm/comptr
use ComPtr in WASAPIContext
This commit is contained in:
2 files changed
+20
-30
No files matched your search
+14
-23
@@ -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(¬ificationClient_);
|
||||
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; }
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user