mic back/cont & plug/unplug done; devicead/rem to go
This commit is contained in:
parent
44ccde6ac8
commit
6f8455c63d
5 changed files with 129 additions and 46 deletions
|
|
@ -53,18 +53,28 @@ HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify
|
|||
}
|
||||
|
||||
//memcpy(&osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller, &pNotify->guidEventContext,sizeof(NGuid) );
|
||||
|
||||
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->muted = pNotify->bMuted;
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->mainVolume = pNotify->fMasterVolume;
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->channels = pNotify->nChannels;
|
||||
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) {
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->channelVolumes[j] = pNotify->afChannelVolumes[j];
|
||||
j++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +201,9 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|||
//todo: preguntitas owindows dword no es uint32_t even tho mingw mingas
|
||||
if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-1);};
|
||||
|
||||
activateEndpointVolume();
|
||||
if(this->endpointState == EndpointState::ENDPOINT_ACTIVE) {
|
||||
activateEndpointVolume();
|
||||
}
|
||||
|
||||
reloadEndpointChannels();
|
||||
|
||||
|
|
@ -214,6 +226,8 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|||
friendlyName = L"Unnamed Not Present Endpoint";
|
||||
else
|
||||
friendlyName = std::wstring(pv.pwszVal);
|
||||
|
||||
this->setFlow();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -222,13 +236,27 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|||
|
||||
|
||||
void Endpoint::activateEndpointVolume() {
|
||||
if (this->endpointVolume == nullptr)
|
||||
if(FAILED(endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&this->endpointVolume))) { log_debugcpp(std::string("no endpointVolume (IAudioEndpointVolume)")); };
|
||||
//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);
|
||||
//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"); */
|
||||
if (FAILED(endpointVolume->GetChannelCount(&channelCount))) {log_debugcpp("get channel count fail");};/* */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,8 +300,10 @@ bool Endpoint::getMute(){
|
|||
|
||||
void Endpoint::setState(uint8_t state){
|
||||
this->endpointState = state;
|
||||
if(state == EndpointState::ENDPOINT_ACTIVE)
|
||||
if(state == EndpointState::ENDPOINT_ACTIVE) {
|
||||
this->activateEndpointVolume();
|
||||
this->reloadEndpointChannels();
|
||||
}
|
||||
}
|
||||
|
||||
size_t Endpoint::getState(){
|
||||
|
|
@ -468,7 +498,7 @@ void Overseer::reloadEndpoints(Flows flow) {
|
|||
for (unsigned int i = 0; i < numEndpoints; i++){
|
||||
if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); };
|
||||
Endpoint *endpoint = new Endpoint(temp, i);
|
||||
endpoint->setFlow();
|
||||
|
||||
//endpoint->setIndex(i);
|
||||
if (flow == Flows::FLOW_PLAYBACK)
|
||||
this->playbackDevices.push_back(endpoint);
|
||||
|
|
|
|||
|
|
@ -14,15 +14,14 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
|
|||
//epName = ep->getName();
|
||||
this->setBackEndpointVolumeCallbackInfoContent(this->getState());
|
||||
osh->pushBackEndpointHandler(this, flow);
|
||||
|
||||
}
|
||||
|
||||
void OverseerHandler::pushBackEndpointHandler(EndpointHandler* eph, Flows flow) {
|
||||
if (eph == nullptr) return;
|
||||
if (flow = Flows::FLOW_PLAYBACK)
|
||||
playbackEndpointHandlers.push_back(eph);
|
||||
if (flow == Flows::FLOW_PLAYBACK)
|
||||
this->playbackEndpointHandlers.push_back(eph);
|
||||
else
|
||||
captureEndpointHandlers.push_back(eph);
|
||||
this->captureEndpointHandlers.push_back(eph);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +38,10 @@ EndpointState EndpointHandler::getFrontVisibilityState(){
|
|||
return ephfv.visibility;
|
||||
}
|
||||
|
||||
Flows EndpointHandler::getFlow(){
|
||||
return ep->getFlow();
|
||||
}
|
||||
|
||||
/* these two, currently unused. If I use them, I should feel bad.
|
||||
* Endpoint* EndpointHandler::getEndpoint() {
|
||||
* return this->ep;
|
||||
|
|
@ -212,16 +215,16 @@ void OverseerHandler::reloadEndpointHandlers(){
|
|||
//setEndpointHandlers(ephs);
|
||||
}
|
||||
|
||||
EndpointHandler* OverseerHandler::addEndpoint(std::wstring endpointId){
|
||||
Flows flow;
|
||||
Endpoint* newEp = this->os->addEndpoint(endpointId, &flow);
|
||||
EndpointHandler* OverseerHandler::addEndpoint(std::wstring endpointId, /* out */ Flows *flow = nullptr){
|
||||
Flows localFlow;
|
||||
Endpoint* newEp = this->os->addEndpoint(endpointId, &localFlow);
|
||||
|
||||
uint64_t ephIdx = (flow == Flows::FLOW_PLAYBACK ? this->getPlaybackEndpointsCount() : this->getCaptureEndpointsCount());
|
||||
uint64_t ephIdx = (localFlow == Flows::FLOW_PLAYBACK ? this->getPlaybackEndpointsCount() : this->getCaptureEndpointsCount()) - 1;
|
||||
|
||||
EndpointHandler* newEph = new EndpointHandler(ephIdx, flow);
|
||||
EndpointHandler* newEph = new EndpointHandler(ephIdx, localFlow);
|
||||
// std::vector<EndpointHandler*> getPlaybackEndpointHandlers();
|
||||
//std::vector<EndpointHandler*> getCaptureEndpointHandlers();
|
||||
|
||||
if (flow != nullptr) *flow = localFlow;
|
||||
return newEph;
|
||||
}
|
||||
|
||||
|
|
@ -238,24 +241,34 @@ void OverseerHandler::changeFrontDefaultsCallback(Roles role, std::wstring endpo
|
|||
}
|
||||
|
||||
void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointState state) {
|
||||
std::vector<EndpointHandler*> allHandlers;
|
||||
allHandlers.insert(allHandlers.end(), this->captureEndpointHandlers.begin(), this->captureEndpointHandlers.end());
|
||||
allHandlers.insert(allHandlers.end(), this->playbackEndpointHandlers.begin(), this->playbackEndpointHandlers.end());
|
||||
EndpointHandler* eph = nullptr;
|
||||
for (auto loopEph : this->playbackEndpointHandlers) {
|
||||
for (auto loopEph : allHandlers) {
|
||||
if (loopEph->getId() == endpointId) {
|
||||
eph = loopEph;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//debug
|
||||
Flows flow;
|
||||
if (!eph) {
|
||||
|
||||
}
|
||||
if (state ^ EndpointState::ENDPOINT_ACTIVE) return;
|
||||
//return;
|
||||
//flow = Flows::FLOW_CAPTURE;
|
||||
eph = osh->addEndpoint(endpointId, &flow);
|
||||
} else
|
||||
flow = eph->getFlow();
|
||||
|
||||
//todo: testing missing shiez. sowwy
|
||||
//if(!eph) osh->
|
||||
//todo: mic done but disabled. Tab-kun will come...
|
||||
if (flow == Flows::FLOW_CAPTURE) return;
|
||||
|
||||
if(EndpointState::ENDPOINT_ACTIVE & state) {
|
||||
|
||||
if(eph && EndpointState::ENDPOINT_ACTIVE & state) {
|
||||
this->addEndpointWidget(eph);
|
||||
} else if (eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE){
|
||||
} else if (eph && eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE){
|
||||
this->removeEndpointWidget(eph->getFrontVisibilityIndex());
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public:
|
|||
uint64_t getPlaybackEndpointsCount();
|
||||
uint64_t getCaptureEndpointsCount();
|
||||
void reloadEndpointHandlers();
|
||||
EndpointHandler* addEndpoint(std::wstring endpointId);
|
||||
EndpointHandler* addEndpoint(std::wstring endpointId, Flows *flow);
|
||||
NGuid getGuid();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -85,7 +85,8 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
|||
/*
|
||||
* Channel sliders setup
|
||||
*/
|
||||
for(uint32_t i = 0; i < eph->getChannelCount(); i++){
|
||||
uint32_t epChannelCount = eph->getChannelCount();
|
||||
for(uint32_t i = 0; i < epChannelCount && epChannelCount > 1; i++){
|
||||
QSlider* tmp = new QSlider(Qt::Horizontal);
|
||||
QLabel* tmpLb = new QLabel("");
|
||||
tmp->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
|
@ -163,7 +164,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
|||
mainSlider->setValue((int)((eph->getCallbackInfo()->mainVolume + roundingFactor) * 100));
|
||||
muteButton->setCheckState((eph->getCallbackInfo()->muted == false ? Qt::Unchecked : Qt::Checked));
|
||||
muteButton->setText(eph->getCallbackInfo()->muted ? STRING_UNMUTE : STRING_MUTE);
|
||||
for(uint32_t i = 0; i < eph->getCallbackInfo()->channels; i++){
|
||||
for(uint32_t i = 0; i < eph->getCallbackInfo()->channels && eph->getChannelCount() > 1; i++){
|
||||
this->channelSliders.at(i)->blockSignals(true);
|
||||
this->channelSliders.at(i)->setValue((int)((eph->getCallbackInfo()->channelVolumes[i] + roundingFactor) * 100));
|
||||
this->channelLabels.at(i)->setText(QString::number((int)((eph->getCallbackInfo()->channelVolumes[i] + roundingFactor) * 100)));
|
||||
|
|
@ -210,15 +211,20 @@ void MainWindow::removeEndpointWidget(EndpointWidgetEvent<uint64_t>* ev){
|
|||
uint64_t i = ev->payload;
|
||||
this->ews.at(i)->setParent(nullptr);
|
||||
this->layout->removeWidget(ews.at(i));
|
||||
uint64_t saisu = ews.size();
|
||||
//uint64_t saisu = ews.size();
|
||||
//delete ews.at(index);
|
||||
delete ews.at(i);
|
||||
while ((i + 1) < ews.size()) {
|
||||
ews.at(i) = ews.at(i + 1);
|
||||
ews.at(i)->setIndex(i);
|
||||
i++;
|
||||
}
|
||||
ews.pop_back();
|
||||
ews.at(i) = nullptr;
|
||||
this->ewsUpdateTimer->start();
|
||||
|
||||
/*
|
||||
* while ((i + 1) < ews.size()) {
|
||||
* ews.at(i) = ews.at(i + 1);
|
||||
* ews.at(i)->setIndex(i);
|
||||
* i++;
|
||||
* }
|
||||
* ews.pop_back();
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -229,6 +235,34 @@ void MainWindow::addEndpointWidget(EndpointWidgetEvent<EndpointHandler*>* ev){
|
|||
return;
|
||||
}
|
||||
|
||||
void MainWindow::reorderEndpointWidgetCollection() {
|
||||
size_t firstNullPosition = 0;
|
||||
size_t ewsSize = ews.size();
|
||||
bool breakSorting = false;
|
||||
|
||||
//todo: is all of gui really atomic by definition? im afraid of cutting through amazing add momentos, but I think I did my homework. Must check back.
|
||||
for (size_t i = 0; i < ewsSize; i++) {
|
||||
if (ews.at(i) == nullptr) {
|
||||
for (size_t j = (i + 1); j < ewsSize; j++) {
|
||||
|
||||
if (ews.at(j) != nullptr) {
|
||||
ews.at(i) = ews.at(j);
|
||||
ews.at(i)->setIndex(i);
|
||||
ews.at(j) = nullptr;
|
||||
break;
|
||||
}
|
||||
if (j == ewsSize - 1) {
|
||||
firstNullPosition = i;
|
||||
breakSorting = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (breakSorting) break;
|
||||
}
|
||||
}
|
||||
ews.resize(firstNullPosition + 1);
|
||||
}
|
||||
|
||||
void EndpointWidget::updateMute(int checked){
|
||||
bool muted = (checked == 2 ? true : false);
|
||||
this->eph->setMute(osh->getGuid(), muted);
|
||||
|
|
@ -304,13 +338,17 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
|||
QEvent::registerEventType(CustomQEvent::EndpointWidgetObsolete);
|
||||
QEvent::registerEventType(CustomQEvent::EndpointWidgetCreated);
|
||||
QEvent::registerEventType(CustomQEvent::EndpointDefaultChange);
|
||||
|
||||
|
||||
ewsUpdateTimer = new QTimer(this);
|
||||
widget = new QWidget();
|
||||
layout = new QGridLayout();
|
||||
trayIcon = new QSystemTrayIcon();
|
||||
trayIconMenu = new QMenu();
|
||||
trayIconMenuQuit = new QAction(STRING_QUIT);
|
||||
|
||||
ewsUpdateTimer->setSingleShot(true);
|
||||
ewsUpdateTimer->setInterval(ewsUpdateTimerFrequency);
|
||||
connect(ewsUpdateTimer, &QTimer::timeout, this, &MainWindow::reorderEndpointWidgetCollection);
|
||||
widget->setLayout(layout);
|
||||
setCentralWidget(widget);
|
||||
//layout->addWidget(pintas, 0, 0);
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ private slots:
|
|||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void removeEndpointWidget(EndpointWidgetEvent<uint64_t>* ev);
|
||||
void addEndpointWidget(EndpointWidgetEvent<EndpointHandler*>* ev);
|
||||
void reorderEndpointWidgetCollection();
|
||||
//TODO: destroy/empty existing EndpointWidgets
|
||||
//void setEndpointHandlers(std::vector<EndpointHandler*> *ephs);
|
||||
|
||||
|
|
@ -162,7 +163,8 @@ private:
|
|||
QSystemTrayIcon *trayIcon;
|
||||
QMenu *trayIconMenu;
|
||||
QAction *trayIconMenuQuit;
|
||||
|
||||
QTimer *ewsUpdateTimer;
|
||||
static constexpr uint64_t ewsUpdateTimerFrequency = 500;
|
||||
//public slots:
|
||||
// void setEndpointHandlers(std::vector<EndpointHandler*> *ephs);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue