User Tools

Site Tools


Interrogating the audio mixer

by Richard Russell, June 2010

Note: On Windows Vista and Windows 7 each running application has its own independent audio mixer. The code listed here will work correctly, but the mixer interrogated is that for the specific application.

The article Controlling the audio mixer explains how to control the volume of Wave, Synth and CD outputs and the level of CD, Microphone and Line inputs (and often several others) using the FN_mixerset routine. The FN_mixerget function listed at the end of this article allows you to interrogate the settings of the various mixer controls. The function should be called using code similar to the following:

        setting% = FN_mixerget(Dest%, Source%, Control%)

The routine returns the current setting of the control (typically 0-65535 for Volume).

The parameters are as follows:

  • “Dest%“ - The destination for the control, which will generally be either the Speaker Output (= 4) or the Recording Input (= 7).
  • “Source%“ - The audio source for the control, for example the Line Input (= &1002), Microphone (= &1003), Synthesizer (= &1004), CD (= &1005) or Wave Output (= &1008).
  • “Control%“ - The control type, which will generally be Volume (= &50030001).

For other possible values consult the Microsoft documentation.

So for example to interrogate the Microphone recording level you could use code like this:

        miclevel% = FN_mixerget(7, &1003, &50030001)

To read the CD Player output volume:

        cdvolume% = FN_mixerget(4, &1005, &50030001)

To read a Master Volume setting (which does not have a specific source) set the “Source%“ parameter to zero. So to discover the Master speaker volume you could do:

        master% = FN_mixerget(4, 0, &50030001)

Finally here is the code for FN_mixerget itself:

        DEF FN_mixerget(dest%, source%, ctrl%)
        LOCAL hmx%, res%, ndevs%, dev%, src%, level%, MixerLine{}
        DIM MixerLine{cbStruct%, dwDestination%, dwSource%, dwLineID%, fdwLine%, \
        \             dwUser%, dwComponentType%, cChannels%, cConnections%, \
        \             cControls%, szShortName&(15), szName&(63), Target{dwType%, \
        \             dwDeviceID%, wMid{l&, h&}, wPid{l&, h&}, vDriverVersion%, \
        \             szPname&(31)}}
        SYS "mixerGetNumDevs" TO ndevs%
        IF ndevs%=0 ERROR 100, "No audio mixer devices"
        level% = -1
        FOR dev% = ndevs%-1 TO 0 STEP -1
          SYS "mixerOpen", ^hmx%, dev%, 0, 0, MIXER_OBJECTFMIXER TO res%
          IF res% ERROR 100, "mixerOpen failed"
          MixerLine.cbStruct% = DIM(MixerLine{})
          MixerLine.dwComponentType% = dest%
          SYS "mixerGetLineInfo", hmx%, MixerLine{}, \
          \                       MIXER_GETLINEINFOF_COMPONENTTYPE TO res%
          IF res% ERROR 100, "mixerGetLineInfo (destination) failed"
          IF source% = 0 THEN
            level% = FN_controlget(hmx%, MixerLine.dwLineID%, ctrl%)
            FOR src% = 0 TO MixerLine.cConnections%-1
              MixerLine.cbStruct% = DIM(MixerLine{})
              MixerLine.dwSource% = src%
              SYS "mixerGetLineInfo", hmx%, MixerLine{}, \
              \                       MIXER_GETLINEINFOF_SOURCE TO res%
              IF res% ERROR 100, "mixerGetLineInfo (source) failed"
              IF MixerLine.dwComponentType% = source% THEN
                level% = FN_controlget(hmx%, MixerLine.dwLineID%, ctrl%)
            NEXT src%
          SYS "mixerClose", hmx%
        NEXT dev%
        = level%
        DEF FN_controlget(hmx%, id%, ctrl%)
        LOCAL res%, MixerLineControls{}, MixerControl{}
        LOCAL MixerControlDetails{}, MixerControlDetailsData{}
        DIM MixerLineControls{cbStruct%, dwLineID%, dwControl%, cControls%, \
        \                     cbmxctrl%, pamxctrl%}
        DIM MixerControl{cbStruct%, dwControlID%, dwControlType%, fdwControl%, \
        \                cMultipleItems%, szShortName&(15), szName&(63), \
        \                lMinimum%, lMaximum%, dwReserved%(9)}
        DIM MixerControlDetails{cbStruct%, dwControlID%, cChannels%, hwndOwner%, \
        \                       cbDetails%, paDetails%}
        DIM MixerControlDetailsData{dwValue%}
        MixerLineControls.cbStruct% = DIM(MixerLineControls{})
        MixerLineControls.dwLineID% = id%
        MixerLineControls.dwControl% = ctrl%
        MixerLineControls.cControls% = 1
        MixerLineControls.cbmxctrl% = DIM(MixerControl{})
        MixerLineControls.pamxctrl% = MixerControl{}
        SYS "mixerGetLineControls", hmx%, MixerLineControls{}, \
        \                           MIXER_GETLINECONTROLSF_ONEBYTYPE TO res%
        IF res% ERROR 100, "mixerGetLineControls failed"
        MixerControlDetails.cbStruct% = DIM(MixerControlDetails{})
        MixerControlDetails.dwControlID% = MixerControl.dwControlID%
        MixerControlDetails.cChannels% = 1
        MixerControlDetails.cbDetails% = DIM(MixerControlDetailsData{})
        MixerControlDetails.paDetails% = MixerControlDetailsData{}
        SYS "mixerGetControlDetails", hmx%, MixerControlDetails{}, \
        \                             MIXER_GETCONTROLDETAILSF_VALUE TO res%
        IF res% ERROR 100, "mixerGetControlDetails failed"
        = MixerControlDetailsData.dwValue%
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
interrogating_20the_20audio_20mixer.txt · Last modified: 2018/04/15 12:51 by richardrussell