=====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%20the%20audio%20mixer|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{} 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%