session volume/mute polling

This commit is contained in:
Hane 2024-02-03 15:33:59 +01:00
commit 064c16d9e7
10 changed files with 263 additions and 4 deletions

View file

@ -1,6 +1,45 @@
#include <backlasses.h>
#include <backfuncs.h>
EndpointNewSessionCallback::EndpointNewSessionCallback(EndpointHandler* eph){
this->eph = eph;
}
ULONG EndpointNewSessionCallback::AddRef(){
return InterlockedIncrement(&ref);
}
ULONG EndpointNewSessionCallback::Release(){
ULONG tempRef = InterlockedDecrement(&ref);
if (tempRef == 0) {
delete this;
}
return tempRef;
}
HRESULT EndpointNewSessionCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IAudioSessionNotification) == riid)
{
AddRef();
*ppvInterface = (IMMNotificationClient*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
HRESULT EndpointNewSessionCallback::OnSessionCreated(IAudioSessionControl *NewSession) {
return S_OK;
}
EndpointVolumeCallback::EndpointVolumeCallback(Endpoint* ep){
this->ep = ep;
}

View file

@ -33,7 +33,6 @@ class Endpoint {
std::wstring getId();
std::wstring getName();
void setVolumeCallback(EndpointVolumeCallback *epc);
void removeVolumeCallback(EndpointVolumeCallback *epc);
@ -134,3 +133,16 @@ class Overseer {
//std::vector<Endpoint*> *captureDevices;
};
class EndpointNewSessionCallback : public IAudioSessionNotification {
public:
//EndpointSituationCallback(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices);
EndpointNewSessionCallback(EndpointHandler *eph);
ULONG AddRef();
ULONG Release();
HRESULT QueryInterface(REFIID riid, VOID **ppvInterface);
HRESULT OnSessionCreated(IAudioSessionControl *NewSession);
private:
ULONG ref = 1;
EndpointHandler *eph;
};

View file

@ -1,6 +1,126 @@
#include "backsessionclasses.h"
#include "backfuncs.h"
SessionStateCallback::SessionStateCallback(SessionHandler *sh) {
this->sh = sh;
}
ULONG SessionStateCallback::AddRef() {
return InterlockedIncrement(&ref);
}
ULONG SessionStateCallback::Release() {
ULONG tempRef = InterlockedDecrement(&ref);
if (tempRef == 0) {
delete this;
}
return tempRef;
}
HRESULT SessionStateCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IAudioSessionNotification) == riid)
{
AddRef();
*ppvInterface = (IMMNotificationClient*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
HRESULT SessionStateCallback::OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext) {
return S_OK;
}
HRESULT SessionStateCallback::OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContex) {
return S_OK;
}
HRESULT SessionStateCallback::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext) {
sh->getVolumeInfo()->muted = NewMute;
sh->getVolumeInfo()->mainVolume = NewVolume;
sh->getVolumeInfo()->caller = GUIDToNGuid((LPGUID)EventContext);
/*
* if (NewMute)
* {
* printf("MUTE\n");
* }
* else
* {
* printf("Volume = %d percent\n",
* (UINT32)(100*NewVolume + 0.5));
* }
*/
return S_OK;
}
HRESULT SessionStateCallback::OnChannelVolumeChanged(DWORD ChannelCount, float NewChannelVolumeArray[], DWORD ChangedChannel, LPCGUID EventContext) {
return S_OK;
}
HRESULT SessionStateCallback::OnGroupingParamChanged(LPCGUID NewGroupingParam, LPCGUID EventContext) {
return S_OK;
}
HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) {
/*
* char *pszState = "?????";
*
* switch (NewState)
* {
* case AudioSessionStateActive:
* pszState = "active";
* break;
* case AudioSessionStateInactive:
* pszState = "inactive";
* break;
* }
* printf("New session state = %s\n", pszState);
*/
return S_OK;
}
HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) {
/*
* char *pszReason = "?????";
*
* switch (DisconnectReason)
* {
* case DisconnectReasonDeviceRemoval:
* pszReason = "device removed";
* break;
* case DisconnectReasonServerShutdown:
* pszReason = "server shut down";
* break;
* case DisconnectReasonFormatChanged:
* pszReason = "format changed";
* break;
* case DisconnectReasonSessionLogoff:
* pszReason = "user logged off";
* break;
* case DisconnectReasonSessionDisconnected:
* pszReason = "session disconnected";
* break;
* case DisconnectReasonExclusiveModeOverride:
* pszReason = "exclusive-mode override";
* break;
* }
* printf("Audio session disconnected (reason: %s)\n",
* pszReason);
*/
return S_OK;
}
Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx) {
this->ep = ep;
this->sessionControl = sessionControl;
@ -147,3 +267,11 @@ wchar_t* fileDescription = NULL;
free(fileVersionInfo);
return exePath;
}
void Session::setStateCallback(SessionStateCallback *ssc){
sessionControl->RegisterAudioSessionNotification((IAudioSessionEvents*) ssc);
}
void Session::removeStateCallback(SessionStateCallback *ssc){
sessionControl->UnregisterAudioSessionNotification((IAudioSessionEvents*) ssc);
}

View file

