diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index 517e10d..a2271ea 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -48,8 +48,8 @@ HRESULT EndpointNewSessionCallback::OnSessionCreated(IAudioSessionControl *NewSe Session* newSession = new Session(this->eph->getEndpoint(), sessionControl); SessionThreadParams tp = { .eph = this->eph, .session = newSession, .isDelete = false }; - std::thread sessionThread(EndpointNewSessionCallback::createSessionThread, tp); - sessionThread.detach(); + std::thread newSessionThread(EndpointNewSessionCallback::createSessionThread, tp); + newSessionThread.detach(); } return S_OK; @@ -97,43 +97,55 @@ HRESULT EndpointVolumeCallback::QueryInterface(REFIID riid, VOID **ppvInterface) HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) { if (pNotify == NULL) return E_INVALIDARG; + AUDIO_VOLUME_NOTIFICATION_DATA paramCopy; + memcpy(¶mCopy, pNotify, sizeof(AUDIO_VOLUME_NOTIFICATION_DATA)); + float* channelVolumes = (float*)malloc(pNotify->nChannels * sizeof(float)); + for (int i = 0; i < pNotify->nChannels; i++) { + channelVolumes[i] = pNotify->afChannelVolumes[i]; + } + std::thread updateVolumeThread(&EndpointVolumeCallback::updateVolumeInfo, this, paramCopy, channelVolumes); + updateVolumeThread.detach(); + return S_OK; +} + +void EndpointVolumeCallback::updateVolumeInfo(AUDIO_VOLUME_NOTIFICATION_DATA newVolume, float* channelVolumes) { //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; + = newVolume.guidEventContext.Data1; osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data2 \ - = pNotify->guidEventContext.Data2; + = newVolume.guidEventContext.Data2; osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data3 \ - = pNotify->guidEventContext.Data3; + = newVolume.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]; + osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data4[i] = newVolume.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()); - } + //memcpy(&osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller, &newVolume.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; + eph->getCallbackInfo()->muted = newVolume.bMuted; + eph->getCallbackInfo()->mainVolume = newVolume.fMasterVolume; + eph->getCallbackInfo()->channels = newVolume.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; + UINT j = 0; + //todo: do while here caused stack corruption; sus + while(j < newVolume.nChannels) { + if (flow & Flows::FLOW_PLAYBACK) + eph->getCallbackInfo()->channelVolumes[j] = channelVolumes[j]; + else + eph->getCallbackInfo()->channelVolumes[j] = channelVolumes[j]; + j++; + } + free(channelVolumes); } @@ -210,31 +222,34 @@ HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) { HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { std::wstring endpointId = std::wstring(pwstrDeviceId); + EndpointState newState; switch (dwNewState) { case DEVICE_STATE_ACTIVE: - osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_ACTIVE); + newState = EndpointState::ENDPOINT_ACTIVE; break; case DEVICE_STATE_DISABLED: - osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_DISABLED); + newState = EndpointState::ENDPOINT_DISABLED; break; case DEVICE_STATE_NOTPRESENT: - osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_NOTPRESENT); + newState = EndpointState::ENDPOINT_NOTPRESENT; break; case DEVICE_STATE_UNPLUGGED: - osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_UNPLUGGED); + newState = EndpointState::ENDPOINT_UNPLUGGED; break; } - + std::thread newEndpointThread(&OverseerHandler::reviseEndpointShowing, osh, + endpointId, newState); + newEndpointThread.detach(); return S_OK; } HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { - //TODO: New thread + Mutex - os->updateEndpointInfo(std::wstring(pwstrDeviceId)); + std::thread propertyThread(&Overseer::updateEndpointInfo, os, std::wstring(pwstrDeviceId)); + propertyThread.detach(); return S_OK; } -Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx){ +Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx) { this->endpoint = ep; this->idx = idx; this->policyConfig = policyConfig; @@ -242,7 +257,9 @@ Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx){ * It can't multiflag, it's that stupid. MS momento. * Only shows most relevant flag according to MS, i.e. 0110 sends 0010 */ - if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-2);}; + DWORD state; + if(FAILED(endpoint->GetState(&state))) {exit(-2);}; + this->endpointState = (EndpointState)state; if(this->endpointState == EndpointState::ENDPOINT_ACTIVE) { activateEndpointVolume(); @@ -253,11 +270,9 @@ Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx){ } - reloadEndpointChannels(); - //todo: atexit into exit Gather ID LPWSTR tempString = nullptr; - if (FAILED(endpoint->GetId(&tempString))) {exit(-1);}; + if (FAILED(endpoint->GetId(&tempString))) { exit(-1); }; endpointId = std::wstring(tempString); log_wdebugcpp(endpointId); CoTaskMemFree(tempString); @@ -265,6 +280,8 @@ Endpoint::Endpoint(IMMDevice* ep, IPolicyConfig7* policyConfig, uint64_t idx){ endpoint->OpenPropertyStore(STGM_READ, &properties); this->updateName(); this->setFlow(); + + reloadEndpointChannels(); } void Endpoint::updateName() { @@ -319,28 +336,19 @@ void Endpoint::addSession(Session* 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); + //If this EP is created after init, COM won't be initialized on the executing thread. + HRESULT result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (this->endpointVolume == nullptr) { 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(); + CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { + log_debugcpp("peakbros..."); + } } + if (result == S_OK) + CoUninitialize(); } void Endpoint::reloadEndpointChannels() { @@ -393,7 +401,7 @@ bool Endpoint::getMute(){ return mute; } -void Endpoint::setState(uint8_t state){ +void Endpoint::setState(EndpointState state){ this->endpointState = state; if(state == EndpointState::ENDPOINT_ACTIVE) { this->activateEndpointVolume(); @@ -401,7 +409,7 @@ void Endpoint::setState(uint8_t state){ } } -size_t Endpoint::getState(){ +EndpointState Endpoint::getState(){ return this->endpointState; } @@ -409,9 +417,13 @@ 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))) {}; + if(FAILED(endpointVolume->SetMasterVolumeLevelScalar(volume, &tempMsGuid))) { + log_wdebugcpp(L"Master volume failed for endpoint: " + friendlyName); + }; } else { - if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {}; + if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) { + log_wdebugcpp(L"Channel " + std::to_wstring(channel) + L" volume failed for endpoint: " + friendlyName); + }; } } @@ -525,9 +537,8 @@ Endpoint::~Endpoint(){ } void Overseer::initCOMLibrary() { - OutputDebugStringW(L"EPWidget creation\n"); if(FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE))) { - log_debugcpp("si"); }; + log_debugcpp("Not even COM?"); }; //Retrieving endpoint enumerator @@ -535,7 +546,7 @@ void Overseer::initCOMLibrary() { if(FAILED(CoCreateInstance( __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&deviceEnumerator)) ) - { log_debugcpp("si"); }; + { log_debugcpp("No MMDeviceEnum. Weird."); }; GUID tempGuid; if(FAILED(CoCreateGuid(&tempGuid))) { log_debugcpp("Failed to obtain GUID: " ); }; @@ -551,7 +562,7 @@ void Overseer::initCOMLibrary() { //TODO: Uninitialize COM } -void Overseer::reloadEndpoints(Flows flow) { +void Overseer::createEndpoints(Flows flow) { IMMDeviceCollection *deviceCollection; unsigned int numEndpoints; EDataFlow MSflow = (flow == Flows::FLOW_PLAYBACK ? EDataFlow::eRender : EDataFlow::eCapture); @@ -631,9 +642,15 @@ void Overseer::reloadEndpoints(Flows flow) { } Endpoint* Overseer::addEndpoint(std::wstring endpointId, /* out */Flows* flow = nullptr) { + //This method is only called from the new endpoint callback and its subsequent thread, + //so another STA can be safely instantiated + if(FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE))) { + log_debugcpp("EP Callback Thread failed. Sad!"); + return nullptr; + } IMMDevice* newep; if(FAILED(deviceEnumerator->GetDevice((LPCWSTR)endpointId.c_str(), &newep))) - log_debugcpp("ay caramba con la hot metida."); + log_debugcpp("ay caramba con la hot metida. Sad!"); Endpoint *endpoint = new Endpoint(newep, policyConfig); @@ -646,10 +663,11 @@ Endpoint* Overseer::addEndpoint(std::wstring endpointId, /* out */Flows* flow = this->captureDevices.push_back(endpoint); } if (flow != nullptr) *flow = getFlow; + CoUninitialize(); return endpoint; } -Overseer::Overseer() : epsc(this){ +Overseer::Overseer() : epsc(this) { log_debugcpp("Initializing Overseer"); //Storing exe path for later use (mainly "Run on startup") @@ -669,20 +687,19 @@ Overseer::Overseer() : epsc(this){ log_debugcpp("-Initializing COM"); initCOMLibrary(); - //Obtaining playback endpoint collection on this point in time - reloadEndpoints(Flows::FLOW_PLAYBACK); + //Obtaining playback endpoint collection + createEndpoints(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......"); } } NGuid Overseer::getGuid() { return guid; } +void Overseer::registerEndpointSituationCallback() { + if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); } +} + std::vector Overseer::getPlaybackEndpoints() { return playbackDevices; } @@ -692,19 +709,22 @@ std::vector Overseer::getCaptureEndpoints() { } void Overseer::updateEndpointInfo(std::wstring endpointId) { - log_wdebugcpp(L"new name Endpoint id: " + endpointId); //todo: reintroduce capture devices + playbackMutex.lock(); + log_wdebugcpp(L"new name Endpoint id: " + endpointId); for(auto ep : playbackDevices) { - if (ep->getId() == endpointId) { + if (ep->getId() == endpointId && ep->getState() == EndpointState::ENDPOINT_ACTIVE) { ep->updateName(); osh->updateFrontEndpointName(ep); break; } } + playbackMutex.unlock(); } Overseer::~Overseer(){ - log_debugcpp("cum"); + //Overseer is never deleted. This is to annotate what would need to be taken care of. + log_debugcpp("jej"); deviceEnumerator->Release(); for(unsigned long long i = 0; i < playbackDevices.size(); i++){ delete(playbackDevices.at(i)); @@ -885,7 +905,6 @@ bool Environment::checkStartup(HKEY rootKeyFlags) { } void Environment::updateStartupConfig(bool onStartup) { - DWORD typeReturned; wchar_t regSubKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"; if(!onStartup) { diff --git a/src/back/backlasses.h b/src/back/backlasses.h index 511774b..5876b4b 100644 --- a/src/back/backlasses.h +++ b/src/back/backlasses.h @@ -58,8 +58,8 @@ class Endpoint { float getVolume(int channel); void setMute(NGuid guid, bool muted); bool getMute(); - void setState(uint8_t state); - size_t getState(); + void setState(EndpointState state); + EndpointState getState(); Roles getRoles(); void setRoles(Roles role); void assignRoles(Roles role); @@ -101,7 +101,7 @@ class Endpoint { std::wstring descriptionName; std::wstring deviceName; std::wstring endpointId; - unsigned long endpointState; + EndpointState endpointState; Roles endpointRoles = (Roles)0; uint64_t idx; //Not implemented in llvm-mingw. Sad! todo: mingw patch @@ -118,6 +118,7 @@ class EndpointVolumeCallback : public IAudioEndpointVolumeCallback { ULONG Release(); HRESULT QueryInterface(REFIID riid, VOID **ppvInterface); HRESULT OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA update); + void updateVolumeInfo(AUDIO_VOLUME_NOTIFICATION_DATA newVolume, float* channelVolumes); //~EndpointVolumeCallback(); private: @@ -146,15 +147,18 @@ class Overseer { public: Overseer(); + void registerEndpointSituationCallback(); NGuid getGuid(); std::vector getPlaybackEndpoints(); std::vector getCaptureEndpoints(); void updateEndpointInfo(std::wstring endpointId); - void reloadEndpoints(Flows flow); + void createEndpoints(Flows flow); Endpoint* addEndpoint(std::wstring endpointId, /* out */ Flows* flow); + std::mutex playbackMutex; + std::mutex captureMutex; //void setEndpointStatusCallback(); //void setEndpointStatusCallback(); @@ -166,8 +170,6 @@ class Overseer { ~Overseer(); private: - std::wstring exeAbsPath; - void initCOMLibrary(); NGuid guid; @@ -177,7 +179,6 @@ class Overseer { std::vector playbackDevices; std::vector captureDevices; - IPolicyConfig7* policyConfig; friend class Endpoint; //IMMDeviceCollection *deviceCollection; @@ -222,7 +223,9 @@ namespace Environment { bool isToRunAtStartup(); uint32_t getAccentColor(); + //todo: binary path cache unused static std::wstring exeAbsPath; + static uint32_t exeAbsPathLen; static bool lightMode; static bool startup = false; static HKEY scope; diff --git a/src/back/backsessionclasses.cpp b/src/back/backsessionclasses.cpp index f98369f..5816ac5 100644 --- a/src/back/backsessionclasses.cpp +++ b/src/back/backsessionclasses.cpp @@ -93,8 +93,10 @@ HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) { } HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) { - sh->setState(SessionState::DISCONNECTED); - sh->reviseSessionShowing(SessionState::DISCONNECTED); + if (DisconnectReason != DisconnectReasonDeviceRemoval) { + sh->setState(SessionState::DISCONNECTED); + sh->reviseSessionShowing(SessionState::DISCONNECTED); + } return S_OK; } diff --git a/src/cont/contclasses.cpp b/src/cont/contclasses.cpp index ad85647..54a349c 100644 --- a/src/cont/contclasses.cpp +++ b/src/cont/contclasses.cpp @@ -24,7 +24,6 @@ void setConfigDirToDefaults() { } EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) { - //std::vector endpoints = osh->getPlaybackEndpoints().at(idx); this->idx = idx; this->flow = flow; this->ep = (flow == Flows::FLOW_PLAYBACK ? osh->getPlaybackEndpoints().at(idx) : osh->getCaptureEndpoints().at(idx)); @@ -62,16 +61,6 @@ Flows EndpointHandler::getFlow(){ return ep->getFlow(); } -/* these two, currently unused. If I use them, I should feel bad. - * Endpoint* EndpointHandler::getEndpoint() { - * return this->ep; - * } - * - * EndpointVolumeCallback* EndpointHandler::getEndpointVolumeCallback() { - * return this->epc; - * } - */ - BackEndpointVolumeCallbackInfo* EndpointHandler::getCallbackInfo(){ return &this->callbackInfo; } @@ -134,12 +123,12 @@ void EndpointHandler::setBackEndpointVolumeCallbackInfoContent(uint8_t state) { } } -void EndpointHandler::setState(uint8_t state){ +void EndpointHandler::setState(EndpointState state){ ep->setState(state); this->setBackEndpointVolumeCallbackInfoContent(state); } -void EndpointHandler::setState(uint8_t state, uint64_t index){ +void EndpointHandler::setState(EndpointState state, uint64_t index){ ep->setState(state); this->setFrontVisibilityInfo((EndpointState)state, index); this->setBackEndpointVolumeCallbackInfoContent(state); @@ -318,7 +307,7 @@ uint64_t OverseerHandler::getCaptureEndpointsCount(){ return this->os->getCaptureEndpoints().size(); } -void OverseerHandler::reloadEndpointHandlers(){ +void OverseerHandler::createEndpointHandlers(){ //todo: add capture //std::vector* ephs = new std::vector; @@ -326,9 +315,7 @@ void OverseerHandler::reloadEndpointHandlers(){ for(uint64_t i = 0; i < this->getPlaybackEndpointsCount(); i++){ log_debugcpp("Creating Playback handler " + std::to_string(i)); - - EndpointHandler* ephexx = new EndpointHandler(i, Flows::FLOW_PLAYBACK); - //this->playbackEndpointHandlers.push_back(ephexx); + new EndpointHandler(i, Flows::FLOW_PLAYBACK); log_debugcpp("Created Playback handler " + std::to_string(i) + ", adding to vector. " + " VSize: " + std::to_string(this->playbackEndpointHandlers.size())); } @@ -336,37 +323,27 @@ void OverseerHandler::reloadEndpointHandlers(){ log_debugcpp("Capture VSize: " + std::to_string(this->getCaptureEndpointsCount())); - for(uint64_t i = 0; i < this->getCaptureEndpointsCount(); i++){ + for(uint64_t i = 0; i < this->getCaptureEndpointsCount(); i++) { log_debugcpp("Creating Capture handler " + std::to_string(i)); - - /* - * if(i < (this->captureEndpointHandlers.size()) && - * this->captureEndpointHandlers.at(i) != nullptr) - * delete captureEndpointHandlers.at(i); - */ - - EndpointHandler* ephoo = new EndpointHandler(i, Flows::FLOW_CAPTURE); - //this->captureEndpointHandlers.push_back(ephoo); + new EndpointHandler(i, Flows::FLOW_CAPTURE); log_debugcpp("Created Capture handler " + std::to_string(i) + ", adding to vector. " + " VSize: " + std::to_string(this->captureEndpointHandlers.size())); - /* * if (i >= this->captureEndpointHandlers.size()) * captureEndpointHandlers.push_back(eph); * else captureEndpointHandlers.at(i) = eph; */ } - //setEndpointHandlers(ephs); + os->registerEndpointSituationCallback(); } -EndpointHandler* OverseerHandler::addEndpoint(std::wstring endpointId, /* out */ Flows *flow = nullptr){ +EndpointHandler* OverseerHandler::addEndpoint(std::wstring endpointId, /* out */ Flows *flow = nullptr) { + //This method is only called from the new endpoint callback and its subsequent thread Flows localFlow; Endpoint* newEp = this->os->addEndpoint(endpointId, &localFlow); uint64_t ephIdx = (localFlow == Flows::FLOW_PLAYBACK ? this->getPlaybackEndpointsCount() : this->getCaptureEndpointsCount()) - 1; EndpointHandler* newEph = new EndpointHandler(ephIdx, localFlow); - // std::vector getPlaybackEndpointHandlers(); - //std::vector getCaptureEndpointHandlers(); if (flow != nullptr) *flow = localFlow; return newEph; } @@ -403,6 +380,10 @@ void OverseerHandler::updateFrontEndpointName(Endpoint* ep) { void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointState state) { //TODO: Race condition!!!!! std::vector allHandlers; + handlersPlaybackMutex.lock(); + handlersCaptureMutex.lock(); + os->playbackMutex.lock(); + os->captureMutex.lock(); allHandlers.insert(allHandlers.end(), this->captureEndpointHandlers.begin(), this->captureEndpointHandlers.end()); allHandlers.insert(allHandlers.end(), this->playbackEndpointHandlers.begin(), this->playbackEndpointHandlers.end()); EndpointHandler* eph = nullptr; @@ -425,11 +406,15 @@ void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointSta //todo: mic done but disabled. Tab-kun will come... if (flow == Flows::FLOW_CAPTURE) return; - if(eph && EndpointState::ENDPOINT_ACTIVE & state) { + if (eph && EndpointState::ENDPOINT_ACTIVE & state) { this->addEndpointWidget(eph); - } else if (eph && eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE){ + } else if (eph && eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE) { this->removeEndpointWidget(eph->getFrontVisibilityIndex()); } + handlersPlaybackMutex.unlock(); + handlersCaptureMutex.unlock(); + os->playbackMutex.unlock(); + os->captureMutex.unlock(); return; } diff --git a/src/cont/contclasses.h b/src/cont/contclasses.h index 9d43088..91d225b 100644 --- a/src/cont/contclasses.h +++ b/src/cont/contclasses.h @@ -58,8 +58,8 @@ public: void setVolume(NGuid guid, int channel, int value); void setMute(NGuid guid, bool muted); - void setState(uint8_t state); - void setState(uint8_t state, uint64_t idx); + void setState(EndpointState state); + void setState(EndpointState state, uint64_t idx); float getPeakVolume(); /* sessions */ @@ -137,10 +137,12 @@ public: void pushBackEndpointHandler(EndpointHandler* eph, Flows flow); uint64_t getPlaybackEndpointsCount(); uint64_t getCaptureEndpointsCount(); - void reloadEndpointHandlers(); + void createEndpointHandlers(); EndpointHandler* addEndpoint(std::wstring endpointId, Flows *flow); NGuid getGuid(); + std::mutex handlersPlaybackMutex; + std::mutex handlersCaptureMutex; /* * void setSessionVolumeCallback(std::function changeSessionVolume); * void setSessionVolume(float newValue, ); @@ -150,6 +152,7 @@ private: Overseer *os; std::vector playbackEndpointHandlers; std::vector captureEndpointHandlers; + std::function changeFrontDefaults; std::function removeEndpointWidget; std::function addEndpointWidget; diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 07adb81..667ce99 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -1088,7 +1088,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { mainMenuBar->addWidget(hw); mainMenuBar->setMovable(false); this->addToolBar(Qt::BottomToolBarArea, mainMenuBar); - + + /* + * Create initial endpoint widgets batch + */ reloadEndpointWidgets(); /* @@ -1319,7 +1322,8 @@ void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) { void MainWindow::reloadEndpointWidgets() { size_t i = 0; ews.resize(2); - //todo: -log flag + + osh->handlersPlaybackMutex.lock(); for (size_t epwIndex = 2; i < (osh->getPlaybackEndpointHandlers().size()); i++) { if (osh->getPlaybackEndpointHandlers().at(i)->getState() == EndpointState::ENDPOINT_ACTIVE){ log_debugcpp("EPWidget creation"); @@ -1336,6 +1340,7 @@ void MainWindow::reloadEndpointWidgets() { { ews.push_back(epw); epw->setIndex(ews.size() - 1); } } } + osh->handlersPlaybackMutex.unlock(); //todo: ya no está aquí tirao como tal, y de hecho, no ha fallado de la manera arriba descrita //pero ahora lo añado porque sí solo para garantizar que está y poder reusarlo luego lmao widgetLayout->addItem(lastRowSpacer, i, 0); diff --git a/src/qtestmain.cpp b/src/qtestmain.cpp index b036c72..d264d01 100644 --- a/src/qtestmain.cpp +++ b/src/qtestmain.cpp @@ -121,7 +121,7 @@ int main (int argc, char* argv[]) { //INIT CONT log_debugcpp("main init"); - osh->reloadEndpointHandlers(); + osh->createEndpointHandlers(); log_debugcpp("Reloaded endpoint handlers"); //INIT FRONT