Commit d72ff91c authored by Leander Schulten's avatar Leander Schulten

SystemVolume: Windows: Don't poll, use a callback to get the current master volume

parent 13015c2b
Pipeline #199365 passed with stage
in 5 minutes and 38 seconds
#include "systemvolume.h"
#ifdef Q_OS_MAC
#include <QtDebug>
#endif
#ifdef Q_OS_MAC
OSStatus callback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void * /*inClientData*/) {
......@@ -25,6 +23,24 @@ OSStatus callback(AudioObjectID inObjectID, UInt32 inNumberAddresses, const Audi
}
#endif
#ifdef Q_OS_WIN
HRESULT Callback::OnNotify(AUDIO_VOLUME_NOTIFICATION_DATA *pNotify) {
SystemVolume::get().setVolume(static_cast<double>(pNotify->fMasterVolume));
return S_OK;
}
Callback::~Callback() {
if (counter != 0) {
qWarning() << "SystemVolume::Callback: Releasing object with ref count > 0";
}
}
HRESULT Callback::QueryInterface(const IID & /*riid*/, void ** /*ppvObject*/) {
qWarning() << "SystemVolume::Callback: What do they want from me?";
return E_NOINTERFACE;
}
#endif
SystemVolume::SystemVolume() {
#ifdef Q_OS_WIN
HRESULT hr;
......@@ -46,6 +62,18 @@ SystemVolume::SystemVolume() {
if (hr < 0) {
return;
}
hr = endpointVolume->RegisterControlChangeNotify(&callback);
if (hr < 0) {
return;
}
// query initial volume
FLOAT v;
hr = endpointVolume->GetMasterVolumeLevelScalar(&v);
if (hr < 0) {
return;
}
volume = static_cast<double>(v);
emit volumeChanged();
#endif
#ifdef Q_OS_MAC
AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster};
......@@ -75,26 +103,6 @@ SystemVolume::SystemVolume() {
this->volume = static_cast<double>(volume);
emit volumeChanged();
}
#else
// we don't need polling on mac, we have a callback
startTimer(SystemVolumeUpdateRateInMs);
timerEvent(nullptr);
#endif
}
void SystemVolume::timerEvent(QTimerEvent * /*event*/) {
#ifdef Q_OS_WIN
if (endpointVolume) {
float vol;
auto hr = endpointVolume->GetMasterVolumeLevelScalar(&vol);
if (hr >= 0 /* success */) {
auto v = static_cast<double>(vol);
if (volume != v) {
volume = v;
emit volumeChanged();
}
}
}
#endif
}
......@@ -107,6 +115,7 @@ SystemVolume::~SystemVolume() {
pDevice->Release();
}
if (endpointVolume) {
endpointVolume->UnregisterControlChangeNotify(&callback);
endpointVolume->Release();
}
if (client) {
......
......@@ -18,6 +18,21 @@
#include <CoreAudio/CoreAudio.h>
#endif
#ifdef Q_OS_WIN
class Callback : public IAudioEndpointVolumeCallback {
ULONG counter = 0;
HRESULT OnNotify(AUDIO_VOLUME_NOTIFICATION_DATA *pNotify) override;
public:
~Callback();
HRESULT QueryInterface(REFIID /*riid*/, void ** /*ppvObject*/) override;
ULONG AddRef() override { return ++counter; }
ULONG Release() override { return --counter; }
};
#endif
class SystemVolume : public QObject {
Q_OBJECT
#ifdef Q_OS_WIN
......@@ -26,6 +41,7 @@ class SystemVolume : public QObject {
IAudioEndpointVolume *endpointVolume = nullptr;
WAVEFORMATEX *wformat = nullptr;
IAudioClient *client = nullptr;
Callback callback;
#endif
#ifdef Q_OS_MAC
AudioDeviceID defaultOutputDeviceID = kAudioDeviceUnknown;
......@@ -34,10 +50,6 @@ class SystemVolume : public QObject {
Q_PROPERTY(double volume READ getVolume WRITE setVolume NOTIFY volumeChanged)
SystemVolume();
static constexpr int SystemVolumeUpdateRateInMs = 10'000;
protected:
void timerEvent(QTimerEvent *event) override;
public:
static SystemVolume &get() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment