#include EndpointCallback::EndpointCallback(Endpoint* ep){ this->ep = ep; } ULONG EndpointCallback::AddRef(){ return InterlockedIncrement(&ref); } ULONG EndpointCallback::Release(){ ULONG tempRef = InterlockedDecrement(&ref); if (tempRef == 0) { delete this; } return tempRef; } HRESULT EndpointCallback::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 EndpointCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) { if (pNotify == NULL) return E_INVALIDARG; /* * AUDIO_VOLUME_NOTIFICATION_DATA eventData = *pNotify; * LPGUID guid = osh->getOverseer()->getGuid(); * * if (eventData.guidEventContext != *guid) { * osh->parseExternalEndpointCallback(this, eventData); * } */ return S_OK; } /* EndpointCallback::~EndpointCallback(){ * PAUDIO_VOLUME_NOTIFICATION_DATA->Release(); * } */ Endpoint::Endpoint(IMMDevice* ep){ this->endpoint = ep; if(FAILED(endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&endpointVolume))) { log_debugcpp("si"); }; //Obtaining friendly name: IPropertyStore creates PROPVARIANT per field // hr = endpointPtr->GetId(&endpointID); endpoint->OpenPropertyStore(STGM_READ, &properties); PROPVARIANT pv; properties->GetValue(PKEY_Device_FriendlyName , &pv); friendlyName = std::wstring(pv.pwszVal); } void Endpoint::setIndex(uint64_t idx){ this->idx = idx; } uint64_t Endpoint::getIndex(){ return idx; } std::wstring Endpoint::getName(){ return friendlyName; } float Endpoint::getVolume(int channel){ float volume; if (channel == ENDPOINT_MASTER_VOLUME) { if(FAILED(endpointVolume->GetMasterVolumeLevelScalar(&volume))) { log_debugcpp("si");} } else { if(FAILED(endpointVolume->GetChannelVolumeLevelScalar(channel, &volume))) { log_debugcpp("si");} } return volume; } bool Endpoint::getMute(){ BOOL mut; if(FAILED(endpointVolume->GetMute(&mut))) { log_debugcpp("si"); } log_debugcpp("back BOOL is " << mut); bool mute = (bool)mut; log_debugcpp("translate to bool " << mute); return mute; } /* * float Endpoint::getLeftChannelVolume(){ * float volume; * if(FAILED(endpointVolume-> GetChannelVolumeLevelScalar(0, &volume)) { log_debugcpp("si"); } ); * return volume; * } * * float Endpoint::getRightChannelVolume(){ * float volume; * if(FAILED(endpointVolume-> GetChannelVolumeLevelScalar(1, &volume)) { log_debugcpp("si");} * return volume; * } */ void Endpoint::setVolume(int channel, float volume) { if (channel == ENDPOINT_MASTER_VOLUME) { if(FAILED(endpointVolume->SetMasterVolumeLevelScalar(volume, NULL))) { log_debugcpp("si"); }; } else { if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, NULL))) { log_debugcpp("si"); }; } } void Endpoint::setMute() { BOOL mut; //log_debugcpp("bool mute arrives as " << mut); if(FAILED(endpointVolume->GetMute(&mut))) { log_debugcpp("si"); } log_debugcpp("translate to BOOL as " << mut); if(FAILED(endpointVolume->SetMute((mut == false ? 1 : 0), NULL))) { log_debugcpp("si"); }; } void Endpoint::setCallback(EndpointCallback *epc){ endpointVolume->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)epc); } void Endpoint::removeCallback(EndpointCallback *epc){ endpointVolume->UnregisterControlChangeNotify((IAudioEndpointVolumeCallback*)epc); } Endpoint::~Endpoint(){ log_debugcpp("cum"); properties->Release(); endpointVolume->Release(); endpoint->Release(); } void Overseer::initCOMLibrary(){ 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; /* * HRESULT her = CoCreateGuid(&tempGuid); * std::bitset<32> bon(her); * //if (hr == EPT_S_CANT_CREATE) * log_debugcpp("Failed to obtain GUID: " /\*<< std::hex *\/<< her << std::dec << " " << bon); */ if(FAILED(CoCreateGuid(&tempGuid))) { log_debugcpp("Failed to obtain GUID: " ); }; this->guid.data1 = tempGuid.Data1; this->guid.data2 = tempGuid.Data2; this->guid.data3 = tempGuid.Data3; for (int i = 0; i < 8; i++){ this->guid.data4[i] = tempGuid.Data4[i]; log_debugcpp("GUID DATA4 BYTE " << i << ": "); log_debugcpp(print_as_binary(8, uint32_t, this->guid.data4[i])); } log_debugcpp("GUID DATA1: " << this->guid.data1); log_debugcpp("GUID DATA2: " << this->guid.data2); log_debugcpp("GUID DATA3: " << this->guid.data3); //TODO: Release lpguid? } void Overseer::reloadEndpoints() { IMMDeviceCollection *deviceCollection; // | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED if(FAILED(deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &deviceCollection) )) { log_debugcpp("si"); }; //Counting them if(FAILED(deviceCollection->GetCount(&numPlaybackEndpoints))) { log_debugcpp("si");}; if(numPlaybackEndpoints == 0) { log_debugcpp("si"); }; //Retrieving actual endpoints and storing them on their own class for (unsigned int i = 0; i < numPlaybackEndpoints; i++){ IMMDevice *temp; if(deviceCollection->Item(i, &temp) != 0) { log_debugcpp("si"); }; Endpoint *endpoint = new Endpoint(temp); endpoint->setIndex(i); this->playbackDevices.push_back(endpoint); //TODO: le porblemx std::cout << "ola" << std::endl; } deviceCollection->Release(); } Overseer::Overseer(){ //Initializing COM library log_debugcpp("Initializing Overseer"); initCOMLibrary(); //Obtaining playback endpoint collection on this point in time reloadEndpoints(); } //Overseer::int getDefaultPlaybackEndpoint(Endpoint** defaultEndpoint){ //if (FAILED(deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &endpointPtr))) // return 1; //return 0; //} //int Overseer::getDefaultCaptureEndpoint(Endpoint** defaultEndpoint); //TODO guid NGuid Overseer::getGuid() { return guid; } std::vector Overseer::getPlaybackEndpoints() { return playbackDevices; } 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 *captureEndpoints); //IMMDeviceEnumerator** Overseer::setOrigin();