258 lines
7.4 KiB
C++
258 lines
7.4 KiB
C++
#include <backlasses.h>
|
|
#include <backfuncs.h>
|
|
|
|
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;
|
|
|
|
float extraChannelVol[pNotify->nChannels];
|
|
bool multiChannel = false;
|
|
AUDIO_VOLUME_NOTIFICATION_DATA eventData = *pNotify;
|
|
if(pNotify->nChannels > 1) {
|
|
multiChannel = true;
|
|
for (UINT i = 0; i < pNotify->nChannels; i++){
|
|
extraChannelVol[i] = pNotify->afChannelVolumes[i];
|
|
}
|
|
}
|
|
NGuid* guid = osh->getGuid();
|
|
|
|
if (memcmp(guid, &eventData, sizeof(*guid)) == 0) {
|
|
log_debugcpp("Onnanokotify says You Shall Not Update Thy Interface.");
|
|
} else {
|
|
log_debugcpp("Onnanokotify says Stored: " << guid->data1);
|
|
log_debugcpp("Onnanokotify says Grace of God: " << eventData.guidEventContext.Data1);
|
|
osh->updateMuteCallback(this->ep->getIndex(), eventData.bMuted);
|
|
osh->updateVolumeCallback(this->ep->getIndex(), AudioChannel::CHANNEL_MAIN ,eventData.fMasterVolume);
|
|
log_debugcpp("Onnanokotify says Reported Channel Qty: " << eventData.nChannels);
|
|
|
|
if(multiChannel)
|
|
for(UINT i = 0; i < eventData.nChannels; i++) {
|
|
osh->updateVolumeCallback(this->ep->getIndex(), (uint32_t)i, extraChannelVol[i]);
|
|
}
|
|
else
|
|
osh->updateVolumeCallback(this->ep->getIndex(), (uint32_t)0, pNotify->afChannelVolumes[0]);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/* EndpointCallback::~EndpointCallback(){
|
|
* PAUDIO_VOLUME_NOTIFICATION_DATA->Release();
|
|
* } */
|
|
|
|
Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
|
this->endpoint = ep;
|
|
this->idx = idx;
|
|
if(FAILED(endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&endpointVolume))) { log_debugcpp("si"); };
|
|
if (FAILED(endpointVolume->GetChannelCount(&channelCount))) log_debugcpp("get channel count fail");
|
|
//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;
|
|
}
|
|
|
|
uint32_t Endpoint::getChannelCount(){
|
|
return (uint32_t)channelCount;
|
|
}
|
|
|
|
|
|
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(NGuid* guid, int channel, float volume) {
|
|
GUID tempMsGuid = NGuidToGUID(guid);
|
|
if (channel == AudioChannel::CHANNEL_MAIN) {
|
|
if(FAILED(endpointVolume->SetMasterVolumeLevelScalar(volume, &tempMsGuid))) { log_debugcpp("MASTER VOLUME FAILED"); };
|
|
} else {
|
|
log_debugcpp("Windows: Channel being updated: " << channel);
|
|
if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) { log_debugcpp("CHANNEL "<< channel <<" VOLUME FAILED"); };
|
|
}
|
|
}
|
|
|
|
void Endpoint::setMute(NGuid* guid, bool muted) {
|
|
//BOOL mut;
|
|
//log_debugcpp("bool mute arrives as " << mut);
|
|
//if(FAILED(endpointVolume->GetMute(&mut))) { log_debugcpp("si"); }
|
|
//log_debugcpp("translate to BOOL as " << mut);
|
|
//TODO: use new funcs
|
|
GUID tempMsGuid = NGuidToGUID(guid);
|
|
if(FAILED(endpointVolume->SetMute(muted, &tempMsGuid))) { log_debugcpp("MUTE FAILED"); };
|
|
}
|
|
|
|
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;
|
|
if(FAILED(CoCreateGuid(&tempGuid))) { log_debugcpp("Failed to obtain GUID: " ); };
|
|
this->guid = GUIDToNGuid(&tempGuid);
|
|
//TODO: Release lpguid?
|
|
//TODO: Uninitialize COM
|
|
}
|
|
|
|
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, i);
|
|
//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<Endpoint*> 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<Endpoint*> *captureEndpoints);
|
|
|
|
//IMMDeviceEnumerator** Overseer::setOrigin();
|
|
|