User Tools

Site Tools


Controlling the audio mixer

by Richard Russell, July 2007

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 controlled is that for the specific application.

The main BBC BASIC for Windows help documentation describes how to control the wave output volume but this is just one of the volume controls usually provided by the audio mixer (accessed by double-clicking on the loudspeaker icon in the system tray). Typically you can independently control the volume of Wave, Synth and CD outputs and the level of CD, Microphone and Line inputs (and often several others). You can also mute selected outputs and select which input to use for recording.

The FN_mixerset routine listed at the end of this article allows you to control the audio mixer from your BBC BASIC program. The routine should be called using code similar to the following:

        ok% = FN_mixerset(Dest%, Source%, Control%, Setting%)

The routine returns TRUE if the control was set successfully and FALSE if not.

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), Mute (= &20010002) or Mux (= &70010001).
  • “Setting%“ - A value in the range 0-65535 for Volume, a value in the range 0-1 for Mute or the required source selection for Mux.

For other possible values consult the Microsoft documentation.

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

        ok% = FN_mixerset(7, &1003, &50030001, 32768)

To set the CD Player output volume to one-quarter:

        ok% = FN_mixerset(4, &1005, &50030001, 16384)

To mute the Line input:

        ok% = FN_mixerset(4, &1002, &20010002, 1)

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

        ok% = FN_mixerset(4, 0, &50030001, 65535)

Finally here is the code for FN_mixerset itself:

        DEF FN_mixerset(dest%, source%, type%, setting%)
        LOCAL hmx%, res%, ndevs%, dev%, src%, ok%, 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"
        FOR dev% = 0 TO ndevs%-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
            ok% OR= FN_controlset(hmx%, MixerLine.dwLineID%, type%, setting%)
            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
                ok% OR= FN_controlset(hmx%, MixerLine.dwLineID%, type%, setting%)
            NEXT src%
          SYS "mixerClose", hmx%
        NEXT dev%
        = ok%
        DEF FN_controlset(hmx%, id%, type%, setting%)
        LOCAL 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% = type%
        MixerLineControls.cControls% = 1
        MixerLineControls.cbmxctrl% = DIM(MixerControl{})
        MixerLineControls.pamxctrl% = MixerControl{}
        SYS "mixerGetLineControls", hmx%, MixerLineControls{}, \
        \                           MIXER_GETLINECONTROLSF_ONEBYTYPE TO res%
        IF res% THEN = FALSE
        MixerControlDetailsData.dwValue% = setting%
        MixerControlDetails.cbStruct% = DIM(MixerControlDetails{})
        MixerControlDetails.dwControlID% = MixerControl.dwControlID%
        MixerControlDetails.cChannels% = 1
        MixerControlDetails.cbDetails% = DIM(MixerControlDetailsData{})
        MixerControlDetails.paDetails% = MixerControlDetailsData{}
        SYS "mixerSetControlDetails", hmx%, MixerControlDetails{}, \
        \                             MIXER_SETCONTROLDETAILSF_VALUE TO res%
        IF res% ERROR 100, "mixerSetControlDetails failed"
        = TRUE
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
controlling_20the_20audio_20mixer.txt · Last modified: 2018/04/15 12:48 by richardrussell