=====Controlling the Master Volume===== //by Richard Russell, October 2016//\\ \\ The main Help documentation describes how to [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwine.html#playsound|control the sound volume]] but in **Windows Vista** and later each running application has its own volume control and the code shown there affects only the sound output from your own program. If instead you want to control the **master volume** you can use the code listed here.\\ \\ The code contains two functions: **FNgetVolume()** which returns the current setting and **PROCsetVolume()** which sets the volume to a specified value. In each case you can specify whether you want to work with **deciBels** (in which case the 'scalar%' parameter should be set to zero) or with a '**linear**' volume range from 0.0 to 1.0 (in which case the 'scalar%' parameter should be set non-zero).\\ \\ The code is adapted from the C++ code listed [[http://www.codeproject.com/Tips/233484/Change-Master-Volume-in-Visual-Cplusplus|here]]. DEF PROCsetVolume(volume#, scalar%) LOCAL ole32%, oleaut32%, deviceEnumerator%, endpointDevice%, endpointVolume% LOCAL Release, Activate, GetDefaultAudioEndpoint, volume% LOCAL SetMasterVolumeLevel, SetMasterVolumeLevelScalar SYS "LoadLibrary", "ole32.dll" TO ole32% SYS "LoadLibrary", "oleaut32.dll" TO oleaut32% SYS "GetProcAddress", ole32%, "CoInitialize" TO `CoInitialize` SYS "GetProcAddress", ole32%, "CoUninitialize" TO `CoUninitialize` SYS "GetProcAddress", ole32%, "CoCreateInstance" TO `CoCreateInstance` SYS "GetProcAddress", ole32%, "CLSIDFromString" TO `CLSIDFromString` SYS "GetProcAddress", oleaut32%, "VarR4FromR8" TO `VarR4FromR8` SYS `CoInitialize`, 0 CLSCTX_INPROC_SERVER = 1 IID_MMDeviceEnumerator = FNguid("{A95664D2-9614-4F35-A746-DE8DB63617E6}") CLSID_MMDeviceEnumerator = FNguid("{BCDE0395-E52F-467C-8E3D-C4579291692E}") IID_IAudioEndpointVolume = FNguid("{5CDF2C82-841E-4546-9722-0CF74078229A}") Release = 2*4 Activate = 3*4 GetDefaultAudioEndpoint = 4*4 SetMasterVolumeLevel = 6*4 SetMasterVolumeLevelScalar = 7*4 SYS `CoCreateInstance`, CLSID_MMDeviceEnumerator, 0, CLSCTX_INPROC_SERVER, \ \ IID_MMDeviceEnumerator, ^deviceEnumerator% SYS !(!deviceEnumerator% + GetDefaultAudioEndpoint), deviceEnumerator%, \ \ 0, 0, ^endpointDevice% SYS !(!endpointDevice% + Activate), endpointDevice%, IID_IAudioEndpointVolume, \ \ CLSCTX_INPROC_SERVER, 0, ^endpointVolume% SYS !(!endpointDevice% + Release), endpointDevice% endpointDevice% = 0 SYS `VarR4FromR8`, !^volume#, !(^volume# + 4), ^volume% IF scalar% THEN SYS !(!endpointVolume% + SetMasterVolumeLevelScalar), endpointVolume%, volume%, 0 ELSE SYS !(!endpointVolume% + SetMasterVolumeLevel), endpointVolume%, volume%, 0 ENDIF SYS !(!endpointVolume% + Release), endpointVolume% endpointVolume% = 0 SYS `CoUninitialize` SYS "FreeLibrary", oleaut32% SYS "FreeLibrary", ole32% ENDPROC DEF FNgetVolume(scalar%) LOCAL ole32%, oleaut32%, deviceEnumerator%, endpointDevice%, endpointVolume% LOCAL Release, Activate, GetDefaultAudioEndpoint, volume#, volume% LOCAL GetMasterVolumeLevel, GetMasterVolumeLevelScalar SYS "LoadLibrary", "ole32.dll" TO ole32% SYS "LoadLibrary", "oleaut32.dll" TO oleaut32% SYS "GetProcAddress", ole32%, "CoInitialize" TO `CoInitialize` SYS "GetProcAddress", ole32%, "CoUninitialize" TO `CoUninitialize` SYS "GetProcAddress", ole32%, "CoCreateInstance" TO `CoCreateInstance` SYS "GetProcAddress", ole32%, "CLSIDFromString" TO `CLSIDFromString` SYS "GetProcAddress", oleaut32%, "VarR8FromR4" TO `VarR8FromR4` SYS `CoInitialize`, 0 CLSCTX_INPROC_SERVER = 1 IID_MMDeviceEnumerator = FNguid("{A95664D2-9614-4F35-A746-DE8DB63617E6}") CLSID_MMDeviceEnumerator = FNguid("{BCDE0395-E52F-467C-8E3D-C4579291692E}") IID_IAudioEndpointVolume = FNguid("{5CDF2C82-841E-4546-9722-0CF74078229A}") Release = 2*4 Activate = 3*4 GetDefaultAudioEndpoint = 4*4 GetMasterVolumeLevel = 8*4 GetMasterVolumeLevelScalar = 9*4 SYS `CoCreateInstance`, CLSID_MMDeviceEnumerator, 0, CLSCTX_INPROC_SERVER, \ \ IID_MMDeviceEnumerator, ^deviceEnumerator% SYS !(!deviceEnumerator% + GetDefaultAudioEndpoint), deviceEnumerator%, \ \ 0, 0, ^endpointDevice% SYS !(!endpointDevice% + Activate), endpointDevice%, IID_IAudioEndpointVolume, \ \ CLSCTX_INPROC_SERVER, 0, ^endpointVolume% SYS !(!endpointDevice% + Release), endpointDevice% endpointDevice% = 0 IF scalar% THEN SYS !(!endpointVolume% + GetMasterVolumeLevelScalar), endpointVolume%, ^volume% ELSE SYS !(!endpointVolume% + GetMasterVolumeLevel), endpointVolume%, ^volume% ENDIF SYS `VarR8FromR4`, volume%, ^volume# SYS !(!endpointVolume% + Release), endpointVolume% endpointVolume% = 0 SYS `CoUninitialize` SYS "FreeLibrary", oleaut32% SYS "FreeLibrary", ole32% = volume# DEF FNguid(A$) LOCAL C%, M% DIM C% 15, M% LOCAL 2*LENA$+1 SYS "MultiByteToWideChar", 0, 0, A$, -1, M%, LENA$+1 SYS `CLSIDFromString`, M%, C% = C%