IanN1990 Posted October 5, 2012 Share Posted October 5, 2012 (edited) My Knoweledge of c++ is extremely limited, so i thought i would release this question here as this is the c++ forum ^^.The code below displays a GUI with a progress bar that varys depending on the volume level. Louder it is, higher the bar. Quiter it is, lower the bar.I want to make a auto-volume control, so when the peak goes above a set level it would lower or raise it. The problem is, as far as i can tell this code only gets the volume level of the application running. I would like to get the master volume, so when the master volume is lowered then the peak would be lowered.From my understanding atm,when the code is run it displays the peak of "B". As if i lower/raise that slider, the peak is changed. I would like to read the peak from "A". So in that example, i could see the peak is much higher then the set volume, and for it to be raised.So i was wondering if there is someone who does understand how this works could help me change it to the desired results.Codeexpandcollapse popup#include <GuiConstants.au3> #include <ProgressConstants.au3> Global Const $S_OK = 0 ;=============================================================================== #interface "IMMDeviceEnumerator" Global Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}" Global Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}" ; Definition Global Const $tagIMMDeviceEnumerator = "EnumAudioEndpoints hresult(dword;dword;ptr*);" & _ "GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" & _ "GetDevice hresult(wstr;ptr*);" & _ "RegisterEndpointNotificationCallback hresult(ptr);" & _ "UnregisterEndpointNotificationCallback hresult(ptr);" ;=============================================================================== ;=============================================================================== #interface "IMMDevice" Global Const $sIID_IMMDevice = "{D666063F-1587-4E43-81F1-B948E807363F}" ; Definition Global Const $tagIMMDevice = "Activate hresult(clsid;dword;variant*;ptr*);" & _ "OpenPropertyStore hresult(dword;ptr*);" & _ "GetId hresult(ptr*);" & _ "GetState hresult(dword*);" ;=============================================================================== ;=============================================================================== #interface "IAudioMeterInformation" Global Const $sIID_IAudioMeterInformation = "{C02216F6-8C67-4B5B-9D00-D008E73E0064}" ; Definition Global Const $tagIAudioMeterInformation = "GetPeakValue hresult(float*);" & _ "GetMeteringChannelCount hresult(dword*);" & _ "GetChannelsPeakValues hresult(dword;float*);" & _ "QueryHardwareSupport hresult(dword*);" ;=============================================================================== Global $oAudioMeterInformation = _AudioVolObject() If Not IsObj($oAudioMeterInformation) Then Exit -1 ; Will happen on non-supported systems Global $hGUI Global $hControl = _MakePeakMeterInWindow($hGUI) ; Register function to periodically update the progress control AdlibRegister("_LevelMeter", 45) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd AdlibUnRegister() ; Bye, bye... Func _MakePeakMeterInWindow($hWindow) $hWindow = GUICreate("ABC", 150, 400) Return GUICtrlCreateProgress(20, 70, 15, 200, $PBS_VERTICAL) EndFunc Func _LevelMeter() Local $iPeak If $oAudioMeterInformation.GetPeakValue($iPeak) = $S_OK Then $iCurrentRead = 100 * $iPeak GUICtrlSetData($hControl, $iCurrentRead + 1) GUICtrlSetData($hControl, $iCurrentRead) EndIf EndFunc Func _AudioVolObject() ; Sequences of code below are taken from the source of plugin written for AutoIt for setting master volume on Vista and above systems. ; Code was written by wraithdu in C++. ; MMDeviceEnumerator Local $oMMDeviceEnumerator = ObjCreateInterface($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $tagIMMDeviceEnumerator) If @error Then Return SetError(1, 0, 0) Local Const $eRender = 0 Local Const $eConsole = 0 ; DefaultAudioEndpoint Local $pDefaultDevice $oMMDeviceEnumerator.GetDefaultAudioEndpoint($eRender, $eConsole, $pDefaultDevice) If Not $pDefaultDevice Then Return SetError(2, 0, 0) ; Turn that pointer into object Local $oDefaultDevice = ObjCreateInterface($pDefaultDevice, $sIID_IMMDevice, $tagIMMDevice) Local Const $CLSCTX_INPROC_SERVER = 0x1 ; AudioMeterInformation Local $pAudioMeterInformation $oDefaultDevice.Activate($sIID_IAudioMeterInformation, $CLSCTX_INPROC_SERVER, 0, $pAudioMeterInformation) If Not $pAudioMeterInformation Then Return SetError(3, 0, 0) Return ObjCreateInterface($pAudioMeterInformation, $sIID_IAudioMeterInformation, $tagIAudioMeterInformation) EndFuncOriginal PostMicrosoft MSDMhttp://msdn.microsoft.com/en-us/library/dd316561%28VS.85%29.aspx Edited October 5, 2012 by IanN1990 Link to comment Share on other sites More sharing options...
wraithdu Posted October 5, 2012 Share Posted October 5, 2012 See my reply in your other thread. Please don't cross post. Link to comment Share on other sites More sharing options...
IanN1990 Posted October 5, 2012 Author Share Posted October 5, 2012 @Wraithdu I read your reply and it did help me understand a few things. So i will amend my original post.I wasn't sure which topic to reply to, and i guess in that sense i see what you mean by cross posting but that wasn't my goal.Considering Posting new code on a Thread labelled "March 2012" as necroing. The original poster for that thread has not been on-line for a while and only has 5 posts. Plus the only answer available is related to c++ rather then general help / support within auto it. Which is why I felt it would be best to start fresh here. Maybe I was in the wrong. Link to comment Share on other sites More sharing options...
IanN1990 Posted October 5, 2012 Author Share Posted October 5, 2012 (edited) I read your post, and i tell you what. I think you have solved this problem.I increased the slider to 100% and I did notice the grey bar disappears. Meaning my original question becomes invalid, so i had to rethink how i would write the question to still achive the end result. I also noticed when the main-volume is turned up or down both green bars change respectively *Even in the example I now see both bars are exactly level*. So getting the App Volume or Main Volume would make no difference. I approached this whole problem the wrong way round.Then it hit me, in the code the $peak is times 100. What if this value was timed by the master volume level ? and sure enough this gives the result I am after.expandcollapse popup#Notrayicon #include <_AudioEndpointVolume.au3> Local $pDefaultDevice local $pAudioMeterInformation Local $oAudioMeterInformation = _AudioVolObject() $hWindow = GUICreate("ABC", 150, 400) $hControl = GUICtrlCreateProgress(20, 70, 15, 200, 4) GUISetState() AdlibRegister("_LevelMeter", 125) while 1 sleep(250) wend Func _LevelMeter() Local $iPeak $oAudioMeterInformation.GetPeakValue($iPeak) $iPeak *= _GetMasterVolumeLevelScalar() GUICtrlSetData($hControl, $iPeak) ConsoleWrite($iPeak & @CRLF) If $iPeak < 30 then Send("{Volume_UP}") If $iPeak > 35 then Send("{Volume_Down}") EndFunc Func _AudioVolObject() Local $oMMDeviceEnumerator = ObjCreateInterface("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}", "EnumAudioEndpoints hresult(dword;dword;ptr*);GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" ) $oMMDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, $pDefaultDevice) Local $oDefaultDevice = ObjCreateInterface($pDefaultDevice, "{D666063F-1587-4E43-81F1-B948E807363F}", "Activate hresult(clsid;dword;variant*;ptr*);") $oDefaultDevice.Activate("{C02216F6-8C67-4B5B-9D00-D008E73E0064}", 0x1, 0, $pAudioMeterInformation) Return ObjCreateInterface($pAudioMeterInformation, "{C02216F6-8C67-4B5B-9D00-D008E73E0064}", "GetPeakValue hresult(float*);") EndFuncI have yet to really test to code, as i only came up with this idea a few minutes "and am quite excited as well, 4 days with no results and then a break though ^^" but i hope it will turn out wellRequires _AudioEndpointVolume.au3Works on Windows 7 Edited October 5, 2012 by IanN1990 Link to comment Share on other sites More sharing options...
wraithdu Posted October 5, 2012 Share Posted October 5, 2012 It works as long as the channel volume matches the master volume, since all this code is dealing with the master volume endpoint. Otherwise you need to be able to get the channel volume as well so you can get the proper ratio. But yeah, you're definitely on the right track. Though I'm not sure just multiplying by the master volume level is correct. The peak value is multiplied by 100 because it is a float value between 0 and 1, and you need *100 to get a 'percentage' value from 0 to 100. So thinking about this again... you're not really interested in the channel volume at all right? So the original code is actually what you're after... the master output peak volume. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now