Jump to content

Automating SoundWire Server's Master Volume slider


b9k
 Share

Recommended Posts

Hi, I am stuck on a GUI problem and would like your help to solve it.

I am trying to automate the SoundWire Server app to match my current system volume level while it is minimized to the notification area (so no clicking or stealing focus),

I can already get the handle and alter the tracker position by sending a WM_SETPOS message, but somehow the actual volume is not changed: I think I need to do something else to trigger the event handler for the value change and propagate it correctly.

This is the control summary from Au3 info:

>>>> Window <<<<
Title:  SoundWire Server
Class:  #32770
Position:   441, 218
Size:   566, 429
Style:  0x94CA00C4
ExStyle:    0x00050101
Handle: 0x0000000000510E12

>>>> Control <<<<
Class:  msctls_trackbar32
Instance:   4
ClassnameNN:    msctls_trackbar324
Name:   
Advanced (Class):   [CLASS:msctls_trackbar32; INSTANCE:4]
ID: 6002
Text:   
Position:   51, 222
Size:   47, 126
ControlClick Coords:    1, 101
Style:  0x5001000A
ExStyle:    0x00000000
Handle: 0x00000000001234C8

>>>> Mouse <<<<
Position:   496, 567
Cursor ID:  2
Color:  0xF0F0F0

>>>> StatusBar <<<<

>>>> ToolsBar <<<<

>>>> Visible Text <<<<
Default multimedia device
Tray on Start
Static
Server Address:
 192.168.1.8
Status:
 Connected to B9K~OP3
Audio Output          Audio Input                  Level                   Record to File
Input Select:
 44.1 kHz
Minimize to
Master Volume
Mute


>>>> Hidden Text <<<<
Slider2
Mute
OK
Cancel
Label
Balance
Slider1
Volume
Front L/R
Fr C/LFE
Side L/R
Back L/R


I am attaching the program in question so you don't have to install it (i don't know if it is portable enough, tough): 

SoundWire Server_files.zip

Thanks in advance and I hope I didn't post in the wrong section :D

Edited by b9k
more info
Link to comment
Share on other sites

On Windows7 I use a DLL to get and put the system volume.  I have done it other ways on XP but I forget atm and I'm at work.

Author: JohnOne

 

Func _SetMasterVolume($vol) ; 0 - 100
    Local $V7Voldll = "W7VVol.dll"
    DllCall($V7Voldll, 'long', 'setvol', 'float', $vol / 100)
    If @error Then
        MsgBox(0, $gScript_name, "_SetMasterVolume(): Error", @error)
        ;Exit MsgBox($gScript_name, "Error", @error)
    EndIf
EndFunc   ;==>_SetMasterVolume

Func _GetMasterVolume()
    Local $V7Voldll = "W7VVol.dll"
    $aDllCall = DllCall($V7Voldll, 'float', 'getvol')
    If @error Then
        MsgBox(0, $gScript_name, "_GetMasterVolume(): Error", @error)
        ;Exit MsgBox(0, "Error", @error)
    EndIf
    Return Round($aDllCall[0], 2) * 100
EndFunc   ;==>_GetMasterVolume

 

W7VVol.dll

Edited by Xandy
Link to comment
Share on other sites

Getting the system volume is working, so now the real problem is how to change the "Master Volume" slider in Sound Wire Server. 

I tried to send a TBS_SETPOS window message to the slider control, but while the head is moved no event handler is invoked because the volume does not change.
I believe this may be due to some other window message i need to send or because that GUI seems to be made with qt.

 

image.png

Edited by b9k
Link to comment
Share on other sites

Update: I also tried sending TBM_SETPOSNOTIFY but it does not seem to move.

I believe it may be due to the fact that the slider does not normally react to the scrolling wheel and that message's documentation said it uses a scroll message to alert the parent window of the change.

Edited by b9k
more info
Link to comment
Share on other sites

@EarthshineHere is the failing code:

#include <SendMessage.au3> ; 1029 is TBM_SETPOS, 1 is to redraw the control, 65535 is the slider position (65535 = 0%, 0 = 100%)
_SendMessage(ControlGetHandle(WinGetHandle("SoundWire Server"), "", "[CLASS:msctls_trackbar32; INSTANCE:4]"), 1029, 1, 65535)

Which actually is the same as using _GUICtrlSlider_SetPos on that control, and it does nothing.


This is the program window before running the code, with volume set to maximum (look at the Level indicator):

image.png.3384b9826351e0dad4251c2a7f05badd.png

 

This is the window after I run the above code (look at the Level indicator, it's still there even if the displayed volume is zero):
image.png.a6ef165a1be6a19e11cb4f366e93446c.png

 

And finally this is the expected result (now the Level indicator is right and the volume is zero for real):


image.png.6463f4f3cc0811ceeaaa9b83263c3532.png

I hope this helps you guys understand my problem :)

Edited by b9k
Link to comment
Share on other sites

Figure out the value when the slider is maxed.

I think you can GetPos.  You're still going to need to somehow figure out the Max.  1, 100, 128, 255 are guesses.

Is the max 1?

Max / GetPos = Val?

Something like that, I hate math.

Edit this is where I came up with that idea.

 

Edited by Xandy
Link to comment
Share on other sites

Yeah I visited that thread: it was very useful since it gave me the idea to use the TBM_SETPOS message.

In this particular case I don't need to use TBM_GETPOS because the position I am trying to set is a known value: the 65535 in my code.
It will be eventually replaced by a variable holding the correct position based on the volume (the volume value too is in the 0-65535 range so no math needed). 


Now, I only need to be able to set that slider position correctly.

Edited by b9k
Link to comment
Share on other sites

I understand now my solution wasn't valid.

I'm not sure how to handle this.  I'll keep thinking about it.

Need to set value of the slider as well as the position.  I'll look for a command and give it a go later if I have time.  You've looked for a GetVal I imagine. :)

Edited by Xandy
Link to comment
Share on other sites

@b9k

#include <GuiSlider.au3>

$hCtrl = ControlGetHandle("SoundWire Server", "", "msctls_trackbar324")
$aRange = _GUICtrlSlider_GetRange($hCtrl)
ConsoleWrite($aRange[0] & ":" & $aRange[1] & @CRLF)

_GUICtrlSlider_SetPos($hCtrl, $aRange[1] * 0.5) ; 50%
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "50%")

_GUICtrlSlider_SetPos($hCtrl, $aRange[1]) ; min
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "min")

_GUICtrlSlider_SetPos($hCtrl, $aRange[1] * 0.3) ; 70%
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "70%")

_GUICtrlSlider_SetPos($hCtrl, $aRange[0]) ; max
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "max")

 

Link to comment
Share on other sites

2 hours ago, InnI said:

@b9k

#include <GuiSlider.au3>

$hCtrl = ControlGetHandle("SoundWire Server", "", "msctls_trackbar324")
$aRange = _GUICtrlSlider_GetRange($hCtrl)
ConsoleWrite($aRange[0] & ":" & $aRange[1] & @CRLF)

_GUICtrlSlider_SetPos($hCtrl, $aRange[1] * 0.5) ; 50%
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "50%")

_GUICtrlSlider_SetPos($hCtrl, $aRange[1]) ; min
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "min")

_GUICtrlSlider_SetPos($hCtrl, $aRange[1] * 0.3) ; 70%
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "70%")

_GUICtrlSlider_SetPos($hCtrl, $aRange[0]) ; max
ControlSend("SoundWire Server", "", $hCtrl, "{up}")
MsgBox(0, "", "max")

 

Thanks, this is very clever indeed! So I needed to "stimulate" a refresh on the app side by sending bogus input: it works flawlessly because in this particular app the {up} and {down} keys do not change the value. But as a thought exercise, what could I have done if they did? I'm wondering... basically I got lucky this time.

I will use this trick in my code, since it works, but I'm still open to other solutions.

Link to comment
Share on other sites

4 hours ago, b9k said:

other solution

#include <GuiSlider.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>

$iPercent = 30 ; volume % (0-100)

$hWnd = WinGetHandle("SoundWire Server")
$hCtrl = ControlGetHandle($hWnd, "", "msctls_trackbar324")
_GUICtrlSlider_SetPos($hCtrl, (100 - $iPercent) * 655.35)
_SendMessage($hWnd, $WM_VSCROLL, 0, $hCtrl)

 

Link to comment
Share on other sites

19 hours ago, InnI said:
#include <GuiSlider.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>

$iPercent = 30 ; volume % (0-100)

$hWnd = WinGetHandle("SoundWire Server")
$hCtrl = ControlGetHandle($hWnd, "", "msctls_trackbar324")
_GUICtrlSlider_SetPos($hCtrl, (100 - $iPercent) * 655.35)
_SendMessage($hWnd, $WM_VSCROLL, 0, $hCtrl)

 

Yo, that was what I was thinking when I posted here: a more general approach! Thank you all for your help!

Edited by b9k
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...