From e8283b091609e907176034a5c195e05cc4f85c7a Mon Sep 17 00:00:00 2001 From: oupson Date: Wed, 28 Dec 2022 17:52:42 +0100 Subject: [PATCH] Initial Commit --- AudioManager.sln | 31 +++++ AudioManager/AudioManager.cpp | 113 ++++++++++++++++ AudioManager/AudioManager.vcxproj | 138 ++++++++++++++++++++ AudioManager/AudioManager.vcxproj.filters | 27 ++++ AudioManager/CAudioEndpointVolumeCallback.h | 87 ++++++++++++ 5 files changed, 396 insertions(+) create mode 100644 AudioManager.sln create mode 100644 AudioManager/AudioManager.cpp create mode 100644 AudioManager/AudioManager.vcxproj create mode 100644 AudioManager/AudioManager.vcxproj.filters create mode 100644 AudioManager/CAudioEndpointVolumeCallback.h diff --git a/AudioManager.sln b/AudioManager.sln new file mode 100644 index 0000000..68c9080 --- /dev/null +++ b/AudioManager.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33110.190 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioManager", "AudioManager\AudioManager.vcxproj", "{AB9AB063-8DF7-475F-BA26-E548DE7ADC42}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Debug|x64.ActiveCfg = Debug|x64 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Debug|x64.Build.0 = Debug|x64 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Debug|x86.ActiveCfg = Debug|Win32 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Debug|x86.Build.0 = Debug|Win32 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Release|x64.ActiveCfg = Release|x64 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Release|x64.Build.0 = Release|x64 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Release|x86.ActiveCfg = Release|Win32 + {AB9AB063-8DF7-475F-BA26-E548DE7ADC42}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E52E8A34-C699-4524-A66A-AD77846E7FF9} + EndGlobalSection +EndGlobal diff --git a/AudioManager/AudioManager.cpp b/AudioManager/AudioManager.cpp new file mode 100644 index 0000000..334aeb9 --- /dev/null +++ b/AudioManager/AudioManager.cpp @@ -0,0 +1,113 @@ +// AudioManager.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include + + +#include +#include +#include +#include +#include "CAudioEndpointVolumeCallback.h" + + +#define EXIT_ON_ERROR(hr) \ + if (FAILED(hr)) { exit(-1); } +#define ERROR_CANCEL(hr) \ + if (FAILED(hr)) { \ + MessageBox(hDlg, TEXT("The program will exit."), \ + TEXT("Fatal error"), MB_OK); \ + EndDialog(hDlg, TRUE); return TRUE; } + +#define SAFE_RELEASE(punk) \ + if ((punk) != NULL) \ + { (punk)->Release(); (punk) = NULL; } + + + +volatile bool isRunning = true; +BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) { + switch (dwCtrlType) + { + case CTRL_C_EVENT: + isRunning = false; + // Signal is handled - don't pass it on to the next handler + return TRUE; + default: + // Pass signal on to the next handler + return FALSE; + } +} + +int main() +{ + HRESULT hr = S_OK; + + GUID g_guidMyContext = GUID_NULL; + + IMMDeviceEnumerator* pEnumerator = NULL; + + IMMDevice* pDevice = NULL; + IMMDevice* cDevice = NULL; + + static IAudioEndpointVolume* g_pEndptVol = NULL; + static IAudioEndpointVolume* g_cEndptVol = NULL; + + SetConsoleCtrlHandler(HandlerRoutine, TRUE); + + hr = CoInitialize(NULL); + EXIT_ON_ERROR(hr); + + hr = CoCreateGuid(&g_guidMyContext); + EXIT_ON_ERROR(hr); + + // Get enumerator for audio endpoint devices. + hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), + NULL, CLSCTX_INPROC_SERVER, + __uuidof(IMMDeviceEnumerator), + (void**)&pEnumerator); + EXIT_ON_ERROR(hr); + + hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice); + EXIT_ON_ERROR(hr); + + hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eCommunications, &cDevice); + EXIT_ON_ERROR(hr); + + + hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), + CLSCTX_ALL, NULL, (void**)&g_pEndptVol); + EXIT_ON_ERROR(hr); + + hr = cDevice->Activate(__uuidof(IAudioEndpointVolume), + CLSCTX_ALL, NULL, (void**)&g_cEndptVol); + EXIT_ON_ERROR(hr); + + CAudioEndpointVolumeCallback EPVolEvents(g_pEndptVol, g_cEndptVol, g_guidMyContext); + + float mainVolume; + hr = g_pEndptVol->GetMasterVolumeLevelScalar(&mainVolume); + EXIT_ON_ERROR(hr); + + float commVolume; + hr = g_cEndptVol->GetMasterVolumeLevelScalar(&commVolume); + EXIT_ON_ERROR(hr); + + std::cout << "\r\033[2KMain Volume : " << mainVolume * 100 << ", Communication Volume : " << commVolume * 100; + + hr = g_pEndptVol->RegisterControlChangeNotify( + (IAudioEndpointVolumeCallback*)&EPVolEvents); + EXIT_ON_ERROR(hr); + + while (isRunning) { + Sleep(0); + } + + SAFE_RELEASE(pEnumerator); + SAFE_RELEASE(pDevice); + SAFE_RELEASE(g_pEndptVol); + SAFE_RELEASE(g_cEndptVol); + CoUninitialize(); + + return 0; +} \ No newline at end of file diff --git a/AudioManager/AudioManager.vcxproj b/AudioManager/AudioManager.vcxproj new file mode 100644 index 0000000..f21892e --- /dev/null +++ b/AudioManager/AudioManager.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {ab9ab063-8df7-475f-ba26-e548de7adc42} + AudioManager + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/AudioManager/AudioManager.vcxproj.filters b/AudioManager/AudioManager.vcxproj.filters new file mode 100644 index 0000000..4cf75d3 --- /dev/null +++ b/AudioManager/AudioManager.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/AudioManager/CAudioEndpointVolumeCallback.h b/AudioManager/CAudioEndpointVolumeCallback.h new file mode 100644 index 0000000..6d34e38 --- /dev/null +++ b/AudioManager/CAudioEndpointVolumeCallback.h @@ -0,0 +1,87 @@ +#pragma once + +#include +#include + +class CAudioEndpointVolumeCallback : public IAudioEndpointVolumeCallback +{ +private: + LONG _cRef; + IAudioEndpointVolume* g_pEndptVol; + IAudioEndpointVolume* g_cEndptVol; + GUID g_guidContext; + +public: + CAudioEndpointVolumeCallback(IAudioEndpointVolume* g_pEndptVol, IAudioEndpointVolume* g_cEndptVol, GUID g_guidContext) : + _cRef(1), g_pEndptVol(g_pEndptVol), g_cEndptVol(g_cEndptVol), g_guidContext(g_guidContext) + { + } + + ~CAudioEndpointVolumeCallback() + { + } + + // IUnknown methods -- AddRef, Release, and QueryInterface + + ULONG STDMETHODCALLTYPE AddRef() + { + return InterlockedIncrement(&_cRef); + } + + ULONG STDMETHODCALLTYPE Release() + { + ULONG ulRef = InterlockedDecrement(&_cRef); + if (0 == ulRef) + { + delete this; + } + return ulRef; + + } + + HRESULT STDMETHODCALLTYPE 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; + } + + // Callback method for endpoint-volume-change notifications. + + HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify) + { + if (pNotify == NULL) + { + return E_INVALIDARG; + } + if (pNotify->guidEventContext != this->g_guidContext) + { + HRESULT hr = this->g_cEndptVol->SetMasterVolumeLevelScalar(pNotify->fMasterVolume, &this->g_guidContext); + if (hr != S_OK) { + std::cerr << "Error while setting volume" << std::endl; + } + + + float commVolume; + hr = g_cEndptVol->GetMasterVolumeLevelScalar(&commVolume); + if (hr == S_OK) { + std::cout << "\r\033[2KMain Volume : " << pNotify->fMasterVolume * 100 << ", Communication Volume : " << commVolume * 100; + } + + } + return S_OK; + } +};