mixer/src/back/backlasses.cpp
2024-05-11 22:39:49 +02:00

763 lines
22 KiB
C++

#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) {
if (eph->getFlow() == Flows::FLOW_CAPTURE) return S_OK;
HRESULT result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
IAudioSessionControl2* sessionControl;
//ISimmpleAudioVolume* sessionVolume;
if (FAILED(NewSession->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl))) { log_wdebugcpp(L"no nueva sesion......"); };
if (sessionControl) {
sessionControl->AddRef();
//sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume);
Session* newSession = new Session(this->eph->getEndpoint(), sessionControl);
eph->addSessionSendFront(newSession);
}
if (result == S_OK)
CoUninitialize();
return S_OK;
}
EndpointVolumeCallback::EndpointVolumeCallback(Endpoint* ep){
this->ep = ep;
}
ULONG EndpointVolumeCallback::AddRef(){
return InterlockedIncrement(&ref);
}
ULONG EndpointVolumeCallback::Release(){
ULONG tempRef = InterlockedDecrement(&ref);
if (tempRef == 0) {
delete this;
}
return tempRef;
}
HRESULT EndpointVolumeCallback::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;
}
HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) {
if (pNotify == NULL) return E_INVALIDARG;
//delete osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller;
//osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.freeData4();
//Could've made a function or = override to hide this within Nguid, but back in cont = bad.
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data1 \
= pNotify->guidEventContext.Data1;
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data2 \
= pNotify->guidEventContext.Data2;
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data3 \
= pNotify->guidEventContext.Data3;
for(int i = 0; i < 8 /* Data4 size */; i++){
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data4[i] = pNotify->guidEventContext.Data4[i];
}
//memcpy(&osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller, &pNotify->guidEventContext,sizeof(NGuid) );
Flows flow = this->ep->getFlow();
EndpointHandler* eph = nullptr;
if (flow & Flows::FLOW_PLAYBACK) {
eph = osh->getPlaybackEndpointHandlers().at(this->ep->getIndex());
} else {
eph = osh->getCaptureEndpointHandlers().at(this->ep->getIndex());
}
eph->getCallbackInfo()->muted = pNotify->bMuted;
eph->getCallbackInfo()->mainVolume = pNotify->fMasterVolume;
eph->getCallbackInfo()->channels = pNotify->nChannels;
UINT j = 0;
//todo: do while here caused stack corruption; sus
while(j < pNotify->nChannels) {
if (flow & Flows::FLOW_PLAYBACK)
eph->getCallbackInfo()->channelVolumes[j] = pNotify->afChannelVolumes[j];
else
eph->getCallbackInfo()->channelVolumes[j] = pNotify->afChannelVolumes[j];
j++;
}
return S_OK;
}
EndpointSituationCallback::EndpointSituationCallback(Overseer* os){
this->os = os;
}
ULONG EndpointSituationCallback::AddRef(){
return InterlockedIncrement(&ref);
}
ULONG EndpointSituationCallback::Release(){
ULONG tempRef = InterlockedDecrement(&ref);
if (tempRef == 0) {
delete this;
}
return tempRef;
}
HRESULT EndpointSituationCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IMMNotificationClient) == riid)
{
AddRef();
*ppvInterface = (IMMNotificationClient*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
HRESULT EndpointSituationCallback::OnDefaultDeviceChanged(EDataFlow flow, ERole role,LPCWSTR pwstrDeviceId) {
if (flow == EDataFlow::eCapture) return E_INVALIDARG;
Roles nRole;
switch (role) {
case ERole::eConsole:
nRole = Roles::ROLE_CONSOLE;
break;
case ERole::eMultimedia:
nRole = Roles::ROLE_MULTIMEDIA;
break;
case ERole::eCommunications:
nRole = Roles::ROLE_COMMUNICATIONS;
break;
}
std::wstring wstringEndpointId = pwstrDeviceId;
log_wdebugcpp(L"we got za defol 4 " + wstringEndpointId);
osh->changeFrontDefaultsCallback(nRole, wstringEndpointId);
return S_OK;
}
HRESULT EndpointSituationCallback::OnDeviceAdded(LPCWSTR pwstrDeviceId) {
log_wdebugcpp(L"ayo we eventing za adin " + std::wstring(pwstrDeviceId));
return S_OK;
};
HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) {
log_wdebugcpp(L"ayo we eventing za rmovin " + std::wstring(pwstrDeviceId));
return S_OK;
}
HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) {
std::wstring endpointId = std::wstring(pwstrDeviceId);
switch (dwNewState){
case DEVICE_STATE_ACTIVE:
osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_ACTIVE);
break;
case DEVICE_STATE_DISABLED:
osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_DISABLED);
break;
case DEVICE_STATE_NOTPRESENT:
osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_NOTPRESENT);
break;
case DEVICE_STATE_UNPLUGGED:
osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_UNPLUGGED);
break;
}
return S_OK;
}
HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) {
os->updateEndpointInfo(std::wstring(pwstrDeviceId));
return S_OK;
}
Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
this->endpoint = ep;
this->idx = idx;
/*
* It can't multiflag, it's that stupid. MS momento.
* Only shows most relevant flag according to MS, i.e. 0110 sends 0010
*/
//todo: preguntitas owindows dword no es uint32_t even tho mingw mingas
if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-2);};
if(this->endpointState == EndpointState::ENDPOINT_ACTIVE) {
activateEndpointVolume();
//if(FAILED(endpoint->Activate(__uuidof(IAudioClient),
// CLSCTX_ALL, NULL, (void**)&audioClient))) { log_debugcpp("audioclntbros..."); }
//audioClient->GetDevicePeriod(&defTime, &minTime);
}
reloadEndpointChannels();
//todo: atexit into exit Gather ID
LPWSTR tempString = nullptr;
if (FAILED(endpoint->GetId(&tempString))) {exit(-1);};
endpointId = std::wstring(tempString);
log_wdebugcpp(endpointId);
CoTaskMemFree(tempString);
endpoint->OpenPropertyStore(STGM_READ, &properties);
this->updateName();
this->setFlow();
if (this->flow == Flows::FLOW_PLAYBACK) {
activateEndpointSessions();
log_debugcpp("plays back");
}
}
void Endpoint::updateName() {
PROPVARIANT pv;
#define store_name(key, propvariant, wstr) do { \
properties->GetValue(key , &propvariant); \
if (pv.pwszVal == nullptr) wstr = L"Unnamed Not Present Endpoint"; \
else wstr = std::wstring(pv.pwszVal); \
} while (0)
store_name(PKEY_Device_FriendlyName, pv, friendlyName);
store_name(PKEY_Device_DeviceDesc, pv, descriptionName);
store_name(PKEY_DeviceInterface_FriendlyName, pv, deviceName);
#undef store_name
log_wdebugcpp(L"Endpoint name: " + friendlyName);
}
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; }
endpointSessions.resize(1, nullptr);
int sessionCount;
sessionEnumerator->GetCount(&sessionCount);
for (int i = 0; i < sessionCount; i++) {
IAudioSessionControl* sessionControlTmp;
sessionEnumerator->GetSession(i, (IAudioSessionControl**)&sessionControlTmp);
/*todo: borrar when donezo
* float test2;
* IAudioMeterInformation* ttmp = (IAudioMeterInformation*)sessionControlTmp;
* ttmp->GetPeakValue(&test2);
*/
//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);
if (sessionControl->IsSystemSoundsSession() == S_OK) endpointSessions[0] = session;
else endpointSessions.push_back(session);
}
sessionEnumerator->Release();
}
void Endpoint::addSession(Session* session) {
session->setIndex(this->getSessionCount());
endpointSessions.push_back(session);
}
void Endpoint::activateEndpointVolume() {
//bool extraThread = false;
/*
* Forgive me, for MS has sinned, and now I must too.
*/
if (this->endpointVolume == nullptr){
HRESULT result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&this->endpointVolume);
//todo: check header
if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); }
//
//if (endpointVolume == nullptr) { //why they returning 0 after dealing with the error jfc CO_E_NOTINITIALIZED) {
//CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
//extraThread = true;
//goto initialized;
//}
//log_debugcpp(std::string("no endpointVolume (IAudioEndpointVolume)"));
if (result == S_OK)
CoUninitialize();
}
}
void Endpoint::reloadEndpointChannels() {
if (this->endpointState == DEVICE_STATE_ACTIVE) {
if (FAILED(endpointVolume->GetChannelCount(&channelCount))) {log_debugcpp("get channel count fail");};/* */
}
}
void Endpoint::setIndex(uint64_t idx){
this->idx = idx;
}
uint64_t Endpoint::getIndex(){
return idx;
}
std::wstring Endpoint::getName(){
return friendlyName;
}
std::wstring Endpoint::getId(){
return endpointId;
}
float Endpoint::getPeakVolume() {
float peakVol;
if(endpointPeakMeter) endpointPeakMeter->GetPeakValue(&peakVol);
else return 0;
return peakVol;
}
float Endpoint::getVolume(int channel){
float volume;
if (channel == AudioChannel::CHANNEL_MAIN) {
if(FAILED(endpointVolume->GetMasterVolumeLevelScalar(&volume))) { /* log_debugcpp("si") */;}
} else {
if(FAILED(endpointVolume->GetChannelVolumeLevelScalar(channel, &volume))) { /* log_debugcpp("si"); */}
}
return volume;
}
uint32_t Endpoint::getChannelCount(){
return (uint32_t)channelCount;
}
bool Endpoint::getMute(){
BOOL mut;
if(FAILED(endpointVolume->GetMute(&mut))) { /* TIP: Below */ }
bool mute = (bool)mut;
return mute;
}
void Endpoint::setState(uint8_t state){
this->endpointState = state;
if(state == EndpointState::ENDPOINT_ACTIVE) {
this->activateEndpointVolume();
this->reloadEndpointChannels();
}
}
size_t Endpoint::getState(){
return this->endpointState;
}
void Endpoint::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(endpointVolume->SetMasterVolumeLevelScalar(volume, &tempMsGuid))) {};
} else {
if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {};
}
}
void Endpoint::setMute(NGuid guid, bool muted) {
GUID tempMsGuid = NGuidToGUID(guid);
if(FAILED(endpointVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"EndpointVolume null?")); };
}
void Endpoint::setVolumeCallback(EndpointVolumeCallback *epc){
if(endpointVolume == nullptr) {
this->activateEndpointVolume();
}
endpointVolume->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)epc);
}
void Endpoint::removeVolumeCallback(EndpointVolumeCallback *epc){
endpointVolume->UnregisterControlChangeNotify((IAudioEndpointVolumeCallback*)epc);
}
Roles Endpoint::getRoles(){
return this->endpointRoles;
}
void Endpoint::setRoles(Roles role){
//todo: otro exe momento
STARTUPINFOEXW startupConfig;
PROCESS_INFORMATION processInfo;
SecureZeroMemory(&startupConfig, sizeof(STARTUPINFOEXW));
SecureZeroMemory(&startupConfig.StartupInfo, sizeof(STARTUPINFOW));
startupConfig.StartupInfo.cb = sizeof(STARTUPINFOEXW);
SecureZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
std::wstring command = L"SoundVolumeView.exe /SetDefault " + endpointId + L" ";
std::wstring troublePair = L"1";
switch (role) {
case Roles::ROLE_ALL:
/*
* console or multimedia, one sends both, at least for now;
* either cos of ms or dis guy;
* no choice but to treat them as one for now.
* command += L"all"; and nothing else would've been nice...
*/
troublePair = command + troublePair;
if(CreateProcessW(
NULL,
(wchar_t*)troublePair.c_str(),
NULL,
NULL,
false,
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
(LPSTARTUPINFOW)&startupConfig,
&processInfo
) == true) {
WaitForSingleObject(processInfo.hProcess, INFINITE );
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
command += L"2";
break;
case Roles::ROLE_CONSOLE:
command += std::to_wstring(0);
break;
case Roles::ROLE_MULTIMEDIA:
command += std::to_wstring(1);
break;
case Roles::ROLE_COMMUNICATIONS:
command += std::to_wstring(2);
break;
}
if(CreateProcessW(
NULL,
(wchar_t*)command.c_str(),
NULL,
NULL,
false,
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
(LPSTARTUPINFOW)&startupConfig,
&processInfo
) == true) {
WaitForSingleObject(processInfo.hProcess, INFINITE );
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
}
void Endpoint::assignRoles(Roles role){
Roles roles = (Roles)(endpointRoles | role);
this->endpointRoles = roles;
}
void Endpoint::removeRoles(Roles role){
Roles roles = (Roles)(endpointRoles ^ role);
this->endpointRoles = roles;
}
void Endpoint::setFlow() {
IMMEndpoint* flowGetter;
//this should be as simple as writing IID_IMMEndpoint, but it just won't find the macro, so I reimpl it. Sad.
if(FAILED(this->endpoint->QueryInterface(__uuidof(IMMEndpoint), (void**)&flowGetter)))
{ log_debugcpp("no flow..."); }
EDataFlow MSflow;
HRESULT vafllar = flowGetter->GetDataFlow(&MSflow);
this->flow = (MSflow == EDataFlow::eRender ? Flows::FLOW_PLAYBACK : Flows::FLOW_CAPTURE);
log_debugcpp("Endpoint flow: " + std::to_string(flow));
flowGetter->Release();
}
Flows Endpoint::getFlow() {
return this->flow;
}
/* sessions */
std::vector<Session*> Endpoint::getSessions() {
return endpointSessions;
}
size_t Endpoint::getSessionCount() {
return endpointSessions.size();
}
void Endpoint::registerNewSessionNotification(EndpointNewSessionCallback* ensc){
sessionManager->RegisterSessionNotification(ensc);
}
void Endpoint::unregisterNewSessionNotification(EndpointNewSessionCallback* ensc){
sessionManager->UnregisterSessionNotification(ensc);
}
Endpoint::~Endpoint(){
log_wdebugcpp(L"murio endpoint-san uwu");
properties->Release();
endpointVolume->Release();
endpoint->Release();
sessionManager->Release();
}
void Overseer::initCOMLibrary() {
OutputDebugStringW(L"EPWidget creation\n");
if(FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE))) {
log_debugcpp("si"); };
//Retrieving endpoint enumerator
//MMDeviceEnumerator es el CLSID de toda la vaina de MMDevicear
if(FAILED(CoCreateInstance( __uuidof(MMDeviceEnumerator), NULL,
CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
(void**)&deviceEnumerator)) )
{ log_debugcpp("si"); };
GUID tempGuid;
if(FAILED(CoCreateGuid(&tempGuid))) { log_debugcpp("Failed to obtain GUID: " ); };
//todo: wtf? why is it working? floats are ptrs...
this->guid = GUIDToNGuid(&tempGuid);
HRESULT hre = CoCreateInstance(__uuidof(CPolicyConfigClient),
NULL, CLSCTX_ALL,
__uuidof(IPolicyConfig7), (LPVOID *)&policyConfig);
if (hre != S_OK) exit(-1);
//TODO: Release lpguid?
//TODO: Uninitialize COM
}
void Overseer::reloadEndpoints(Flows flow) {
IMMDeviceCollection *deviceCollection;
unsigned int numEndpoints;
EDataFlow MSflow = (flow == Flows::FLOW_PLAYBACK ? EDataFlow::eRender : EDataFlow::eCapture);
// | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED
// NOTPRESENT shows a lot of garbage, unnamed devices.
if(FAILED(deviceEnumerator->EnumAudioEndpoints(MSflow, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED, &deviceCollection) ))
{ log_debugcpp("si"); };
/*
* Counting them
*/
if(FAILED(deviceCollection->GetCount(&numEndpoints))) { log_debugcpp("si");};
if(numEndpoints == 0) { log_debugcpp("si"); };
/*
* Retrieving actual endpoints and storing them on their own collection
*/
IMMDevice *temp;
for (unsigned int i = 0; i < numEndpoints; i++){
if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); };
Endpoint *endpoint = new Endpoint(temp, i);
if (flow == Flows::FLOW_PLAYBACK)
this->playbackDevices.push_back(endpoint);
else
this->captureDevices.push_back(endpoint);
//TODO: le porblemx std::cout + "ola" + std::endl;
}
deviceCollection->Release();
//IPolicyConfig7 test
/*
* deviceEnumerator->GetDefaultAudioEndpoint(MSflow, ERole::eCommunications, &temp);
* LPWSTR tempString = nullptr;
* temp->GetId(&tempString);
* HRESULT hre = policyConfig->SetDefaultEndpoint(
* tempString,
* ERole::eMultimedia
* );
*/
/*
* Discerning default endpoints per role
* order: console, multimedia, communications
*/
for(int i = 0; i < ERole_enum_count; i++){
ERole val;
switch(i) {
case 0:
val = eConsole;
break;
case 1:
val = eMultimedia;
break;
case 2:
val = eCommunications;
break;
}
deviceEnumerator->GetDefaultAudioEndpoint(MSflow, val, &temp);
LPWSTR id = nullptr;
if (flow == Flows::FLOW_PLAYBACK) {
for (unsigned int j = 0; j < numEndpoints; j++) {
std::wstring eptId = playbackDevices.at(j)->getId();
temp->GetId(&id);
int comparison = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, eptId.c_str(), -987, id, -987, NULL, NULL, 0);
if (comparison - 2 == 0) {
log_wdebugcpp(L"ola defaul playback de " + std::to_wstring(i) + L" es " + id);
playbackDevices.at(j)->assignRoles((Roles)(1 << i));
}
}
} else {
for (unsigned int j = 0; j < numEndpoints; j++){
std::wstring eptId = captureDevices.at(j)->getId();
temp->GetId(&id);
int comparison = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, eptId.c_str(), -987, id, -987, NULL, NULL, 0);
if (comparison - 2 == 0) {
log_wdebugcpp(L"ola defaul capture de "
+ std::to_wstring(i) + L" es " + id);
captureDevices.at(j)->assignRoles((Roles)(1 << i));
}
}
}
}
}
Endpoint* Overseer::addEndpoint(std::wstring endpointId, /* out */Flows* flow = nullptr) {
IMMDevice* newep;
if(FAILED(deviceEnumerator->GetDevice((LPCWSTR)endpointId.c_str(), &newep)))
log_debugcpp("ay caramba con la hot metida.");
Endpoint *endpoint = new Endpoint(newep);
Flows getFlow = endpoint->getFlow();
if (getFlow == Flows::FLOW_PLAYBACK) {
endpoint->setIndex(osh->getPlaybackEndpointsCount());
this->playbackDevices.push_back(endpoint);
} else {
endpoint->setIndex(osh->getCaptureEndpointsCount());
this->captureDevices.push_back(endpoint);
}
if (flow != nullptr) *flow = getFlow;
return endpoint;
}
Overseer::Overseer() : epsc(this){
//Initializing COM library
log_debugcpp("Initializing Overseer");
initCOMLibrary();
//Obtaining playback endpoint collection on this point in time
reloadEndpoints(Flows::FLOW_PLAYBACK);
//reloadEndpoints(Flows::FLOW_CAPTURE);
//Registering for endpoint information callback
//this->epsc.fill(deviceEnumerator, playbackDevices, captureDevices);
//this->epsc.fill(deviceEnumerator);
if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); }
}
void Overseer::openControlPanel() {
STARTUPINFOEXW startupConfig;
PROCESS_INFORMATION processInfo;
SecureZeroMemory(&startupConfig, sizeof(STARTUPINFOEXW));
SecureZeroMemory(&startupConfig.StartupInfo, sizeof(STARTUPINFOW));
startupConfig.StartupInfo.cb = sizeof(STARTUPINFOEXW);
SecureZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
std::wstring command = L"rundll32 shell32, Control_RunDLL mmsys.cpl";
if(CreateProcessW(
NULL,
(wchar_t*)command.c_str(),
NULL,
NULL,
false,
CREATE_UNICODE_ENVIRONMENT,
NULL,
NULL,
(LPSTARTUPINFOW)&startupConfig,
&processInfo
) == true) {
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
}
NGuid Overseer::getGuid() {
return guid;
}
std::vector<Endpoint*> Overseer::getPlaybackEndpoints() {
return playbackDevices;
}
std::vector<Endpoint*> Overseer::getCaptureEndpoints() {
return captureDevices;
}
void Overseer::updateEndpointInfo(std::wstring endpointId) {
log_wdebugcpp(L"new name Endpoint id: " + endpointId);
//todo: reintroduce capture devices
for(auto ep : playbackDevices) {
if (ep->getId() == endpointId) {
ep->updateName();
osh->updateFrontEndpointName(ep);
break;
}
}
}
Overseer::~Overseer(){
log_debugcpp("cum");
deviceEnumerator->Release();
for(unsigned long long i = 0; i < playbackDevices.size(); i++){
delete(playbackDevices.at(i));
}
}
//int Overseer::getCaptureEndpoints(std::vector<Endpoint*> *captureEndpoints);
//IMMDeviceEnumerator** Overseer::setOrigin();