Sound Functions

Applies to:

Other sound-related functions:

Endpoint Devices

The "devices" referenced by the SoundGet and SoundSet functions are audio endpoint devices. A single device driver or physical device often has multiple endpoints, such as for different types of output or input. For example:

NameDescription
Speakers (Example HD Audio)The main analog outputs of this device (uses multiple jacks in the case of surround sound).
Digital Output (Example HD Audio)An optical or coaxial digital output.
Microphone (Example HD Audio)Captures audio through a microphone jack.
Stereo Mix (Example HD Audio)Captures whatever audio is being output to the Speakers endpoint.

Device names typically consist of an endpoint name such as "Speakers" followed by the name of the audio driver in parentheses. Scripts may use the full name or just the leading part of the name, such as "Mic" or "Microphone". An audio driver has a fixed name, but endpoint names may be changed by an administrator at any time via the Sound control panel.

Devices are listed in the Sound control panel, which can be opened by running mmsys.cpl from the command line, or via the Run dialog (Win+R) or the Run function. By default, the control panel only lists devices that are enabled and plugged in (if applicable), but this can be changed via the right-click menu. AutoHotkey detects devices which are not plugged in, but does not detect disabled devices.

Components

Components are as shown on the Levels tab of the sound device's properties dialog.

Levels

In this example, the master controls are at the top, followed by the first four components: Microphone, FrontMic, Line In, and Side. All have volume and mute controls, except the fourth component, which only has volume.

A sound device's properties dialog can be opened via the Sound control panel.

Audio drivers are capable of exposing other controls, such as bass and treble. However, common audio drivers tend to have only volume and mute controls, or no components at all. Volume and mute controls are supported directly through SoundGetVolume, SoundSetVolume, SoundGetMute and SoundSetMute. All other controls are supported only indirectly, through SoundGetInterface and ComCall.

Advanced Details

Components are discovered through the DeviceTopology API, which exposes a graph of Connectors and Subunits. Each component shown above has a Connector, and it is the Connector that defines the component's name. Each control (such as volume or mute) is represented by a Subunit which sits between the Connector and the endpoint. Data "flows" from or to the Connector and is altered as it flows through each Subunit, such as to adjust volume or suppress (mute) all sound.

The SoundGet and SoundSet functions identify components by walking the device topology graph and counting Connectors with the given name (or all Connectors if no name is given). Once the matching Connector is found, a control interface (such as IAudioVolumeLevel or IAudioMute) is retrieved by querying each Subunit on that specific branch of the graph, starting nearest the Connector.

Subunits which apply to multiple Connectors are excluded - such as Subunits which correspond to the master volume and mute controls. A Connector is counted if (and only if) it has at least one Subunit of its own, even if the Subunit is not of the requested type.

In practice, the end result is that the available components are as listed on the Levels tab, and in the same order. However, this process is based on observation, trial and error, so might not be 100 % accurate.

Common Parameters

Component

Type: String or Integer

One of the following:

If only an index is specified, the display names are ignored. For example, 1, "1" and ":1" use the first component regardless of name, whereas "" uses the master controls.

If the sound device lacks the specified Component, a TargetError is thrown.

Device

Type: String or Integer

One of the following:

The soundcard analysis script may help determine which name and/or number to use.

Examples

Soundcard Analysis. Use the following script to discover the available audio device and component names and whether each device or component supports volume and/or mute controls. It displays the results in a simple ListView. The current volume and mute settings are shown if they can be retrieved, but are not updated in realtime.

scGui := Gui(, "Sound Components")
scLV := scGui.Add('ListView', "w600 h400"
    , ["Component", "#", "Device", "Volume", "Mute"])

devMap := Map()

loop
{
    ; For each loop iteration, try to get the corresponding device.
    try
        devName := SoundGetName(, dev := A_Index)
    catch  ; No more devices.
        break
    
    ; Qualify names with ":index" where needed.
    devName := Qualify(devName, devMap, dev)
    
    ; Retrieve master volume and mute setting, if possible.
    vol := mute := ""
    try vol := Round(SoundGetVolume( , dev), 2)
    try mute := SoundGetMute( , dev)
    
    ; Display the master settings only if at least one was retrieved.
    if vol != "" || mute != ""
        scLV.Add("", "", dev, devName, vol, mute)
    
    ; For each component, first query its name.
    cmpMap := Map()
    
    loop
    {
        try
            cmpName := SoundGetName(cmp := A_Index, dev)
        catch
            break
        ; Retrieve this component's volume and mute setting, if possible.
        vol := mute := ""
        try vol := Round(SoundGetVolume(cmp, dev), 2)
        try mute := SoundGetMute(cmp, dev)
        ; Display this component even if it does not support volume or mute,
        ; since it likely supports other controls via SoundGetInterface().
        scLV.Add("", Qualify(cmpName, cmpMap, A_Index), dev, devName, vol, mute)
    }
}

loop 5
    scLV.ModifyCol(A_Index, 'AutoHdr Logical')
scGui.Show()

; Qualifies full names with ":index" when needed.
Qualify(name, names, overallIndex)
{
    if name = ''
        return overallIndex
    key := StrLower(name)
    index := names.Has(key) ? ++names[key] : (names[key] := 1)
    return (index > 1 || InStr(name, ':') || IsInteger(name)) ? name ':' index : name
}