@ -6,6 +6,26 @@
class Endpoint;
class SessionStateCallback : public IAudioSessionEvents {
public:
SessionStateCallback(SessionHandler *sh);
ULONG AddRef();
ULONG Release();
HRESULT QueryInterface(REFIID riid, VOID **ppvInterface);
HRESULT OnSessionCreated(IAudioSessionControl *NewSession);
HRESULT OnChannelVolumeChanged(DWORD ChannelCount, float NewChannelVolumeArray[], DWORD ChangedChannel, LPCGUID EventContext);
HRESULT OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext);
HRESULT OnGroupingParamChanged( LPCGUID NewGroupingParam, LPCGUID EventContext);
HRESULT OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContext);
HRESULT OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason);
HRESULT OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext);
HRESULT OnStateChanged(AudioSessionState NewState);
private:
ULONG ref = 1;
SessionHandler *sh;
};
class Session {
public:
@ -15,6 +35,9 @@ class Session {
void setMute(NGuid guid, bool muted);
bool getMute();
std::wstring getName();
void setStateCallback(SessionStateCallback *ssc);
void removeStateCallback(SessionStateCallback *ssc);
//uint32_t getChannelCount();
private:
@ -25,3 +48,4 @@ class Session {
ISimpleAudioVolume* sessionVolume = nullptr;
size_t idx;
};

View file

@ -15,7 +15,6 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
this->setBackEndpointVolumeCallbackInfoContent(this->getState());
osh->pushBackEndpointHandler(this, flow);
if (this->flow == Flows::FLOW_PLAYBACK && this->getState() == EndpointState::ENDPOINT_ACTIVE) {
for (int i = 0; i < this->getSessionCount(); i++) {
SessionHandler* sessionHandler = new SessionHandler(this, this->getSessions().at(i),i);

View file

@ -104,6 +104,12 @@ public:
EndpointHandler* addEndpoint(std::wstring endpointId, Flows *flow);
NGuid getGuid();
/* Session's */
/*
* void setSessionVolumeCallback(std::function<void(float)> changeSessionVolume);
* void setSessionVolume(float newValue, );
*/
private:
Overseer *os;
std::vector<EndpointHandler*> playbackEndpointHandlers;
@ -112,6 +118,9 @@ private:
std::function<void(uint64_t /* epw id */)> removeEndpointWidget;
std::function<void(EndpointHandler*)> addEndpointWidget;
/* Session's */
std::function<void(float)> changeSessionVolume;
//std::function<void(uint64_t /* device */, uint32_t /* channel */, float /* value */)> updateFrontVolumeCallback;
//std::function<void(uint64_t /* device */, bool /* mute */)> updateFrontMuteCallback;

View file

@ -5,6 +5,13 @@ SessionHandler::SessionHandler(EndpointHandler* eph, Session* session, size_t id
this->eph = eph;
this->idx = idx;
this->session = session;
this->svi.mainVolume = session->getVolume(AudioChannel::CHANNEL_MAIN);
this->svi.muted = session->getMute();
this->svi.caller = osh->getGuid();
ssc = new SessionStateCallback(this);
this->session->setStateCallback(ssc);
}
void SessionHandler::setVolume(NGuid guid, int channel, int value){
@ -28,3 +35,7 @@ std::wstring SessionHandler::getName(){
bool SessionHandler::getMute(){
return session->getMute();
}
SessionVolumeInfo* SessionHandler::getVolumeInfo() {
return &svi;
}

View file

@ -5,6 +5,17 @@
class EndpointHandler;
class Session;
class SessionStateCallback;
struct SessionVolumeInfo {
//SessionVolumeInfo(bool muted, float mainVolume);
bool muted;
float mainVolume;
NGuid caller;
//size_t channels;
//std::vector<float> channelVolumes;
};
class SessionHandler {
public:
@ -14,10 +25,13 @@ class SessionHandler {
void setMute(NGuid guid, bool muted);
bool getMute();
std::wstring getName();
SessionVolumeInfo* getVolumeInfo();
private:
SessionVolumeInfo svi;
EndpointHandler* eph;
Session* session;
SessionStateCallback* ssc;
size_t idx;
};

View file

@ -60,6 +60,29 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
connect<void(QSlider::*)(int), void(SessionWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&SessionWidget::updateMainVolume);
connect<void(QCheckBox::*)(int), void(SessionWidget::*)(int)>(muteButton, &QCheckBox::stateChanged, this, (&SessionWidget::updateMute));
/*
* Session Volume Polling
*/
volumePoller = new QTimer();
connect(volumePoller, &QTimer::timeout, [this, sh](){
//if (memcmp(osh->callbackInfo[idx]->caller, osh->getGuid(), sizeof(NGuid)) == 0) return; CHECK IF THIS PROGRAM GENERATED THE FUNSIES IS NO LONGER IN USE FOR NOW.
//todo: global + constexpr + ratio
const float roundingFactor = 0.005;
mainSlider->blockSignals(true);
muteButton->blockSignals(true);
mainSlider->setValue((int)((sh->getVolumeInfo()->mainVolume + roundingFactor) * 100));
muteButton->setCheckState((sh->getVolumeInfo()->muted == false ? Qt::Unchecked : Qt::Checked));
muteButton->setText(sh->getVolumeInfo()->muted ? STRING_UNMUTE : STRING_MUTE);
//memcpy(osh->callbackInfo[idx]->caller, osh->getGuid(), sizeof(NGuid));
//TODO: el default = objcopy frees?
//Todo: like fr pregunta
sh->getVolumeInfo()->caller = osh->getGuid();
mainSlider->blockSignals(false);
muteButton->blockSignals(false);
});
volumePoller->start(10);
}
void SessionWidget::updateMute(int checked){

View file

@ -102,6 +102,7 @@ private:
QGridLayout *layout = nullptr;
QCheckBox *muteButton = nullptr;
SessionHandler* sh;
QTimer* volumePoller = nullptr;
};
class EndpointWidget : public QWidget {
@ -118,7 +119,6 @@ public:
void setVolume(int channel, float volume);
~EndpointWidget();
//void updateMainVolume(float newValue);
//void updateVolume(uint32_t channel, float newValue);
//void updateMute(bool muted);