AutoHotkey Community

It is currently May 25th, 2012, 5:18 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 151 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next
Author Message
PostPosted: October 2nd, 2007, 1:47 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Vista Audio Control Functions v2.1
VA provides Windows Vista and 7-compatible alternatives to some SoundSet/SoundGet subcommands, as well as some additional features that SoundSet/SoundGet do not support. See the online documentation for a list of functions.

Note: This library depends entirely upon APIs present only in Windows Vista and later. Scripts using it should NOT be run in XP compatibility mode or on any version of Windows older than Vista.

Notes for v2.1:
  • Requires AutoHotkey_L (any recent build should work).
  • COM.ahk is NOT required. COM_Init() does NOT need to be called.
Notes for v2.0:


Download v2.1 with documentation - v2.0
Covered by Lexikos' default copyright license.
Online Documentation


Device Topology / Subunits

Subunit/component names are defined by the audio drivers, so will vary from PC to PC. Volume subunits often have the same names as shown on the Levels tab in the Properties of the sound device. Mute subunits might not have unique names; in those cases, use a numeric index instead of a name.

topology2.ahk can be used to determine which devices, volume and mute subunits are available. By default it shows playback devices; to show capture devices, replace "playback:" with "capture:".


Last edited by Lexikos on December 30th, 2010, 10:39 am, edited 12 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 1:20 am 
Offline

Joined: January 7th, 2007, 6:40 pm
Posts: 109
Location: In fund pe scaun, la o bere prin Romania :D
Image I wanted this! I had problems with some of the OSC sound controls scripts working in Vista. Mes omages! :D

_________________
ImageBackgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 1:40 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
I'm glad it was of use to someone. :) I wrote it so that I could mute/unmute line in. :lol:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 5th, 2007, 8:44 pm 
Offline

Joined: October 3rd, 2007, 9:32 pm
Posts: 157
Location: UK
Sounds like a great app but i still cant get it to work correctly. The thing is VA_GETVOLUME() seems to retrieve the wrong volumes when compared to what is detailed by windows mixer, so i did a test:

Code:
Windows Mixer vs VA_GETVOLUME()

0   0.000000
1   0.184100
2   0.391507
3   0.623866
4   0.878952
5   1.151728
6   1.451509
7   1.773915
8   2.112748
9   2.470650
10   2.854000
11   3.246838
12   3.671082
13   4.110560
14   4.560251
15   5.034180
16   5.531064
17   6.049241
18   6.586668
19   7.113557
20   7.679757
21   8.256726
22   8.874515
23   9.500057
24   10.129228
25   10.757594
26   11.423194
27   12.128233
28   12.827102
29   13.514300
30   14.236999
31   14.997031
32   15.796326
33   16.575456
34   17.327725
35   18.180182
36   19.003250
37   19.789590
38   20.683663
39   21.537840
40   22.426500
41   23.351034
42   24.223868
43   25.128676
44   26.066630
45   27.038945
46   28.046877
47   28.985548
48   30.064791
49   31.069872
50   32.108030
51   33.059484
52   34.163121
53   35.303077
54   36.347829
55   37.423088
56   38.529746
57   39.668718
58   40.840949
59   41.894696
60   43.131927
61   44.244104
62   45.549938
63   46.723785
64   47.927570
65   49.162057
66   50.428028
67   51.726288
68   53.057658
69   54.225826
70   55.620946
71   56.845049
72   58.306970
73   59.589685
74   60.900392
75   62.239699
76   63.608233
77   65.006629
78   66.435541
79   67.895633
80   69.387587
81   70.655721
82   72.207904
83   73.793958
84   75.142075
85   76.514664
86   78.194697
87   79.622695
88   81.076615
89   82.856196
90   84.368809
91   85.908878
92   87.476902
93   89.073389
94   90.698855
95   92.353825
96   94.038836
97   95.408841
98   97.149306
99   98.921363
100   100.000000
[Moderator's note - added code tags to shrink]
Which ends up looking like this:
Image

I simply wrote the values derived from currentSound := VA_GetVolume() to a csv file as a test - what could have gone wrong? Any suggestions?

Many thanks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 3:03 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
tuna wrote:
Sounds like a great app but i still cant get it to work correctly. The thing is VA_GETVOLUME() seems to retrieve the wrong volumes when compared to what is detailed by windows mixer,
The APIs I used aren't really intended for simple master volume control. They only allow volume control using decibels (which is non-linear), whereas a more appropriate interface (for master volume only) allows decibels or scalar values (between 0 and 1.)

To use scalar values, I had to find an algorithm to calculate scalar from decibels, and vice versa. Since I had tested it (on "Line Volume") and the results seemed accurate, your results surprise me.

Actually, testing it again, it does exactly what it is supposed to: VA_GetVolume("Speakers") matches up with the volume reported by Speakers Properties (Levels tab.) It is strange that Speakers in Speakers Properties and Speakers in the Volume Mixer differ like that. I guess it's because the Speakers Properties tab uses the same interface and algorithm as I do to convert decibels <-> scalar values, whereas the Volume Mixer does not.

To get to Speakers Properties, right-click the volume tray icon, click Playback Devices, and on the Playback tab, double-click Speakers.
Larry Osterman wrote:
In Vista RTM, the SetMasterVolumeLevelScalar API runs the input volume (from 0.0 to 1.0) through a volume curve to produce a more linear volume experience - it's intended for use in application volume control sliders.
IAudioEndpointVolume value and SndVol not in Sync
(He is referring to the IAudioEndpointVolume interface, which is for master volume control. I use IAudioVolumeLevel, which works for Line In, Microphone, etc.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 3:52 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
I've updated the script, adding the following functions:
Code:
VA_GetMasterVolume( [ channel ] )
VA_SetMasterVolume( vol [, channel ] )
VA_GetMasterChannelCount()
VA_GetMasterMute()
VA_SetMasterMute( mute )

These use IAudioEndpointVolume, so they accurately reflect the volume levels reported by Vista's volume mixer.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 8:41 am 
Offline

Joined: October 3rd, 2007, 9:32 pm
Posts: 157
Location: UK
Thanks. However oddly enough it still doesnt seem to work too well (though the mute function seems to wrok fine - its just the get and set ones that seem to be having problems). Since you've fixed your code, its probably now something in my code:

Code:
COM_CoInitialize()


currentSound := VA_GetMasterVolume()
; msgbox %currentSound%`n%vol% ;just for testing

wingetactivetitle, programName
winget, progID, id, %programName%
progPID := errorlevel

loop, 25
   emptyBar = %EmptyBar%%volBarEmpty%
exit

Display:
currentSound := VA_GetVolume("master", "")
tooltip, Volume (%currentSound%`%): %curr%

presstime = %a_mday%%a_hour%%a_min%%a_sec%
presstime += 2
settimer, splashOff, On
return

ctrl_bn_volume:
g_buttonDown(1, "")

if ctrl_bn_volume = 1
{
   VA_SetMute(1)
   currentSound := VA_GetMasterVolume()
   toolTipmessage = Unmute volume (at %currentSound%`%)
   g_tooltipControl("" , toolTipmessage)
}
   
else
{
   VA_SetMute(0)
   g_tooltipControl("", "Mute volume")
}
return

volumeUp:
currentSound := VA_GetMasterVolume()
currentSound += 1
VA_SetMasterVolume(currentSound) ; Send {Volume_Up 2}

mark = 0
curr = %emptyBar%

loop
{
   mark += 1
   if mark <= %currentSound%
      stringreplace, curr, curr, %volBarEmpty%, %volBarFull%
   else
      break
}

gosub, display
return


volumeDn:
currentSound := VA_GetMasterVolume()
currentSound -= 1
VA_SetMasterVolume(currentSound)

mark = 0
curr = %emptyBar%

loop
{
   mark += 1
   if mark <= %currentSound%
      stringreplace, curr, curr, %volBarEmpty%, %volBarFull%
   else
      break
}

gosub, display
return


Its a bit messy becuase i cut in halfway through the script. Any suggestions?

Many thanks


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 10:16 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Perhaps this line:
Code:
currentSound := VA_GetVolume("master", "")
On my system, there aren't any volume interfaces with "master" in the name. The master volume interface is called "Speakers". You should probably be using VA_GetMasterVolume(), anyway.

It's probably unrelated, but I guess this:
Code:
winget, progID, id, %programName%
progPID := errorlevel
is meant to be:
Code:
winget, progID, id, %programName%
winget, progPID, PID, %programName%


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 1:06 pm 
Offline

Joined: October 3rd, 2007, 9:32 pm
Posts: 157
Location: UK
Cheers. Yeah the PID thing was a bit left over from a deleted section. I did another test using the exact same test script with currentSound := VA_GetMasterVolume() instead of VA_GetVolume() and got a set of perfect results. I think you've fixed the problem - just probably something a bit dodgy with my script - ill check it out.

Many thanks.


Last edited by tuna on October 6th, 2007, 1:17 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 1:14 pm 
Offline

Joined: October 3rd, 2007, 9:32 pm
Posts: 157
Location: UK
After a fine comb i think the suspect is

Code:
setformat, float, 0.0


when i remove it from the autoexcecute section, i seem to get a correct value with VA_GETMASTERVOLUME() (though va_getvolume() still doesnt seem to work).

...just in case anyone else is having similar problems.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 6th, 2007, 1:48 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
tuna wrote:
After a fine comb i think the suspect is
Code:
setformat, float, 0.0
Yes, that would do it. VA_GetMasterVolume() retrieves a floating-point value between 0.0 and 1.0. With SetFormat,Float,0.0, this value would be set to either 0 or 1 when it is stored in a variable (since DecimalPlaces is 0.) The return value is volume*100, which would be 0 or 100 (but never something in between.)
Quote:
(though va_getvolume() still doesnt seem to work).
If it doesn't work at all: Specifying "master" as the component (as in your previous post) is not likely to work; "Speakers" is the name you need. (For mute it is "Master Mute", or a substring like "master".) I explained this in my original post and again in the comments of the script. If the device topology script shows "master" in the VOLUME SUBINITS list, it should work (and you should disregard what I just said.)

If the component name isn't the issue, please be more specific as to the expected and actual effects of VA_GetVolume() in your script.

If it is reporting values that don't match the volume mixer: it isn't supposed to, as previously explained.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 11th, 2007, 6:09 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
New feature:
Detect when sound is playing through the default output device.

Example script:
Code:
COM_CoInitialize()
if peakMeter := VA_GetDefaultAudioMeter()
{
    Loop {
        if GetKeyState("End")
            break
        ToolTip % VA_GetPeakValue(peakMeter)  ; display peak value since last call
        Sleep, 100
    }
    COM_Release(peakMeter)
} else
    MsgBox Failed to get peak meter.
COM_CoUninitialize()

(Be sure to update to the latest version of VA.ahk first.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 10th, 2007, 6:29 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Hey this works great without needing UAC access!

To clarify, this will only work in Vista, right?

I currently run this if A_OSVersion = WIN_VISTA and run SoundSet otherwise, but I just want to make sure that's necessary.

Thanks for the great functions!

Edit: Maybe I spoke too soon. I seem to be having trouble now with VA_GetMasterVolume returning a blank value. It worked at first, and oddly enough, just stopped working on subsequent script runs.

Edit 2: Now it works again. Hmm. Perhaps just some odd Vista behavior. Seems fine now though.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 1:07 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
bmcclure wrote:
To clarify, this will only work in Vista, right?
Unfortunately, that is correct.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 1:32 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Here's an OS-independent function that lets you increment, set, or mute/unmute the master volume. It uses SoundGet/SoundSet or your functions, depending on OS type.
Code:
SetVol(pSetVol="") {
   If (pSetVol="") {
      curMute := (A_OSVersion = "WIN_VISTA") ? VA_GetMasterMute() : SoundGet("","Mute")
      If (curMute = "On" or curMute = "Off")
         curMute := (curMute = "On") ? 1 : 0
      pSetVol := curMute ? "u" : "m"
   }
   If (SubStr(pSetVol,1,1) = "m") {
      If (A_OSVersion = "WIN_VISTA")
         VA_SetMasterMute(1)
      Else SoundSet,% 1,,Mute
      return "Muted"
   } Else If (SubStr(pSetVol,1,1) = "u") {
      If (A_OSVersion = "WIN_VISTA")
         VA_SetMasterMute(0)
      Else SoundSet,% 0,,Mute
      return "Unmuted"
   } Else {
      curVol := Transform("Round", (A_OSVersion = "WIN_VISTA") ? VA_GetMasterVolume() : SoundGet())
      If (SubStr(pSetVol,1,1) = "+") {
         newVol := ((curVol + SubStr(pSetVol,2)) > 100) ? 100 : curVol + SubStr(pSetVol,2)
      } Else If (SubStr(pSetVol,1,1) = "-") {
         newVol := ((curVol - SubStr(pSetVol,2)) < 0) ? 0 : curVol - SubStr(pSetVol,2)
      } Else If (pSetVol <= 100 and pSetVol >= 0){
         newVol := pSetVol
      } Else Return "Error"
      If (A_OSVersion = "WIN_VISTA")
         VA_SetMasterVolume(newVol)
      Else SoundSet %newVol%
      Return newVol
   }
}


Note: requires Titan's AHK functions and SoundGet and Transform. Otherwise it can be easily modified to use AHK's base commands

Pass nothing to toggle mute on and off - SetVol()
Pass "u" or "m" or "unmute" or "mute" to unmute or mute - SetVol("m")
Pass a +num or -num to increment the volume - SetVol("-5")
Pass a number between 1 and 100 to set the volume - SetVol(75)

Function will return either the new volume, "Muted"/"Unmuted", or "Error"

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 151 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: nothing, toddintr, Yahoo [Bot] and 22 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group