session volume/mute polling
This commit is contained in:
parent
9e159f6ba3
commit
165aff07e4
10 changed files with 263 additions and 4 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ class Endpoint {
|
|||
Flows getFlow();
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
|
|||
//epName = ep->getName();
|
||||
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++) {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,12 @@ public:
|
|||
void reloadEndpointHandlers();
|
||||
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;
|
||||
|
|
@ -111,6 +117,9 @@ private:
|
|||
std::function<void(Roles, std::wstring /* endpointid */)> changeFrontDefaults;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -59,7 +59,30 @@ SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent)
|
|||
//TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option?
|
||||
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){
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue