poll merge squash
This commit is contained in:
parent
308a0486b6
commit
40bee90610
21 changed files with 2753 additions and 261 deletions
282
src/back/backsessionclasses.cpp
Normal file
282
src/back/backsessionclasses.cpp
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
#include "backsessionclasses.h"
|
||||
#include "backfuncs.h"
|
||||
|
||||
SessionStateCallback::SessionStateCallback(SessionHandler *sh) {
|
||||
this->sh = sh;
|
||||
}
|
||||
|
||||
ULONG SessionStateCallback::AddRef() {
|
||||
return InterlockedIncrement(&ref);
|
||||
}
|
||||
|
||||
ULONG SessionStateCallback::Release() {
|
||||
ULONG tempRef = InterlockedDecrement(&ref);
|
||||
if (tempRef == 0) {
|
||||
delete this;
|
||||
}
|
||||
return tempRef;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
|
||||
if (IID_IUnknown == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IUnknown*)this;
|
||||
}
|
||||
else if (__uuidof(IAudioSessionNotification) == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IMMNotificationClient*)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvInterface = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContex) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext) {
|
||||
sh->getVolumeInfo()->muted = NewMute;
|
||||
sh->getVolumeInfo()->mainVolume = NewVolume;
|
||||
sh->getVolumeInfo()->caller = GUIDToNGuid((LPGUID)EventContext);
|
||||
/*
|
||||
* if (NewMute)
|
||||
* {
|
||||
* printf("MUTE\n");
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* printf("Volume = %d percent\n",
|
||||
* (UINT32)(100*NewVolume + 0.5));
|
||||
* }
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnChannelVolumeChanged(DWORD ChannelCount, float NewChannelVolumeArray[], DWORD ChangedChannel, LPCGUID EventContext) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnGroupingParamChanged(LPCGUID NewGroupingParam, LPCGUID EventContext) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnStateChanged(AudioSessionState NewState) {
|
||||
SessionState newState;// = sh->getState();
|
||||
switch (NewState) {
|
||||
case AudioSessionStateActive:
|
||||
newState = SessionState::ACTIVE;
|
||||
break;
|
||||
case AudioSessionStateInactive:
|
||||
newState = SessionState::INACTIVE;
|
||||
break;
|
||||
case AudioSessionStateExpired:
|
||||
newState = SessionState::EXPIRED;
|
||||
break;
|
||||
}
|
||||
|
||||
sh->reviseSessionShowing(newState);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SessionStateCallback::OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason) {
|
||||
sh->setState(SessionState::DISCONNECTED);
|
||||
sh->reviseSessionShowing(SessionState::DISCONNECTED);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx) {
|
||||
this->ep = ep;
|
||||
this->sessionControl = sessionControl;
|
||||
this->idx = idx;
|
||||
|
||||
AudioSessionState msState;
|
||||
sessionControl->GetState(&msState);
|
||||
switch (msState) {
|
||||
case AudioSessionState::AudioSessionStateActive:
|
||||
this->sessionState = SessionState::ACTIVE;
|
||||
break;
|
||||
case AudioSessionState::AudioSessionStateInactive:
|
||||
this->sessionState = SessionState::INACTIVE;
|
||||
break;
|
||||
case AudioSessionState::AudioSessionStateExpired:
|
||||
this->sessionState = SessionState::EXPIRED;
|
||||
break;
|
||||
}
|
||||
|
||||
sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume);
|
||||
DWORD pid;
|
||||
sessionControl->GetProcessId(&pid);
|
||||
if (sessionControl->IsSystemSoundsSession() == S_OK)
|
||||
this->sessionName = std::wstring(LSTRING_SYSTEM_SOUNDS);
|
||||
else {
|
||||
LPWSTR sessionDisplayName;
|
||||
this->sessionControl->GetDisplayName(&sessionDisplayName);
|
||||
if (!wcscmp(sessionDisplayName, L""))
|
||||
this->sessionName = this->fetchProcessName(pid);
|
||||
else
|
||||
this->sessionName = std::wstring(sessionDisplayName);
|
||||
CoTaskMemFree(sessionDisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
float Session::getVolume(int channel){
|
||||
float volume;
|
||||
if (channel == AudioChannel::CHANNEL_MAIN) {
|
||||
if(FAILED(sessionVolume->GetMasterVolume(&volume))) { /* log_debugcpp("si") */;}
|
||||
} else {
|
||||
return 0.0;
|
||||
//if(FAILED(endpointVolume->GetChannelVolumeLevelScalar(channel, &volume))) { /* log_debugcpp("si"); */}
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
/*
|
||||
* uint32_t Endpoint::getChannelCount(){
|
||||
* return (uint32_t)channelCount;
|
||||
* }
|
||||
*/
|
||||
|
||||
std::wstring Session::getName() {
|
||||
return sessionName;
|
||||
}
|
||||
|
||||
bool Session::getMute() {
|
||||
BOOL mut;
|
||||
if(FAILED(sessionVolume->GetMute(&mut))) { /* TIP: Below */ }
|
||||
bool mute = (bool)mut;
|
||||
return mute;
|
||||
}
|
||||
|
||||
void Session::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(sessionVolume->SetMasterVolume(volume, &tempMsGuid))) {};
|
||||
} else {
|
||||
//if(FAILED(sessionVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {};
|
||||
}
|
||||
}
|
||||
|
||||
void Session::setIndex(size_t idx) {
|
||||
this->idx = idx;
|
||||
}
|
||||
|
||||
void Session::setMute(NGuid guid, bool muted) {
|
||||
GUID tempMsGuid = NGuidToGUID(guid);
|
||||
if(FAILED(sessionVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"SessionVolume null?")); };
|
||||
}
|
||||
|
||||
std::wstring Session::fetchProcessName(DWORD pid) {
|
||||
/*
|
||||
* https://learn.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
|
||||
* https://stackoverflow.com/questions/11843368/how-to-get-process-description
|
||||
*/
|
||||
|
||||
/* Executable path retrieval */
|
||||
std::wstring exePath = L"";
|
||||
|
||||
HANDLE processList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
|
||||
if (processList == INVALID_HANDLE_VALUE) {
|
||||
log_wdebugcpp(L"aye no procname.");
|
||||
return exePath;
|
||||
}
|
||||
|
||||
MODULEENTRY32W me32w;
|
||||
me32w.dwSize = sizeof(MODULEENTRY32W);
|
||||
if(Module32FirstW(processList, &me32w)) {
|
||||
do {
|
||||
if (me32w.th32ProcessID == pid) {
|
||||
exePath = std::wstring(me32w.szExePath);
|
||||
break;
|
||||
/*
|
||||
* However, if the calling process is a 32-bit process, you must call the
|
||||
* QueryFullProcessImageName function to retrieve the full path of the
|
||||
* executable file for a 64-bit process.
|
||||
*/
|
||||
}
|
||||
} while(Module32NextW(processList, &me32w));
|
||||
}
|
||||
CloseHandle(processList);
|
||||
|
||||
/* File description retrieval */
|
||||
struct LANGANDCODEPAGE {
|
||||
WORD wLanguage;
|
||||
WORD wCodePage;
|
||||
} *translationArray;
|
||||
|
||||
DWORD filler;
|
||||
DWORD fileVersionInfoSize = GetFileVersionInfoSizeW(exePath.c_str(), &filler);
|
||||
if (!fileVersionInfoSize) return exePath;
|
||||
|
||||
void* fileVersionInfo = malloc(fileVersionInfoSize);
|
||||
if(!GetFileVersionInfoW(exePath.c_str(),0,fileVersionInfoSize, fileVersionInfo))
|
||||
return exePath;
|
||||
|
||||
UINT translationArrayLen = 0;
|
||||
if (!VerQueryValueW(fileVersionInfo, L"\\VarFileInfo\\Translation", (LPVOID*)&translationArray, &translationArrayLen))
|
||||
return exePath;
|
||||
|
||||
bool match = false;
|
||||
for (UINT i = 0; i < (translationArrayLen / sizeof(LANGANDCODEPAGE)); i++) {
|
||||
wchar_t fileDescriptionKey[256];
|
||||
LANGID defaultUILanguage = GetUserDefaultUILanguage();
|
||||
if (defaultUILanguage != translationArray[i].wLanguage)
|
||||
continue;
|
||||
|
||||
match = true;
|
||||
wchar_t* fileDescription = NULL;
|
||||
UINT fileDescriptionSize = 0;
|
||||
swprintf(fileDescriptionKey, L"\\StringFileInfo\\%04x%04x\\FileDescription",
|
||||
translationArray[i].wLanguage, translationArray[i].wCodePage);
|
||||
if (VerQueryValueW(fileVersionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) {
|
||||
exePath = std::wstring(fileDescription);
|
||||
}
|
||||
}
|
||||
|
||||
if (!match && 1 <= (translationArrayLen / sizeof(LANGANDCODEPAGE))) {
|
||||
wchar_t fileDescriptionKey[256];
|
||||
|
||||
wchar_t* fileDescription = NULL;
|
||||
UINT fileDescriptionSize = 0;
|
||||
swprintf(fileDescriptionKey, L"\\StringFileInfo\\%04x%04x\\FileDescription",
|
||||
translationArray[0].wLanguage, translationArray[0].wCodePage);
|
||||
if (VerQueryValueW(fileVersionInfo, fileDescriptionKey, (LPVOID*)&fileDescription, &fileDescriptionSize)) {
|
||||
exePath = std::wstring(fileDescription);
|
||||
}
|
||||
}
|
||||
|
||||
free(fileVersionInfo);
|
||||
return exePath;
|
||||
}
|
||||
|
||||
//todo: conflicting names. change callback name
|
||||
void Session::setState(SessionState state) {
|
||||
sessionState = state;
|
||||
}
|
||||
|
||||
SessionState Session::getState() {
|
||||
return sessionState;
|
||||
}
|
||||
|
||||
void Session::setStateCallback(SessionStateCallback *ssc){
|
||||
sessionControl->RegisterAudioSessionNotification((IAudioSessionEvents*) ssc);
|
||||
}
|
||||
|
||||
void Session::removeStateCallback(SessionStateCallback *ssc){
|
||||
sessionControl->UnregisterAudioSessionNotification((IAudioSessionEvents*) ssc);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
sessionControl->Release();
|
||||
sessionVolume->Release();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue