almost captured, only to hotplug. such is life...
This commit is contained in:
parent
f92df42995
commit
44ccde6ac8
6 changed files with 235 additions and 63 deletions
|
|
@ -39,30 +39,30 @@ HRESULT EndpointVolumeCallback::QueryInterface(REFIID riid, VOID **ppvInterface)
|
|||
HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) {
|
||||
if (pNotify == NULL) return E_INVALIDARG;
|
||||
|
||||
//delete osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller;
|
||||
//osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.freeData4();
|
||||
//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->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data1 \
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data1 \
|
||||
= pNotify->guidEventContext.Data1;
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data2 \
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data2 \
|
||||
= pNotify->guidEventContext.Data2;
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data3 \
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data3 \
|
||||
= pNotify->guidEventContext.Data3;
|
||||
for(int i = 0; i < 8 /* Data4 size */; i++){
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data4[i] = pNotify->guidEventContext.Data4[i];
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller.data4[i] = pNotify->guidEventContext.Data4[i];
|
||||
}
|
||||
|
||||
//memcpy(&osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller, &pNotify->guidEventContext,sizeof(NGuid) );
|
||||
//memcpy(&osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->caller, &pNotify->guidEventContext,sizeof(NGuid) );
|
||||
|
||||
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->muted = pNotify->bMuted;
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->mainVolume = pNotify->fMasterVolume;
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->channels = pNotify->nChannels;
|
||||
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;
|
||||
|
||||
UINT j = 0;
|
||||
//todo: do while here caused stack corruption; sus
|
||||
while(j < pNotify->nChannels) {
|
||||
osh->getEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->channelVolumes[j] = pNotify->afChannelVolumes[j];
|
||||
osh->getPlaybackEndpointHandlers().at(this->ep->getIndex())->getCallbackInfo()->channelVolumes[j] = pNotify->afChannelVolumes[j];
|
||||
j++;
|
||||
}
|
||||
return S_OK;
|
||||
|
|
@ -76,9 +76,10 @@ HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify
|
|||
*
|
||||
*/
|
||||
//todo: not on construct since it expects them to already exist; smells like refactor!
|
||||
void EndpointSituationCallback::fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices){
|
||||
void EndpointSituationCallback::fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices, std::vector<Endpoint*> captureDevices){
|
||||
this->deviceEnumerator = deviceEnumerator;
|
||||
this->playbackDevices = playbackDevices;
|
||||
this->captureDevices = captureDevices;
|
||||
}
|
||||
|
||||
ULONG EndpointSituationCallback::AddRef(){
|
||||
|
|
@ -151,10 +152,14 @@ HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, D
|
|||
osh->reviseEndpointShowing(endpointId, EndpointState::ENDPOINT_ACTIVE);
|
||||
break;
|
||||
case DEVICE_STATE_DISABLED:
|
||||
case DEVICE_STATE_NOTPRESENT:
|
||||
case DEVICE_STATE_UNPLUGGED:
|
||||
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;
|
||||
|
|
@ -189,6 +194,11 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|||
activateEndpointVolume();
|
||||
|
||||
reloadEndpointChannels();
|
||||
|
||||
/*
|
||||
* if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
|
||||
* CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); }
|
||||
*/
|
||||
|
||||
//todo:: atexit into exit Gather ID
|
||||
LPWSTR tempString = nullptr;
|
||||
|
|
@ -206,6 +216,11 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|||
friendlyName = std::wstring(pv.pwszVal);
|
||||
}
|
||||
|
||||
/*
|
||||
* Endpoint::Endpoint(IMMDevice* endpoint) : Endpoint(endpoint, 0) {};
|
||||
*/
|
||||
|
||||
|
||||
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)")); };
|
||||
|
|
@ -372,6 +387,33 @@ void Endpoint::removeRoles(Roles 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 copied it. Sad.
|
||||
GUID manual;
|
||||
manual.Data1 = 0x1be09788;
|
||||
manual.Data2 = 0x6894;
|
||||
manual.Data3 = 0x4089;
|
||||
manual.Data4[0] = 0x85;
|
||||
manual.Data4[1] = 0x86;
|
||||
manual.Data4[2] = 0x9a;
|
||||
manual.Data4[3] = 0x2a;
|
||||
manual.Data4[4] = 0x6c;
|
||||
manual.Data4[5] = 0x26;
|
||||
manual.Data4[6] = 0x5a;
|
||||
manual.Data4[7] = 0xc5;
|
||||
if(FAILED(this->endpoint->QueryInterface((const _GUID)manual, (void**)&flowGetter)))
|
||||
{ log_debugcpp("no flow..."); }
|
||||
EDataFlow MSflow;
|
||||
HRESULT vafllar = flowGetter->GetDataFlow(&MSflow);
|
||||
this->flow = (MSflow == EDataFlow::eRender ? Flows::FLOW_PLAYBACK : Flows::FLOW_CAPTURE);
|
||||
flowGetter->Release();
|
||||
}
|
||||
|
||||
Flows Endpoint::getFlow() {
|
||||
return this->flow;
|
||||
}
|
||||
|
||||
Endpoint::~Endpoint(){
|
||||
log_debugcpp("murio endpoint-san uwu");
|
||||
properties->Release();
|
||||
|
|
@ -394,6 +436,7 @@ void Overseer::initCOMLibrary() {
|
|||
|
||||
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);
|
||||
|
||||
//if(FAILED(CoCreateInstance(__uuidof(CPolicyConfigClient),
|
||||
|
|
@ -403,28 +446,34 @@ void Overseer::initCOMLibrary() {
|
|||
//TODO: Uninitialize COM
|
||||
}
|
||||
|
||||
void Overseer::reloadEndpoints() {
|
||||
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(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED, &deviceCollection) ))
|
||||
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(&numPlaybackEndpoints))) { log_debugcpp("si");};
|
||||
if(numPlaybackEndpoints == 0) { log_debugcpp("si"); };
|
||||
if(FAILED(deviceCollection->GetCount(&numEndpoints))) { log_debugcpp("si");};
|
||||
if(numEndpoints == 0) { log_debugcpp("si"); };
|
||||
|
||||
/*
|
||||
* Retrieving actual endpoints and storing them on their own class
|
||||
*/
|
||||
IMMDevice *temp;
|
||||
for (unsigned int i = 0; i < numPlaybackEndpoints; i++){
|
||||
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);
|
||||
this->playbackDevices.push_back(endpoint);
|
||||
if (flow == Flows::FLOW_PLAYBACK)
|
||||
this->playbackDevices.push_back(endpoint);
|
||||
else
|
||||
this->captureDevices.push_back(endpoint);
|
||||
//TODO: le porblemx std::cout + "ola" + std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -447,30 +496,65 @@ void Overseer::reloadEndpoints() {
|
|||
val = eCommunications;
|
||||
break;
|
||||
}
|
||||
deviceEnumerator->GetDefaultAudioEndpoint(EDataFlow::eRender, val, &temp);
|
||||
deviceEnumerator->GetDefaultAudioEndpoint(MSflow, val, &temp);
|
||||
LPWSTR id = nullptr;
|
||||
|
||||
for (unsigned int j = 0; j < numPlaybackEndpoints; 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 de " + std::to_wstring(i) + L" es " + id);
|
||||
playbackDevices.at(j)->assignRoles((Roles)(1 << i));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
//uint8_t debg = playbackDevices.at(j)->getRoles();
|
||||
}
|
||||
} 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(deviceEnumerator, playbackDevices){
|
||||
//Initializing COM library
|
||||
log_debugcpp("Initializing Overseer");
|
||||
initCOMLibrary();
|
||||
|
||||
//Obtaining playback endpoint collection on this point in time
|
||||
reloadEndpoints();
|
||||
this->epsc.fill(deviceEnumerator, playbackDevices);
|
||||
reloadEndpoints(Flows::FLOW_PLAYBACK);
|
||||
//reloadEndpoints(Flows::FLOW_CAPTURE);
|
||||
|
||||
//Registering for endpoint information callback
|
||||
this->epsc.fill(deviceEnumerator, playbackDevices, captureDevices);
|
||||
if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); }
|
||||
}
|
||||
|
||||
|
|
@ -482,6 +566,10 @@ std::vector<Endpoint*> Overseer::getPlaybackEndpoints() {
|
|||
return playbackDevices;
|
||||
}
|
||||
|
||||
std::vector<Endpoint*> Overseer::getCaptureEndpoints() {
|
||||
return captureDevices;
|
||||
}
|
||||
|
||||
Overseer::~Overseer(){
|
||||
log_debugcpp("cum");
|
||||
deviceEnumerator->Release();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue