mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-02 02:41:49 +02:00
Merge pull request #618 from stijnvdb88/master
wasapi: added listener for getting system volume
This commit is contained in:
commit
2a6360a832
2 changed files with 117 additions and 0 deletions
|
@ -45,6 +45,7 @@ const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
|||
const IID IID_IAudioClient = __uuidof(IAudioClient);
|
||||
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
|
||||
const IID IID_IAudioClock = __uuidof(IAudioClock);
|
||||
const IID IID_IAudioEndpointVolume = _uuidof(IAudioEndpointVolume);
|
||||
|
||||
_COM_SMARTPTR_TYPEDEF(IMMDevice, __uuidof(IMMDevice));
|
||||
_COM_SMARTPTR_TYPEDEF(IMMDeviceCollection, __uuidof(IMMDeviceCollection));
|
||||
|
@ -229,6 +230,8 @@ void WASAPIPlayer::worker()
|
|||
hr = device->Activate(__uuidof(IAudioSessionManager), CLSCTX_INPROC_SERVER, NULL, (void**)&sessionManager);
|
||||
CHECK_HR(hr);
|
||||
|
||||
|
||||
|
||||
// Get the control interface for the process-specific audio
|
||||
// session with session GUID = GUID_NULL. This is the session
|
||||
// that an audio stream for a DirectSound, DirectShow, waveOut,
|
||||
|
@ -241,6 +244,11 @@ void WASAPIPlayer::worker()
|
|||
hr = control->RegisterAudioSessionNotification(audioEventListener_);
|
||||
CHECK_HR(hr);
|
||||
|
||||
AudioEndpointVolumeCallback audioEndpointVolumeCallback;
|
||||
hr = device->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&audioEndpointListener_);
|
||||
|
||||
audioEndpointListener_->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)&audioEndpointVolumeCallback);
|
||||
|
||||
// Get the device period
|
||||
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
|
||||
hr = audioClient->GetDevicePeriod(NULL, &hnsRequestedDuration);
|
||||
|
@ -336,7 +344,14 @@ void WASAPIPlayer::worker()
|
|||
|
||||
// update our volume from IAudioControl
|
||||
if (mode_ == ClientSettings::SharingMode::exclusive)
|
||||
{
|
||||
volCorrection_ = audioEventListener_->getVolume();
|
||||
// muteOverride = audioEventListener_->getMuted(); // use this for also applying audio mixer mute state
|
||||
}
|
||||
|
||||
// get audio device volume from IAudioEndpointVolume
|
||||
// float deviceVolume = audioEndpointVolumeCallback.getVolume(); // system volume (for this audio device)
|
||||
// bool deviceMuted = audioEndpointVolumeCallback.getMuted(); // system mute (for this audio device)
|
||||
|
||||
clock->GetPosition(&position, NULL);
|
||||
|
||||
|
@ -406,6 +421,8 @@ HRESULT STDMETHODCALLTYPE AudioSessionEventListener::QueryInterface(REFIID riid,
|
|||
HRESULT STDMETHODCALLTYPE AudioSessionEventListener::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext)
|
||||
{
|
||||
volume_ = NewVolume;
|
||||
muted_ = NewMute;
|
||||
|
||||
if (NewMute)
|
||||
{
|
||||
LOG(DEBUG, LOG_TAG) << ("MUTE\n");
|
||||
|
@ -463,5 +480,27 @@ HRESULT STDMETHODCALLTYPE AudioSessionEventListener::OnSessionDisconnected(Audio
|
|||
}
|
||||
LOG(INFO, LOG_TAG) << "Audio session disconnected (reason: " << pszReason << ")";
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AudioEndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
|
||||
{
|
||||
if (pNotify == NULL)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (pNotify->bMuted)
|
||||
{
|
||||
LOG(DEBUG, LOG_TAG) << ("MASTER MUTE\n");
|
||||
}
|
||||
|
||||
LOG(DEBUG, LOG_TAG) << "Volume = " << (UINT32)(100 * pNotify->fMasterVolume + 0.5) << " percent\n";
|
||||
|
||||
volume_ = pNotify->fMasterVolume;
|
||||
muted_ = pNotify->bMuted;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -20,12 +20,14 @@
|
|||
#define WASAPI_PLAYER_H
|
||||
#include "player.hpp"
|
||||
#include <audiopolicy.h>
|
||||
#include <endpointvolume.h>
|
||||
|
||||
class AudioSessionEventListener : public IAudioSessionEvents
|
||||
{
|
||||
LONG _cRef;
|
||||
|
||||
float volume_ = 1.f;
|
||||
bool muted_ = false;
|
||||
|
||||
public:
|
||||
AudioSessionEventListener() : _cRef(1)
|
||||
|
@ -37,6 +39,11 @@ public:
|
|||
return volume_;
|
||||
}
|
||||
|
||||
bool getMuted()
|
||||
{
|
||||
return muted_;
|
||||
}
|
||||
|
||||
~AudioSessionEventListener()
|
||||
{
|
||||
}
|
||||
|
@ -89,6 +96,75 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason);
|
||||
};
|
||||
|
||||
|
||||
class AudioEndpointVolumeCallback : public IAudioEndpointVolumeCallback
|
||||
{
|
||||
LONG _cRef;
|
||||
float volume_ = 1.f;
|
||||
bool muted_ = false;
|
||||
|
||||
public:
|
||||
AudioEndpointVolumeCallback() : _cRef(1)
|
||||
{
|
||||
}
|
||||
|
||||
~AudioEndpointVolumeCallback()
|
||||
{
|
||||
}
|
||||
|
||||
float getVolume()
|
||||
{
|
||||
return volume_;
|
||||
}
|
||||
|
||||
bool getMuted()
|
||||
{
|
||||
return muted_;
|
||||
}
|
||||
|
||||
// IUnknown methods -- AddRef, Release, and QueryInterface
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&_cRef);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
ULONG ulRef = InterlockedDecrement(&_cRef);
|
||||
if (0 == ulRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return ulRef;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID** ppvInterface)
|
||||
{
|
||||
if (IID_IUnknown == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IUnknown*)this;
|
||||
}
|
||||
else if (__uuidof(IAudioEndpointVolumeCallback) == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IAudioEndpointVolumeCallback*)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvInterface = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Callback method for endpoint-volume-change notifications.
|
||||
|
||||
HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify);
|
||||
};
|
||||
|
||||
class WASAPIPlayer : public Player
|
||||
{
|
||||
public:
|
||||
|
@ -106,6 +182,8 @@ protected:
|
|||
|
||||
private:
|
||||
AudioSessionEventListener* audioEventListener_;
|
||||
IAudioEndpointVolume* audioEndpointListener_;
|
||||
ClientSettings::SharingMode mode_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue