session baby steps
This commit is contained in:
parent
6f8455c63d
commit
6d88697811
14 changed files with 393 additions and 87 deletions
|
|
@ -9,8 +9,8 @@ QT += widgets network
|
||||||
INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
||||||
DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
||||||
VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
|
||||||
SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp contclasses.cpp
|
SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp backsessionclasses.cpp contclasses.cpp contsessionclasses.cpp
|
||||||
HEADERS += qtclasses.h backlasses.h contclasses.h global.h debug.h backfuncs.h ipolicyconfig.h
|
HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h
|
||||||
RESOURCES = assets.qrc
|
RESOURCES = assets.qrc
|
||||||
|
|
||||||
#DESTDIR += "build"
|
#DESTDIR += "build"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
GUID NGuidToGUID(NGuid guid) {
|
GUID inline NGuidToGUID(NGuid guid) {
|
||||||
GUID msGuid = GUID();
|
GUID msGuid = GUID();
|
||||||
msGuid.Data1 = guid.data1;
|
msGuid.Data1 = guid.data1;
|
||||||
msGuid.Data2 = guid.data2;
|
msGuid.Data2 = guid.data2;
|
||||||
|
|
@ -15,7 +15,7 @@ GUID NGuidToGUID(NGuid guid) {
|
||||||
return msGuid;
|
return msGuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
NGuid GUIDToNGuid(LPGUID msGuid){
|
NGuid inline GUIDToNGuid(LPGUID msGuid){
|
||||||
NGuid guid = NGuid();
|
NGuid guid = NGuid();
|
||||||
guid.data1 = msGuid->Data1;
|
guid.data1 = msGuid->Data1;
|
||||||
guid.data2 = msGuid->Data2;
|
guid.data2 = msGuid->Data2;
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
||||||
|
|
||||||
reloadEndpointChannels();
|
reloadEndpointChannels();
|
||||||
|
|
||||||
/*
|
/* todo: check header
|
||||||
* if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
|
* if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
|
||||||
* CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); }
|
* CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); }
|
||||||
*/
|
*/
|
||||||
|
|
@ -228,12 +228,37 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
||||||
friendlyName = std::wstring(pv.pwszVal);
|
friendlyName = std::wstring(pv.pwszVal);
|
||||||
|
|
||||||
this->setFlow();
|
this->setFlow();
|
||||||
|
if (this->endpointState == EndpointState::ENDPOINT_ACTIVE && this->flow == Flows::FLOW_PLAYBACK) {
|
||||||
|
activateEndpointSessions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Endpoint::Endpoint(IMMDevice* endpoint) : Endpoint(endpoint, 0) {};
|
* Endpoint::Endpoint(IMMDevice* endpoint) : Endpoint(endpoint, 0) {};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void Endpoint::activateEndpointSessions() {
|
||||||
|
//sessionManager;
|
||||||
|
if (FAILED(endpoint->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**) &sessionManager))) { log_wdebugcpp(L"sesionbros..."); return; }
|
||||||
|
|
||||||
|
IAudioSessionEnumerator* sessionEnumerator = nullptr;
|
||||||
|
if (FAILED(sessionManager->GetSessionEnumerator(&sessionEnumerator))) { log_wdebugcpp(L"sesEnumeratorBros..."); return; }
|
||||||
|
|
||||||
|
int sessionCount;
|
||||||
|
sessionEnumerator->GetCount(&sessionCount);
|
||||||
|
for (int i = 0; i < sessionCount; i++) {
|
||||||
|
IAudioSessionControl* sessionControlTmp;
|
||||||
|
sessionEnumerator->GetSession(i, (IAudioSessionControl**)&sessionControlTmp);
|
||||||
|
//todo:: asegurar lo del dynamic_cast
|
||||||
|
IAudioSessionControl2* sessionControl;
|
||||||
|
sessionControlTmp->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl);
|
||||||
|
sessionControl->AddRef();
|
||||||
|
sessionControlTmp->Release();
|
||||||
|
Session* session = new Session(this, sessionControl, (size_t)i);
|
||||||
|
endpointSessions.push_back(session);
|
||||||
|
}
|
||||||
|
sessionEnumerator->Release();
|
||||||
|
}
|
||||||
|
|
||||||
void Endpoint::activateEndpointVolume() {
|
void Endpoint::activateEndpointVolume() {
|
||||||
//bool extraThread = false;
|
//bool extraThread = false;
|
||||||
|
|
@ -444,11 +469,21 @@ Flows Endpoint::getFlow() {
|
||||||
return this->flow;
|
return this->flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sessions */
|
||||||
|
std::vector<Session*> Endpoint::getSessions() {
|
||||||
|
return endpointSessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Endpoint::getSessionCount() {
|
||||||
|
return endpointSessions.size();
|
||||||
|
}
|
||||||
|
|
||||||
Endpoint::~Endpoint(){
|
Endpoint::~Endpoint(){
|
||||||
log_debugcpp("murio endpoint-san uwu");
|
log_wdebugcpp(L"murio endpoint-san uwu");
|
||||||
properties->Release();
|
properties->Release();
|
||||||
endpointVolume->Release();
|
endpointVolume->Release();
|
||||||
endpoint->Release();
|
endpoint->Release();
|
||||||
|
sessionManager->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overseer::initCOMLibrary() {
|
void Overseer::initCOMLibrary() {
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0A00
|
#include "msinclude.h"
|
||||||
#include <sdkddkver.h>
|
#include "backsessionclasses.h"
|
||||||
|
|
||||||
//done by qt by def #define UNICODE
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <processthreadsapi.h>
|
|
||||||
#include <mmdeviceapi.h>
|
|
||||||
#include <combaseapi.h>
|
|
||||||
#include <initguid.h>
|
|
||||||
#include <Propidl.h>
|
|
||||||
#include <functiondiscoverykeys_devpkey.h>
|
|
||||||
//#include <debugapi.h>
|
|
||||||
|
|
||||||
#include <endpointvolume.h>
|
|
||||||
#include <audiopolicy.h>
|
|
||||||
#include <audioclient.h>
|
|
||||||
//#include <comdef.h>
|
|
||||||
//#include <comip.h>
|
|
||||||
#include <Winerror.h>
|
|
||||||
#include <stringapiset.h>
|
|
||||||
#include "ipolicyconfig.h"
|
|
||||||
#include <Mmreg.h>
|
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "contclasses.h"
|
#include "contclasses.h"
|
||||||
|
|
||||||
class EndpointVolumeCallback;
|
class EndpointVolumeCallback;
|
||||||
|
class Session;
|
||||||
|
|
||||||
class Endpoint {
|
class Endpoint {
|
||||||
|
|
||||||
|
|
@ -53,15 +32,25 @@ class Endpoint {
|
||||||
Flows getFlow();
|
Flows getFlow();
|
||||||
std::wstring getId();
|
std::wstring getId();
|
||||||
std::wstring getName();
|
std::wstring getName();
|
||||||
|
|
||||||
|
|
||||||
void setVolumeCallback(EndpointVolumeCallback *epc);
|
void setVolumeCallback(EndpointVolumeCallback *epc);
|
||||||
void removeVolumeCallback(EndpointVolumeCallback *epc);
|
void removeVolumeCallback(EndpointVolumeCallback *epc);
|
||||||
|
|
||||||
|
/* sessions */
|
||||||
|
std::vector<Session*> getSessions();
|
||||||
|
size_t getSessionCount();
|
||||||
|
|
||||||
~Endpoint();
|
~Endpoint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void inline activateEndpointVolume();
|
void inline activateEndpointVolume();
|
||||||
|
void inline activateEndpointSessions();
|
||||||
|
|
||||||
|
std::vector<Session*> endpointSessions;
|
||||||
uint32_t channelCount = 0;
|
uint32_t channelCount = 0;
|
||||||
IMMDevice* endpoint;
|
IMMDevice* endpoint;
|
||||||
|
IAudioSessionManager2 *sessionManager;
|
||||||
Flows flow;
|
Flows flow;
|
||||||
IAudioEndpointVolume *endpointVolume = nullptr;
|
IAudioEndpointVolume *endpointVolume = nullptr;
|
||||||
IPropertyStore *properties;
|
IPropertyStore *properties;
|
||||||
|
|
|
||||||
62
src/back/backsessionclasses.cpp
Normal file
62
src/back/backsessionclasses.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "backsessionclasses.h"
|
||||||
|
#include "backfuncs.h"
|
||||||
|
Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx) {
|
||||||
|
this->ep = ep;
|
||||||
|
this->sessionControl = sessionControl;
|
||||||
|
this->idx = idx;
|
||||||
|
|
||||||
|
sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume);
|
||||||
|
DWORD pid;
|
||||||
|
sessionControl->GetProcessId(&pid);
|
||||||
|
if (sessionControl->IsSystemSoundsSession() == S_OK)
|
||||||
|
this->sessionName = std::wstring(LSTRING_SYSTEM_SOUNDS);
|
||||||
|
else {
|
||||||
|
LPWSTR sessionDisplayName;
|
||||||
|
this->sessionControl->GetDisplayName(&sessionDisplayName);
|
||||||
|
this->sessionName = std::wstring(sessionDisplayName);
|
||||||
|
CoTaskMemFree(sessionDisplayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Session::getVolume(int channel){
|
||||||
|
float volume;
|
||||||
|
if (channel == AudioChannel::CHANNEL_MAIN) {
|
||||||
|
if(FAILED(sessionVolume->GetMasterVolume(&volume))) { /* log_debugcpp("si") */;}
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
//if(FAILED(endpointVolume->GetChannelVolumeLevelScalar(channel, &volume))) { /* log_debugcpp("si"); */}
|
||||||
|
}
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uint32_t Endpoint::getChannelCount(){
|
||||||
|
* return (uint32_t)channelCount;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::wstring Session::getName() {
|
||||||
|
return sessionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Session::getMute() {
|
||||||
|
BOOL mut;
|
||||||
|
if(FAILED(sessionVolume->GetMute(&mut))) { /* TIP: Below */ }
|
||||||
|
bool mute = (bool)mut;
|
||||||
|
return mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::setVolume(NGuid guid, int channel, float volume) {
|
||||||
|
//TIP: There used to be log messages here. Now, it's a ghost town.
|
||||||
|
GUID tempMsGuid = NGuidToGUID(guid);
|
||||||
|
if (channel == AudioChannel::CHANNEL_MAIN) {
|
||||||
|
if(FAILED(sessionVolume->SetMasterVolume(volume, &tempMsGuid))) {};
|
||||||
|
} else {
|
||||||
|
//if(FAILED(sessionVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::setMute(NGuid guid, bool muted) {
|
||||||
|
GUID tempMsGuid = NGuidToGUID(guid);
|
||||||
|
if(FAILED(sessionVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"SessionVolume null?")); };
|
||||||
|
}
|
||||||
26
src/back/backsessionclasses.h
Normal file
26
src/back/backsessionclasses.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include "msinclude.h"
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "contclasses.h"
|
||||||
|
|
||||||
|
class Endpoint;
|
||||||
|
|
||||||
|
class Session {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx);
|
||||||
|
void setVolume(NGuid guid, int channel, float volume);
|
||||||
|
float getVolume(int channel);
|
||||||
|
void setMute(NGuid guid, bool muted);
|
||||||
|
bool getMute();
|
||||||
|
std::wstring getName();
|
||||||
|
//uint32_t getChannelCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::wstring sessionName;
|
||||||
|
Endpoint* ep;
|
||||||
|
IAudioSessionControl2* sessionControl = nullptr;
|
||||||
|
ISimpleAudioVolume* sessionVolume = nullptr;
|
||||||
|
size_t idx;
|
||||||
|
};
|
||||||
25
src/back/msinclude.h
Normal file
25
src/back/msinclude.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x0A00
|
||||||
|
#include <sdkddkver.h>
|
||||||
|
|
||||||
|
//done by qt by def #define UNICODE
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
#include <mmdeviceapi.h>
|
||||||
|
#include <combaseapi.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
#include <Propidl.h>
|
||||||
|
#include <functiondiscoverykeys_devpkey.h>
|
||||||
|
//#include <debugapi.h>
|
||||||
|
|
||||||
|
#include <endpointvolume.h>
|
||||||
|
#include <audiopolicy.h>
|
||||||
|
#include <audioclient.h>
|
||||||
|
//#include <comdef.h>
|
||||||
|
//#include <comip.h>
|
||||||
|
#include <Winerror.h>
|
||||||
|
#include <stringapiset.h>
|
||||||
|
#include "ipolicyconfig.h"
|
||||||
|
#include <Mmreg.h>
|
||||||
|
|
@ -14,6 +14,14 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
|
||||||
//epName = ep->getName();
|
//epName = ep->getName();
|
||||||
this->setBackEndpointVolumeCallbackInfoContent(this->getState());
|
this->setBackEndpointVolumeCallbackInfoContent(this->getState());
|
||||||
osh->pushBackEndpointHandler(this, flow);
|
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);
|
||||||
|
sessionHandlers.push_back(sessionHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverseerHandler::pushBackEndpointHandler(EndpointHandler* eph, Flows flow) {
|
void OverseerHandler::pushBackEndpointHandler(EndpointHandler* eph, Flows flow) {
|
||||||
|
|
@ -141,6 +149,19 @@ void EndpointHandler::removeRoles(Roles newRole){
|
||||||
ep->removeRoles(newRole);
|
ep->removeRoles(newRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sessions */
|
||||||
|
size_t EndpointHandler::getSessionCount() {
|
||||||
|
return ep->getSessionCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Session*> EndpointHandler::getSessions(){
|
||||||
|
return ep->getSessions();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SessionHandler*> EndpointHandler::getSessionHandlers(){
|
||||||
|
return this->sessionHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
EndpointHandler::~EndpointHandler() {
|
EndpointHandler::~EndpointHandler() {
|
||||||
ep->removeVolumeCallback(epc);
|
ep->removeVolumeCallback(epc);
|
||||||
epc->Release();
|
epc->Release();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "contsessionclasses.h"
|
||||||
//#define invoke_mem_fn(object,ptrToMember) ((object).*(ptrToMember))
|
//#define invoke_mem_fn(object,ptrToMember) ((object).*(ptrToMember))
|
||||||
//#define pinvoke_mem_fn(object,ptrToMember) ((object)->*(ptrToMember))
|
//#define pinvoke_mem_fn(object,ptrToMember) ((object)->*(ptrToMember))
|
||||||
|
|
||||||
|
|
@ -6,50 +9,7 @@ class EndpointWidget;
|
||||||
class Endpoint;
|
class Endpoint;
|
||||||
class EndpointVolumeCallback;
|
class EndpointVolumeCallback;
|
||||||
class Overseer;
|
class Overseer;
|
||||||
|
class SessionHandler;
|
||||||
enum AudioChannel {
|
|
||||||
CHANNEL_LEFT = (1 << 0),
|
|
||||||
CHANNEL_RIGHT = (1 << 1),
|
|
||||||
CHANNEL_MAIN = ~0,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EndpointState {
|
|
||||||
ENDPOINT_ACTIVE = (1 << 0),
|
|
||||||
ENDPOINT_DISABLED = (1 << 1),
|
|
||||||
ENDPOINT_NOTPRESENT = (1 << 2),
|
|
||||||
ENDPOINT_UNPLUGGED = (1 << 3),
|
|
||||||
ENDPOINT_ALL = 0x0F
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Flows {
|
|
||||||
FLOW_PLAYBACK = (1 << 0),
|
|
||||||
FLOW_CAPTURE = (1 << 1),
|
|
||||||
FLOW_BOTH = (1 << 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Roles {
|
|
||||||
ROLE_CONSOLE = (1 << 0),
|
|
||||||
ROLE_MULTIMEDIA = (1 << 1),
|
|
||||||
ROLE_COMMUNICATIONS = (1 << 2),
|
|
||||||
ROLE_ALL = 0x07,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NGuid {
|
|
||||||
//todo: still leaking?
|
|
||||||
uint32_t data1;
|
|
||||||
uint16_t data2;
|
|
||||||
uint16_t data3;
|
|
||||||
unsigned char data4[8];
|
|
||||||
|
|
||||||
|
|
||||||
/* void freeData4(){ */
|
|
||||||
/* int i = 0; */
|
|
||||||
/* do{ */
|
|
||||||
/* if(this->data4 + i != nullptr) free(data4 + i); */
|
|
||||||
/* i++; */
|
|
||||||
/* }while (i < 8); */
|
|
||||||
/* } */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BackEndpointVolumeCallbackInfo {
|
struct BackEndpointVolumeCallbackInfo {
|
||||||
NGuid caller;
|
NGuid caller;
|
||||||
|
|
@ -98,8 +58,14 @@ public:
|
||||||
void setState(uint8_t state);
|
void setState(uint8_t state);
|
||||||
void setState(uint8_t state, uint64_t idx);
|
void setState(uint8_t state, uint64_t idx);
|
||||||
|
|
||||||
|
/* sessions */
|
||||||
|
size_t getSessionCount();
|
||||||
|
std::vector<SessionHandler*> getSessionHandlers();
|
||||||
|
|
||||||
~EndpointHandler();
|
~EndpointHandler();
|
||||||
private:
|
private:
|
||||||
|
std::vector<Session*> getSessions();
|
||||||
|
|
||||||
uint64_t idx;
|
uint64_t idx;
|
||||||
Endpoint *ep = nullptr;
|
Endpoint *ep = nullptr;
|
||||||
EndpointVolumeCallback *epc = nullptr;
|
EndpointVolumeCallback *epc = nullptr;
|
||||||
|
|
@ -110,6 +76,7 @@ private:
|
||||||
uint64_t frontIdx = INT_MAX;
|
uint64_t frontIdx = INT_MAX;
|
||||||
};
|
};
|
||||||
EndpointHandlerFrontVisibility ephfv;
|
EndpointHandlerFrontVisibility ephfv;
|
||||||
|
std::vector<SessionHandler*> sessionHandlers;
|
||||||
//QSlider *slidy;
|
//QSlider *slidy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
30
src/cont/contsessionclasses.cpp
Normal file
30
src/cont/contsessionclasses.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "contsessionclasses.h"
|
||||||
|
#include "backsessionclasses.h"
|
||||||
|
|
||||||
|
SessionHandler::SessionHandler(EndpointHandler* eph, Session* session, size_t idx) {
|
||||||
|
this->eph = eph;
|
||||||
|
this->idx = idx;
|
||||||
|
this->session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionHandler::setVolume(NGuid guid, int channel, int value){
|
||||||
|
if (channel == AudioChannel::CHANNEL_MAIN)
|
||||||
|
session->setVolume(guid, channel, (float)value / 100);
|
||||||
|
else session->setVolume(guid, channel, (float)value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SessionHandler::getVolume(int channel){
|
||||||
|
return session->getVolume(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionHandler::setMute(NGuid guid, bool muted){
|
||||||
|
session->setMute(guid, muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring SessionHandler::getName(){
|
||||||
|
return session->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SessionHandler::getMute(){
|
||||||
|
return session->getMute();
|
||||||
|
}
|
||||||
23
src/cont/contsessionclasses.h
Normal file
23
src/cont/contsessionclasses.h
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
//#include "contclasses.h"
|
||||||
|
|
||||||
|
class EndpointHandler;
|
||||||
|
class Session;
|
||||||
|
|
||||||
|
class SessionHandler {
|
||||||
|
public:
|
||||||
|
SessionHandler(EndpointHandler* eph, Session* session, size_t idx);
|
||||||
|
void setVolume(NGuid guid, int channel, int value);
|
||||||
|
float getVolume(int channel);
|
||||||
|
void setMute(NGuid guid, bool muted);
|
||||||
|
bool getMute();
|
||||||
|
std::wstring getName();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EndpointHandler* eph;
|
||||||
|
Session* session;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
};
|
||||||
48
src/global.h
48
src/global.h
|
|
@ -18,8 +18,56 @@
|
||||||
#define STRING_ROLE_MULTIMEDIA "Multimedia"
|
#define STRING_ROLE_MULTIMEDIA "Multimedia"
|
||||||
#define STRING_ROLE_COMMUNICATIONS "Communications"
|
#define STRING_ROLE_COMMUNICATIONS "Communications"
|
||||||
#define STRING_ROLE_ALL "All"
|
#define STRING_ROLE_ALL "All"
|
||||||
|
|
||||||
|
#define STRING_SYSTEM_SOUNDS "System Sounds"
|
||||||
|
#define LSTRING_SYSTEM_SOUNDS L"System Sounds"
|
||||||
//INIT BACK
|
//INIT BACK
|
||||||
|
|
||||||
|
enum AudioChannel {
|
||||||
|
CHANNEL_LEFT = (1 << 0),
|
||||||
|
CHANNEL_RIGHT = (1 << 1),
|
||||||
|
CHANNEL_MAIN = ~0,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EndpointState {
|
||||||
|
ENDPOINT_ACTIVE = (1 << 0),
|
||||||
|
ENDPOINT_DISABLED = (1 << 1),
|
||||||
|
ENDPOINT_NOTPRESENT = (1 << 2),
|
||||||
|
ENDPOINT_UNPLUGGED = (1 << 3),
|
||||||
|
ENDPOINT_ALL = 0x0F
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Flows {
|
||||||
|
FLOW_PLAYBACK = (1 << 0),
|
||||||
|
FLOW_CAPTURE = (1 << 1),
|
||||||
|
FLOW_BOTH = (1 << 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Roles {
|
||||||
|
ROLE_CONSOLE = (1 << 0),
|
||||||
|
ROLE_MULTIMEDIA = (1 << 1),
|
||||||
|
ROLE_COMMUNICATIONS = (1 << 2),
|
||||||
|
ROLE_ALL = 0x07,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NGuid {
|
||||||
|
//todo: still leaking?
|
||||||
|
uint32_t data1;
|
||||||
|
uint16_t data2;
|
||||||
|
uint16_t data3;
|
||||||
|
unsigned char data4[8];
|
||||||
|
|
||||||
|
|
||||||
|
/* void freeData4(){ */
|
||||||
|
/* int i = 0; */
|
||||||
|
/* do{ */
|
||||||
|
/* if(this->data4 + i != nullptr) free(data4 + i); */
|
||||||
|
/* i++; */
|
||||||
|
/* }while (i < 8); */
|
||||||
|
/* } */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class OverseerHandler;
|
class OverseerHandler;
|
||||||
extern OverseerHandler *osh;
|
extern OverseerHandler *osh;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,56 @@ void ExtendedCheckBox::customEvent(QEvent* ev) {
|
||||||
QCheckBox::customEvent(ev);
|
QCheckBox::customEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent) : QWidget(parent){
|
||||||
|
//todo: based on qgridlayout, name+mute should be its own widget, same with channels
|
||||||
|
this->idx = idx;
|
||||||
|
this->sh = sh;
|
||||||
|
|
||||||
|
layout = new QGridLayout(this);
|
||||||
|
//this->setLayout(
|
||||||
|
|
||||||
|
muteButton = new QCheckBox(this);
|
||||||
|
mainLabel = new QLabel(QString::fromStdWString(sh->getName()), this);
|
||||||
|
mainSlider = new QSlider(Qt::Horizontal, this);
|
||||||
|
|
||||||
|
mainSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
mainSlider->setFocusPolicy(Qt::StrongFocus);
|
||||||
|
mainSlider->setTickPosition(QSlider::TicksBothSides);
|
||||||
|
mainSlider->setTickInterval(5);
|
||||||
|
mainSlider->setSingleStep(1);
|
||||||
|
mainSlider->setRange(0,100);
|
||||||
|
|
||||||
|
muteButton->setCheckState((sh->getMute() == false ? Qt::Unchecked : Qt::Checked));
|
||||||
|
muteButton->setText(sh->getMute() ? STRING_UNMUTE : STRING_MUTE);
|
||||||
|
float volume = sh->getVolume(AudioChannel::CHANNEL_MAIN) * 100;
|
||||||
|
mainSlider->setValue((int)volume);
|
||||||
|
log_debugcpp("SESSION SET WITH VOLUME " + std::to_string(volume));
|
||||||
|
|
||||||
|
//tip: would need to be new widget with layout in it
|
||||||
|
//mainMuteLayout = new QGridLayout();
|
||||||
|
layout->addWidget(mainLabel, 0, 0, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
|
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
|
layout->addWidget(mainSlider, 0, 2, 1, 2);
|
||||||
|
|
||||||
|
//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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionWidget::updateMute(int checked){
|
||||||
|
bool muted = (checked == 2 ? true : false);
|
||||||
|
this->sh->setMute(osh->getGuid(), muted);
|
||||||
|
this->muteButton->setText(this->sh->getMute() ? STRING_UNMUTE : STRING_MUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionWidget::updateMainVolume(int newValue){
|
||||||
|
this->sh->setVolume(osh->getGuid(), AudioChannel::CHANNEL_MAIN, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){
|
EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){
|
||||||
//todo: based on qgridlayout, name+mute should be its own widget, same with channels
|
//todo: based on qgridlayout, name+mute should be its own widget, same with channels
|
||||||
|
int row = 0;
|
||||||
this->idx = idx;
|
this->idx = idx;
|
||||||
this->eph = eph;
|
this->eph = eph;
|
||||||
//todo: sussy
|
//todo: sussy
|
||||||
|
|
@ -52,7 +100,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
mainSlider = new QSlider(Qt::Horizontal, this);
|
mainSlider = new QSlider(Qt::Horizontal, this);
|
||||||
|
|
||||||
if (this->eph->getState() != EndpointState::ENDPOINT_ACTIVE) {
|
if (this->eph->getState() != EndpointState::ENDPOINT_ACTIVE) {
|
||||||
layout->addWidget(mainLabel, 0, 0);
|
layout->addWidget(mainLabel, row, 0);
|
||||||
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
|
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -73,9 +121,10 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
|
|
||||||
//tip: would need to be new widget with layout in it
|
//tip: would need to be new widget with layout in it
|
||||||
//mainMuteLayout = new QGridLayout();
|
//mainMuteLayout = new QGridLayout();
|
||||||
layout->addWidget(mainLabel, 0, 0, Qt::AlignLeft | Qt::AlignBottom);
|
layout->addWidget(mainLabel, row, 0, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom);
|
layout->addWidget(muteButton, row, 1, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
layout->addWidget(mainSlider, 0, 2, 1, 2);
|
layout->addWidget(mainSlider, row, 2, 1, 2);
|
||||||
|
row++;
|
||||||
|
|
||||||
//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?
|
//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(EndpointWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&EndpointWidget::updateMainVolume);
|
connect<void(QSlider::*)(int), void(EndpointWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&EndpointWidget::updateMainVolume);
|
||||||
|
|
@ -99,8 +148,9 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
tmpLb->setText(QString::number(volume));
|
tmpLb->setText(QString::number(volume));
|
||||||
this->channelSliders.push_back(tmp);
|
this->channelSliders.push_back(tmp);
|
||||||
this->channelLabels.push_back(tmpLb);
|
this->channelLabels.push_back(tmpLb);
|
||||||
layout->addWidget(tmp, 2, i);
|
layout->addWidget(tmp, row + 1, i);
|
||||||
layout->addWidget(tmpLb, 3, i);
|
layout->addWidget(tmpLb, row + 2, i);
|
||||||
|
|
||||||
//TODO: check if there's a need to prevent deadlocks; probably this will eventually turn into its own func
|
//TODO: check if there's a need to prevent deadlocks; probably this will eventually turn into its own func
|
||||||
//this causes channel bar desync when back -> front. blocksignals below fix it. huh.
|
//this causes channel bar desync when back -> front. blocksignals below fix it. huh.
|
||||||
connect(tmp, &QSlider::valueChanged, [this, i](int newValue){
|
connect(tmp, &QSlider::valueChanged, [this, i](int newValue){
|
||||||
|
|
@ -108,6 +158,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
this->channelLabels.at(i)->setText(QString::number(newValue));
|
this->channelLabels.at(i)->setText(QString::number(newValue));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
row += 3;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Role ExtendedCheckBoxes setup
|
* Role ExtendedCheckBoxes setup
|
||||||
|
|
@ -145,11 +196,11 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
this->eph->setRoles(Roles::ROLE_COMMUNICATIONS);
|
this->eph->setRoles(Roles::ROLE_COMMUNICATIONS);
|
||||||
});
|
});
|
||||||
|
|
||||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), 5, 0);
|
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), row, 0);
|
||||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), 5, 1);
|
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), row, 1);
|
||||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), 5, 2);
|
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), row, 2);
|
||||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS), 5, 3);
|
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS), row, 3);
|
||||||
|
row++;
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -158,6 +209,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
timer = new QTimer();
|
timer = new QTimer();
|
||||||
connect(timer, &QTimer::timeout, [this, eph](){
|
connect(timer, &QTimer::timeout, [this, eph](){
|
||||||
//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.
|
//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;
|
const float roundingFactor = 0.005;
|
||||||
mainSlider->blockSignals(true);
|
mainSlider->blockSignals(true);
|
||||||
muteButton->blockSignals(true);
|
muteButton->blockSignals(true);
|
||||||
|
|
@ -180,6 +232,14 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
});
|
});
|
||||||
timer->start(10);
|
timer->start(10);
|
||||||
|
|
||||||
|
/* sessions */
|
||||||
|
for (size_t i = 0; i < eph->getSessionCount(); i++) {
|
||||||
|
SessionWidget* sessionWidget = new SessionWidget(i, eph->getSessionHandlers().at(i), this);
|
||||||
|
layout->addWidget(sessionWidget, row, 4);
|
||||||
|
row++;
|
||||||
|
sessionWidgets.push_back(sessionWidget);
|
||||||
|
}
|
||||||
|
|
||||||
//todo parent?
|
//todo parent?
|
||||||
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
|
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
|
||||||
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 4, 0);
|
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 4, 0);
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,25 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SessionWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent /* = nullptr */);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateMainVolume(int newValue);
|
||||||
|
void updateMute(int checked);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel *mainLabel = nullptr;
|
||||||
|
QSlider *mainSlider = nullptr;
|
||||||
|
uint64_t idx;
|
||||||
|
QGridLayout *layout = nullptr;
|
||||||
|
QCheckBox *muteButton = nullptr;
|
||||||
|
SessionHandler* sh;
|
||||||
|
};
|
||||||
|
|
||||||
class EndpointWidget : public QWidget {
|
class EndpointWidget : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -126,6 +145,7 @@ private:
|
||||||
size_t defaultRolesVectorSize = 4;
|
size_t defaultRolesVectorSize = 4;
|
||||||
QTimer* timer = nullptr;
|
QTimer* timer = nullptr;
|
||||||
uint64_t idx;
|
uint64_t idx;
|
||||||
|
std::vector<SessionWidget*> sessionWidgets;
|
||||||
//std::vector<EndpointHandler*> *ephs;
|
//std::vector<EndpointHandler*> *ephs;
|
||||||
//std::vector<QSlider> *sliders;
|
//std::vector<QSlider> *sliders;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue