Grab master volume channel left and right info Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Grab master volume channel left and right info

01 Mar 2017, 08:42

Hi there,

I am on windows XP.

I searched everywere and cant find information regarding my issue so decided to join up and post!:)

I just want to be able to grab left channel and right channel information.

Example:
If i set left channel to be 40, i want to be able to grab and obtain that 40 value.

EDIT
I been using VA: https://autohotkey.com/board/topic/2198 ... functions/
It works on my windows 7 machine.. If i can get this to work in XP it would be great! Sadly, when i try run it in windows xp i receive "Class not registered" Error and wont work. This script works a charm on windows 7 and allows me to control left and right volume balance levels. <-- Now im trying to get it to work on xp.

Please help.
Thanks.
Last edited by irishwill2008 on 06 Mar 2017, 05:39, edited 1 time in total.
garry
Posts: 3770
Joined: 22 Dec 2013, 12:50

Re: Grab master volume channel left and right info

01 Mar 2017, 12:15

here only a volume master slider ( I have just a small balance-slider for Left/Right in sndvol32 )

Code: Select all

run,sndvol32.exe
;run,sndvol32.exe /rec
;CB=runDLL32.EXE shell32.dll,Control_RunDLL mmsys.cpl,,0
;run,%CB%

Gui,2:default
;Gui,2: Color, ControlColor,Black         ;- background from edit
Gui,2: Color, Gray                        ;- Gui color
Gui,2: -DPIScale
Gui,2:Font,  S10 CDefault , FixedSys

sm1:=30   ;-volume
SM2:=100  ;-wave
soundset,0,master,mute         ;-SPEAKER=MASTER ON
SoundSet,%sm1%,master          ;-SPEAKER=MASTER volume
soundset,  0,WAVE,mute         ;-WAVE ON
SoundSet,%SM2%,WAVE            ;-WAVE volume

Gui,2:add, text    , cYellow vT1 w25 right,%sm1%
Gui,2:Add, Slider  , x30  y40  h40  w350     altsubmit    vVOL11a gVOL11 Range0-100 left thick27 line10 buddy1T1 cTeal Tickinterval10,%sm1%
;------------------------------------------------
Gui,2:show,x10 y10 h130 w400 ,Volume-Master
return

2Guiclose:
exitapp

;----- volumex ----------
VOL11:
GuiControlGet, VOL11a
Guicontrol,2:,T1,%VOL11a%
SoundSet,%vol11a%,master
return
;------------------------
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

02 Mar 2017, 07:51

Hi Garry,

Thanks for the help but sadly i am in need of a balance read. So i can read the right and left channels. So if i have two speakers, if i set the left side to be 0 and the right side to be 100 then only audio plays through the right speaker. <-- just an understanding of what i want to achieve! I want to grab the values of the right side and left side (if set).

Thanks though!
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

06 Mar 2017, 05:41

Hi all,

I edited my post to include what i been using. VA, if someone can get to this work on xp that would be great! I just want to be able to read/write data for left and right volume channels in windows xp.
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

15 Mar 2017, 12:26

No news or information regarding this situation?

Very surprised since windows xp has been around years!
garry
Posts: 3770
Joined: 22 Dec 2013, 12:50

Re: Grab master volume channel left and right info

15 Mar 2017, 15:37

tried this with XP , Master-Balance-Control

Code: Select all

; 0.....32....64
; If i set left channel to be 40, i want to be able to grab and obtain that 40 value.
;-----------------VOLUMEBALANCECONTROL-XP -------------------------------
#Persistent
DetectHiddenWindows, ON
Run, sndvol32.exe,,Hide, PID
WinWait, ahk_pid %PID%
ID := WinExist( "ahk_pid" PID )
ControlGet, hVCBAL, Hwnd,, msctls_trackbar321, ahk_id %ID%
Menu,Tray,Icon,SndVol32.exe,1
Menu,Tray,Tip, Volume Balance Control
run,sndvol32

Gui,2:default
Gui,2: Color,Black                         ;- Gui color
Gui,2: -DPIScale
Gui,2:Font, cGray , FixedSys

/*
sm1:=30   ;-volume
SM2:=100  ;-wave
soundset,0,master,mute         ;-SPEAKER=MASTER ON
SoundSet,%sm1%,master          ;-SPEAKER=MASTER volume
soundset,  0,WAVE,mute         ;-WAVE ON
SoundSet,%SM2%,WAVE            ;-WAVE volume
*/

desired=32
Gui,2:add, text    , cYellow vT1 w25 right,%desired%
Gui,2:Add, Slider  , x30  y40  h40  w350     altsubmit    vDesired gSetBalance Range0-64 left thick27 line10 buddy1T1 cTeal Tickinterval64,%desired%
;------------------------------------------------
Gui,2:show,x10 y10 h130 w400 ,Volume-Master-Balance
gosub,SetBalance
OnExit, QuitScript
Return

;----- volumex ----------
setBalance:
GuiControlGet,Desired
SendMessage, (TBM_GETPOS:=0x400),0,0,,ahk_id %hVCBAL%
curBAL := Errorlevel
If ( CurBal >= desired)
 {
 difference:=(curbal-desired)
 loop,%difference%
    ControlSend,,{Left},ahk_id %hVCBAL%
 }

If ( CurBal <= desired)
 {
 difference:=(desired-curbal)
 loop,%difference%
    ControlSend,,{right},ahk_id %hVCBAL%
 }
Guicontrol,2:,T1,%desired%
return
;-----------------------------------------

2Guiclose:
QuitScript:
WinClose, ahk_id %ID%
ExitApp
;===========================================================

qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Grab master volume channel left and right info  Topic is solved

15 Mar 2017, 17:34

Hi,
irishwill2008 wrote:Very surprised since windows xp has been around years!
Funnily enough, as It's now 2017, I'm surprised people are still using an OS that requires one to update the certificates manually....

Anyway, for some reason I have an XP virtual machine (which I'll now delete :-)), so after looking at how the volume control panel applet works, here's my messy attempt:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.

WaveOutIDOfPreferredDevice := mixerID := 0
if (DllCall("winmm\waveOutMessage", "Ptr", WAVE_MAPPER := -1, "UInt", DRVM_MAPPER_PREFERRED_GET := 0x2015, "UInt*", WaveOutIDOfPreferredDevice, "UInt*", Status, "UInt") == 0
	&& DllCall("winmm\mixerGetID", "Ptr", WaveOutIDOfPreferredDevice, "UInt*", mixerID, "UInt", MIXER_OBJECTF_WAVEOUT := 0x10000000, "UInt") == 0
	&& FindDevIDs(mixerID, volID, finalDestination)) {
		if (DllCall("winmm\mixerOpen", "Ptr*", hmx, "UInt", mixerID, "UInt", 0, "UInt", 0, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0) {
			VarSetcapacity(mxl, 280, 0)
			NumPut(280, mxl,, "UInt")
			NumPut(finalDestination, mxl, 4, "UInt")
			if (DllCall("winmm\mixerGetLineInfo", "Ptr", hmx, "Ptr", &mxl, "UInt", 0, "UInt") == 0) {
				channels := NumGet(mxl, 28, "UInt")
				VarSetcapacity(mcd, 24, 0)
				VarSetcapacity(m, 4 * channels, 0)
				NumPut(24, mcd,, "UInt")
				NumPut(volID, mcd, 4, "UInt")
				NumPut(channels, mcd, 8, "UInt")
				NumPut(4, mcd, 16, "UInt")
				NumPut(&m, mcd, 20, "Ptr")
				if (DllCall("winmm\mixerGetControlDetailsW", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt") == 0) {
					Loop % channels
						MsgBox % Round((NumGet(m, 4 * (A_Index - 1), "UInt") / 0xFFFF) * 100)
				}
			}
			DllCall("winmm\mixerClose", "Ptr", hmx)
		}
}

FindDevIDs(mixerID, ByRef volID, ByRef finalDestination)
{
	VarSetcapacity(mxcapsw, (cbmxcaps := 80))
	ret := False

	if (DllCall("winmm\mixerGetDevCapsW", "UInt", mixerID, "Ptr", &mxcapsw, "UInt", cbmxcaps) == 0) {
		if ((destinations := NumGet(mxcapsw, cbmxcaps - 4, "UInt")) > 0) {
			VarSetcapacity(mxl, (cbmxl := 280))
			dest := 0
			while (!ret && dest < destinations) {		
				NumPut(cbmxl, mxl,, "UInt")
				NumPut(dest, mxl, 4, "UInt")
				if (DllCall("winmm\mixerGetLineInfoW", "Ptr", mixerID, "Ptr", &mxl, "UInt", 0, "UInt") == 0) {
					componentType := NumGet(mxl, 24, "UInt")
					if (componentType == 4 || componentType == 5 || componentType == 4104) { ; speakers, headphones & wave out 
						if ((controls := NumGet(mxl, 36, "UInt")) && !ret) { ; controls present
							finalDestination := dest
							control := 0
							cbmc := 228
							VarSetcapacity(mc, controls * cbmc)
							VarSetcapacity(mxlc, (cbmxl := 24), 0)
							NumPut(cbmxl, mxlc,, "UInt")
							NumPut(NumGet(mxl, 12, "UInt"), mxlc, 4, "UInt")
							NumPut(controls, mxlc, 12, "UInt")
							NumPut(cbmc, mxlc, 16, "UInt")
							NumPut(&mc, mxlc, 20, "Ptr")
							
							if (DllCall("winmm\mixerGetLineControlsW", "UInt", mixerID, "Ptr", &mxlc, "UInt", 0, "UInt") == 0) {
								while (!ret && control < controls) {
									if (NumGet(mc, 8 * control, "UInt") == 1342373889) {
										ret := True
										volID := NumGet(mc, 4 * control, "UInt")
									}
									control += 1
								}
							}
						}
					}
				}
				dest += 1
			}
		}
	}

	return ret
}
I only tested it with VMware's emulated sound card. If it doesn't work for you, I can't help, sorry. Maybe combine it with garry's GUI (thanks) for something that looks nicer than the MsgBoxes I have now...
Guest

Re: Grab master volume channel left and right info

23 Mar 2017, 13:28

Hey, can you please upload Vista Audio Control Functions 2.3?
I can't download it in the link you posted (https://autohotkey.com/board/topic/2198 ... functions/)
Thanks
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Grab master volume channel left and right info

23 Mar 2017, 19:31

Guest wrote:Hey, can you please upload Vista Audio Control Functions 2.3?
The IA still has it: https://web.archive.org/web/20160817175 ... VA-2.3.zip
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

29 Mar 2017, 10:26

@qwerty12 :D You did it! Worked a charm!! Displays perfectly! Thank you so so much!

With that said, i no you might shoot me but is there any chance of being able to SET the left and right channels now?
So i have up,down, left and right?
Up and down can put the volume + and - on lets say.. channel 1?
And left and right will + and - channel 0?

Thank you again! Really appreciate it!:)
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Grab master volume channel left and right info

30 Mar 2017, 18:57

You should've said you wanted to be able to set the channels' volume individually in your original post... I really did get rid of my XP virtual machine and I don't have any plans on setting up another any time soon. If Windows 10's emulation of the mixer* APIs in compatibility mode are good enough, I'll take another look, but I wouldn't hold my breath - I barely understand how the code I posted above works...
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

03 Apr 2017, 03:27

Yeah i know but at the time i was just fishing to see if anyone knew anything about channels for xp! Also, i had a script to set the channels by simulating clicks but it aint ideal but at the time i had setting channels working through simulating clicks and all i needed was the values from the channels at the end <-- which is how this post was made!

If you can whip something up, i would highly appreciate it!

Thanks again.
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Grab master volume channel left and right info

03 Apr 2017, 17:13

irishwill2008 wrote:If you can whip something up, i would highly appreciate it!
Probably buggy 'cause I'm terribad at maths, but here:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.

Up::ShiftChannelVolume(1, 2, False)
Down::ShiftChannelVolume(1, -2, False)
Left::ShiftChannelVolume(0, -2, False)
Right::ShiftChannelVolume(0, 2, False)

ShiftChannelVolume(channel, adj, jump) {
	static mixerID, volID, finalDestination, Minimum, Maximum := -1, Steps, MIXER_OBJECTF_WAVEOUT := 0x10000000, mxl, mcd
	
	if (channel < 0)
		return

	if (Maximum == -1) {
		if (!(DllCall("winmm\waveOutMessage", "Ptr", WAVE_MAPPER := -1, "UInt", DRVM_MAPPER_PREFERRED_GET := 0x2015, "UInt*", WaveOutIDOfPreferredDevice, "UInt*", Status, "UInt") == 0
		&& DllCall("winmm\mixerGetID", "Ptr", WaveOutIDOfPreferredDevice, "UInt*", mixerID, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0
		&& FindDevIDs(mixerID, volID, finalDestination, Minimum, Maximum, Steps))) {
			Maximum == -1
			return
		}
		VarSetcapacity(mxl, 280)
		VarSetcapacity(mcd, 24)
	}
	DllCall("ntdll\RtlZeroMemory", "Ptr", &mxl, "Ptr", 280)
	NumPut(280, mxl,, "UInt"), NumPut(finalDestination, mxl, 4, "UInt")

	adj := CLAMP(adj, jump ? 0 : -100, 100)

	if (DllCall("winmm\mixerOpen", "Ptr*", hmx, "UInt", mixerID, "UInt", 0, "UInt", 0, "UInt", MIXER_OBJECTF_WAVEOUT, "UInt") == 0) {
		if (DllCall("winmm\mixerGetLineInfo", "Ptr", hmx, "Ptr", &mxl, "UInt", 0, "UInt") == 0) {
			channels := NumGet(mxl, 28, "UInt")
			if (channel < channels) {
				DllCall("ntdll\RtlZeroMemory", "Ptr", &mcd, "Ptr", 24)
				VarSetcapacity(m, 4 * channels, 0)
				NumPut(24, mcd,, "UInt")
				NumPut(volID, mcd, 4, "UInt")
				NumPut(channels, mcd, 8, "UInt")
				NumPut(4, mcd, 16, "UInt")
				NumPut(&m, mcd, 20, "Ptr")
				
				if (DllCall("winmm\mixerGetControlDetailsW", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt") == 0) {
					curVolume := Round((NumGet(m, 4 * channel, "UInt") / Maximum) * 100)
					newVol := jump ? adj : CLAMP(curVolume + adj, 0, 100)
					if (curVolume != newVol) {
						NumPut((Maximum - Minimum) * (newVol / 100.0), m, 4 * channel, "UInt") ; stolen from the AutoHotkey source
						DllCall("winmm\mixerSetControlDetails", "Ptr", hmx, "Ptr", &mcd, "UInt", 0, "UInt")
					}
				}
			}
		}
		DllCall("winmm\mixerClose", "Ptr", hmx)
	}
}

FindDevIDs(mixerID, ByRef volID, ByRef finalDestination, ByRef Minimum, ByRef Maximum, ByRef Steps)
{
	VarSetcapacity(mxcapsw, (cbmxcaps := 80))

	if (DllCall("winmm\mixerGetDevCapsW", "UInt", mixerID, "Ptr", &mxcapsw, "UInt", cbmxcaps) == 0) {
		if ((destinations := NumGet(mxcapsw, cbmxcaps - 4, "UInt")) > 0) {
			VarSetcapacity(mxl, (cbmxl := 280))
			NumPut(cbmxl, mxl,, "UInt")
			cbmc := 228
			cbmxlc := 24
			Loop %destinations% {
				dest := A_Index - 1
				NumPut(dest, mxl, 4, "UInt")
				if (DllCall("winmm\mixerGetLineInfoW", "Ptr", mixerID, "Ptr", &mxl, "UInt", 0, "UInt") == 0) {
					componentType := NumGet(mxl, 24, "UInt")
					if (componentType == 4 || componentType == 5 || componentType == 4104) { ; speakers, headphones & wave out 
						if ((controls := NumGet(mxl, 36, "UInt"))) { ; controls present
							finalDestination := dest
							VarSetcapacity(mc, controls * cbmc)
							VarSetcapacity(mxlc, cbmxlc, 0)
							NumPut(cbmxlc, mxlc,, "UInt")
							NumPut(NumGet(mxl, 12, "UInt"), mxlc, 4, "UInt")
							NumPut(controls, mxlc, 12, "UInt")
							NumPut(cbmc, mxlc, 16, "UInt")
							NumPut(&mc, mxlc, 20, "Ptr")
							
							if (DllCall("winmm\mixerGetLineControlsW", "UInt", mixerID, "Ptr", &mxlc, "UInt", 0, "UInt") == 0) {
								Loop %controls% {
									control := A_Index - 1
									if (NumGet(mc, 8 + (control * cbmc), "UInt") == 1342373889) { ; volume control
										Minimum := NumGet(mc, 180 + (control * cbmc), "UInt")
										Maximum := NumGet(mc, 184 + (control * cbmc), "UInt")
										Steps := NumGet(mc, 204 + (control * cbmc), "UInt")
										volID := NumGet(mc, 4 + (control * cbmc), "UInt")
										return True
									}
								}
							}
						}
					}
				}
			}
		}
	}

	return False
}

CLAMP(x, low, high)
{
	return (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
}
irishwill2008
Posts: 11
Joined: 01 Mar 2017, 08:40

Re: Grab master volume channel left and right info

04 Apr 2017, 03:26

I am not sure how you did it but you did it!! Fantastic :D Works a charm and the maths all work out great! For someone who says they are not the best, you sure are the best! Thank you so so much. Much appreciated! Been trying to get this to work and bam, you got it!

Can i ask,
Where did you come up with all that code to make it work? Could you explain what specific parts mean so i can learn from the code? Looking at it, its hard to make most of it out! xD

Thanks again!
You saved me hours upon hours :)

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 230 guests