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: code format="bb4w" setting% = FN_mixerget(Dest%, Source%, Control%) code The routine returns the current setting of the control (typically 0-65535 for Volume).

The parameters are as follows:


 * ****  - The destination for the control, which will generally be either the **Speaker Output** (= **4**) or the **Recording Input** (= **7**).
 * **** - The audio source for the control, for example the **Line Input** (= **&1002**), **Microphone** (= **&1003**), **Synthesizer** (= **&1004**), **CD** (= **&1005**) or **Wave Output** (= **&1008**).
 * **** - 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: code format="bb4w" miclevel% = FN_mixerget(7, &1003, &50030001) code To read the **CD Player output volume**: code format="bb4w" cdvolume% = FN_mixerget(4, &1005, &50030001) code To read a **Master Volume** setting (which does not have a specific source) set the **** parameter to zero. So to discover the **Master speaker volume** you could do: code format="bb4w" master% = FN_mixerget(4, 0, &50030001) code Finally here is the code for **FN_mixerget** itself: code format="bb4w" DEF FN_mixerget(dest%, source%, ctrl%) LOCAL hmx%, res%, ndevs%, dev%, src%, level%, MixerLine{} MIXER_OBJECTFMIXER = 0 MIXER_GETLINEINFOF_SOURCE = 1 MIXER_GETLINEINFOF_COMPONENTTYPE = 3 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%) ELSE 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%) ENDIF NEXT src% ENDIF SYS "mixerClose", hmx% NEXT dev% = level% DEF FN_controlget(hmx%, id%, ctrl%) LOCAL res%, MixerLineControls{}, MixerControl{} LOCAL MixerControlDetails{}, MixerControlDetailsData{} MIXER_GETLINECONTROLSF_ONEBYTYPE = 2 MIXER_GETCONTROLDETAILSF_VALUE = 0 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% code