Reprint--Adjust the audio settings of the control Panel with the mixer API function

Source: Internet
Author: User

keywords : mixer function, control Panel, audio device adjustment

If you have used Windows Audio devices, such as playing music or recording, chatting, adjusting the size of the microphone or sound, and setting the mute, you can adjust it through the Audio Settings panel in the Control Panel, and you must be familiar with the following two settings panels.

The Control Panel adjusts the volume and left and right channels while playing, and it can also mute a device.


Figure 1


The other is the control panel when recording, where we can select the sound input device and adjust the left and right channel volume when recording


Figure 2


The two dashboards are provided to us by Windows, and the two dashboards are for Windows users to tune the audio device when playing a sound or recording, through which we can choose to play or record the audio device, set the volume size, adjust the left and right channels. But if we develop our own program to use this function, such as the program you developed to provide users with a tuning audio device interface, you can make it easy to use the functions provided by your program to adjust and select the appropriate audio equipment, rather than every time to go to the System Control Panel to adjust them, When the user adjusts the device through the interface we provide, the audio device settings in the Control Panel of the system are changed accordingly, and when the user adjusts the audio settings through the System Control Panel, the corresponding changes will also occur in the interface of our program. I recently encountered this problem in the development process, through a careful review of MSDN and other materials, finally solved the problem, I will summarize my experience, if you also encounter similar problems, hope to be helpful to you.

How to control any audio output and input in the system, such as audio output such as waveform audio, MIDI, CD audio, synthetic voice, and lines in, Mike, etc., Windows provides us with a set of API interface functions called Mixer series functions, mixer also known as mixers, Mixing and volume control can be achieved with the mixer. The most basic mixer structure unit is the audio line, such as microphone, lines in, Cd,midi, etc. are all an audio line. An audio line consists of one or more channels that originate from a single source or system resource, for example, a stereo audio line has two channels, but is still considered an audio line because it originates from a sound source.

The following I would like to briefly introduce the mixer function, in fact, anyway, there are not a few, the use is very simple.

Mixeropen
Mixerclose
Mixergetdevcaps
Mixergetlinecontrols
Mixergetlineinfo
Mixergetcontroldetails
Mixersetcontroldetails
Mixergetid
Mixergetnumdevs

See, just so simple a few functions, through these 9 APIs, we can control the audio input and output devices, in fact, about the definition of these functions you can C:\Program Files\Microsoft Visual Studio\vc98\ Found in the include\mmsystem.h file. Here's a brief introduction to these functions, which you can see in detail in MSDN.

The Mixeropen and Mixerclose functions are used to turn the mixer device on and off

Mixergetnumdevs can determine how many mixer devices are in the system

The Mixergetdevcaps function can determine the capabilities of the mixer device

Mixergetlineinfo can retrieve information for a specified audio line

Mixergetlinecontrols Common information used to retrieve one or more controls associated with an audio line

Mixergetcontroldetails used to retrieve the properties of a control associated with an audio line

The mixersetcontroldetails is used to set the properties of the development control.

In fact, we mainly use the back of the four functions, I hope you focus on the study. The mixer also provides a window callback service, when the user calls Mixeropen, a window handle can be passed as a parameter to mixer, so that when the mixer device changes, the callback window will be sent a message notification, such as the user through the control Panel to adjust the size of the volume, Or select a recording device. The type of message is two Mm_mixm_line_change and Mm_mixm_control_change.

Here's not much to say, I use an example to show you how to set up the audio device in the program, first look at the interface of the example I provided


Figure 3


Here to play and recording I have just selected a few common equipment, of course, the system provides more equipment than I used to use the device, you can according to the method I provide to control other devices. Also note that there are two sliders for the left and right channels. But there is only one channel like a microphone.

Through our program interface we can adjust the volume of the left and right channels as in the Control Panel, and select a device for recording, or mute an audio line, the corresponding system settings will be changed, if you set through the system's control Panel, In our program interface also synchronized can reflect the changes.

      about engineering I'm not much, it's simple, it's a dialog-based project with some controls on it. Let me focus on how each feature is implemented. There are three main features 1 how to adjust the left and right channel volume, 2 How to mute a device, 3 how to select the recording device.

Here's a few words about the use of the mixer function. In general, the operation of the audio line is as follows:

1, get information about the specified audio line through Getlineinfo, return a mixerline structure

2, The general information about the control of the audio line is then obtained through the Getlinecontrol, which is returned through the Mixercontrol structure.

3, gets the property value of the specified control through Getconroldetails

4, the property value specified by the Setcontroldetails setting,

for each line device, the mixer is marked with a type value , for example:

Volume The value of Mixerline_componenttype_dst_speakers

CD for the value mixerline_componenttype_src_ Compactdisc

Midi corresponds to a value of Mixerline_componenttype_src_synthesizer

Wave with a value of mixerline_componenttype_ Src_waveout

Line in corresponds to a value of mixerline_componenttype_src_line

microphone corresponding to Mixerline_componenttype_ Src_microphone

We can obtain information about the corresponding line by the type value of the audio line, or the device ID of the audio line to obtain the corresponding line information. Let's start programming under

.

First defines three variables

UINT M_umxid; ID of the mixer
HWND m_hwnd; Callback Window Handle
Hmixer m_hmx; //


Then it is to open mixer, which can be done in the initialization of the conversation.

#define Max_vol_value 65535
if (mmsyserr_noerror! = Mixeropen (&M_HMX, M_umxid, (DWORD) m_hwnd, 0, Callback_window))
{
return FALSE;
}
if (Mmsyserr_noerror = = Mixergetid ((hmixerobj) m_hmx, &m_umxid, Mixer_objectf_hmixer))
{
return M_UMXID;
}
Set the range of the Volume slider this is only the case of volume.
M_sliderwavel.setrange (0, Max_vol_value, TRUE);
M_sliderwaver.setrange (0, Max_vol_value, TRUE);


Then I'll show you how to get and set the volume value of the left and right channel of the recording device, and how to mute the playback device, here in volume for example, other devices similar, you can follow my code, apply.

1. How to get the volume size of volume device

DWORD Dwlvalue;
DWORD Dwrvalue;
Getvolume (Mixerline_componenttype_dst_speakers, &dwlvalue,&dwrvalue);
The definition of the Getvolume function is shown below, and the position of the slider is adjusted according to the value returned
M_slidervolr.setpos (Max_vol_value-dwlvalue);
M_slidervoll.setpos (Max_vol_value-dwrvalue);


2, how to adjust the size of the system volume according to the position of the slider bar

void Cmixercontroldlg::onvscroll (UINT nsbcode, uint NPos, cscrollbar* Pscrollbar)
{
M_DWSPKR and M_DWSPKL are used to record the volume value of the volume left and right channels, 0~~65535
CSliderCtrl *pslider = (CSliderCtrl *) Pscrollbar;
int nvalue = Max_vol_value-pslider->getpos (); Get the position of the slider POS
else if (M_slidervolr.m_hwnd = = Pslider->m_hwnd)
{
If you are dragging the left channel of the volume
M_DWSPKR = Nvalue;
Set the volume value of the volume
SetVolume (Mixerline_componenttype_dst_speakers, M_DWSPKL, M_DWSPKR);
}
else if (M_slidervoll.m_hwnd = = Pslider->m_hwnd)
{
Volume Right Channel
M_DWSPKL = Nvalue;
Set the volume value of the volume
SetVolume (Mixerline_componenttype_dst_speakers, M_DWSPKL, M_DWSPKR);
}
Other audio lines can be added below, in turn
}


The definitions of the Getvolume and SetVolume functions are given below

BOOL Cmixer::setvolume (DWORD Dwsrctype, DWORD Dwlvalue, DWORD Dwrvalue, BOOL Bmono)
{
Mixerline MXL;
if (! Getlineinfo (&MXL, Mixerline_componenttype_dst_speakers, Dwsrctype))
return FALSE;

Mixercontrol MXC;
if (! Getlinecontrol (&MXC, &MXL, Mixercontrol_controltype_volume))
return FALSE;

Mixercontroldetails Mxcd;
Mixercontroldetails_unsigned mxcd_u1;
Mixercontroldetails_unsigned mxcd_u[2];

mxcd.cbstruct = sizeof (MXCD);
Mxcd.dwcontrolid = Mxc.dwcontrolid;
Mxcd.cmultipleitems = 0;

if (Bmono)
{
Mxcd.cchannels = 1;
mxcd.cbdetails = sizeof (MXCD_U1);
Mxcd.padetails = &mxcd_u1;
Mxcd_u1.dwvalue = Dwlvalue;
}
Else
{
Mxcd.cchannels = Mxl.cchannels;
mxcd.cbdetails = sizeof (*mxcd_u);
Mxcd.padetails = Mxcd_u;
Mxcd_u[0].dwvalue = Dwlvalue;
Mxcd_u[1].dwvalue = Dwrvalue;
}

if (! Setcontroldetails (&mxcd, Mixer_objectf_mixer))
return FALSE;

return TRUE;
}

BOOL Cmixer::getvolume (DWORD dwsrctype, dword* pdwlvalue, dword* pdwrvalue, bool Bmono)
{
Mixerline MXL;
if (! Getlineinfo (&MXL, Mixerline_componenttype_dst_speakers, Dwsrctype))
return FALSE;

Mixercontrol MXC;
if (! Getlinecontrol (&MXC, &MXL, Mixercontrol_controltype_volume))
return FALSE;

Mixercontroldetails Mxcd;
Mixercontroldetails_unsigned mxcd_u1;
Mixercontroldetails_unsigned mxcd_u[2];

mxcd.cbstruct = sizeof (MXCD);
Mxcd.dwcontrolid = Mxc.dwcontrolid;
Mxcd.cmultipleitems = 0;

if (Bmono)
{
Mxcd.cchannels = 1;
mxcd.cbdetails = sizeof (MXCD_U1);
Mxcd.padetails = &mxcd_u1;

if (! Getcontroldetails (&mxcd, Mixer_getcontroldetailsf_value))
return FALSE;

*pdwlvalue = Mxcd_u1.dwvalue;
}
Else
{
Mxcd.cchannels = Mxl.cchannels;
mxcd.cbdetails = sizeof (*mxcd_u);
Mxcd.padetails = Mxcd_u;

if (! Getcontroldetails (&mxcd, Mixer_getcontroldetailsf_value))
return FALSE;

*pdwlvalue = Mxcd_u[0].dwvalue;
*pdwrvalue = Mxcd_u[1].dwvalue;
}
return TRUE;
}


BOOL Getlineinfo (Lpmixerline Pmxl, DWORD Dwdsttype, DWORD Dwsrctype)
{
Mixercaps Mxcaps;
if (! Getdevcaps (&mxcaps))
return FALSE;

UINT u=0;
Do
{
pmxl->cbstruct = sizeof (*PMXL);
pmxl->dwdestination = u;
u++;
if (mmsyserr_noerror! = Mixergetlinecontrols ((hmixerobj) M_umxid, PMXL, mixer_getlineinfof_destination))
{
return FALSE;
}

} while ((U < mxcaps.cdestinations) && (pmxl->dwcomponenttype! = Dwdsttype));

if (U > Mxcaps.cdestinations)
return FALSE;

if (Dwdsttype = = Dwsrctype)
return TRUE;

pmxl->dwdestination = u;
UINT cconnections = (UINT) pmxl->cconnections;

UINT v=0;
u--;
Do
{
pmxl->cbstruct = sizeof (*PMXL);
pmxl->dwdestination = u;
Pmxl->dwsource = v;
v++;

if (mmsyserr_noerror! = Mixergetlinecontrols ((hmixerobj) M_umxid, PMXL, Mixer_getlineinfof_source))
{
return FALSE;
}
} while ((v < cconnections) && (pmxl->dwcomponenttype! = Dwsrctype));

if (V > cconnections) | | (Pmxl->dwcomponenttype!=dwsrctype))
return FALSE;

return TRUE;
}

BOOL Getlinecontrol (Lpmixercontrol pmxc, Lpmixerline pmxl, DWORD dwtype)
{
Lpmixercontrol Pamxctrl;
DWORD cbmxctrls = sizeof (*pamxctrl) * (UINT) pmxl->ccontrols;
Pamxctrl = (Lpmixercontrol) LocalAlloc (LPTR, cbmxctrls);

Mixerlinecontrols mxlc;
mxlc.cbstruct = sizeof (MXLC);
Mxlc.dwlineid = pmxl->dwlineid;
Mxlc.dwcontroltype = dwtype;
Mxlc.ccontrols = pmxl->ccontrols;
Mxlc.cbmxctrl = sizeof (*pamxctrl);
Mxlc.pamxctrl = Pamxctrl;

if (mmsyserr_noerror! = Mixergetcontroldetails ((hmixerobj) M_umxid, &AMP;MXLC, Mixer_getlinecontrolsf_onebytype))
{
return FALSE;
}
memcpy (PMXC, Pamxctrl, sizeof (*pamxctrl));
LocalFree (Pamxctrl);
return TRUE;
}

3, the following shows how to set the volume device mute

Here are two functions, Getmute used to get the system setup to mute an audio line, Setmute is used to mute an audio line of the system.

BOOL Cmixer::setmute (DWORD Dwsrctype, bool bValue)
{
Mixerline MXL;
if (! Getlineinfo (&AMP;MXL, Mixerline_componenttype_dst_speakers, Dwsrctype))
return FALSE;

Mixercontrol MXC;
if (! Getlinecontrol (&AMP;MXC, &AMP;MXL, Mixercontrol_controltype_mute))
return FALSE;

Mixercontroldetails Mxcd;
Mixercontroldetails_boolean Mxcd_f;

mxcd.cbstruct = sizeof (MXCD);
Mxcd.dwcontrolid = Mxc.dwcontrolid;
Mxcd.cchannels = 1;
Mxcd.cmultipleitems = 0;
mxcd.cbdetails = sizeof (Mxcd_f);
Mxcd.padetails = &mxcd_f;
 
Mxcd_f.fvalue = BValue;

if (! Setcontroldetails (&mxcd, Mixer_objectf_mixer))
return FALSE;

return TRUE;
}

BOOL Cmixer::getmute (DWORD dwsrctype, bool* pbvalue)
{
Mixerline MXL;
if (! Getlineinfo (&AMP;MXL, Mixerline_componenttype_dst_speakers, Dwsrctype))
return FALSE;

Mixercontrol MXC;
if (! Getlinecontrol (&AMP;MXC, &AMP;MXL, Mixercontrol_controltype_multipleselect))
return FALSE;

Mixercontroldetails Mxcd;
Mixercontroldetails_boolean Mxcd_f;

mxcd.cbstruct = sizeof (MXCD);
Mxcd.dwcontrolid = Mxc.dwcontrolid;
Mxcd.cchannels = 1;
Mxcd.cmultipleitems = 0;
mxcd.cbdetails = sizeof (Mxcd_f);
Mxcd.padetails = &mxcd_f;

if (! Getcontroldetails (&mxcd, Mixer_getcontroldetailsf_value))
return FALSE;

*pbvalue = Mxcd_f.fvalue;

return TRUE;
}


If I use these two functions, I'll show you how to set and get the mute operation of the volume audio line.

BOOL bValue = TRUE;
Setmute (Mixerline_componenttype_dst_speakers, BValue);
Getmute (Mixerline_componenttype_dst_speakers, &bvalue);


4, the following to see when the system settings change, mixer is how to inform us.

Remember what I said earlier, when we call Mixeropen, we can pass a window handle as a callback window, and when the system's settings change, such as the volume changes, when an audio line is muted, mixer will send a message to our callback window.

Generally there are only two messages, as follows

afx_msg void Onmlchange (WPARAM WPARAM, LPARAM LPARAM);
afx_msg void Onmcchange (WPARAM WPARAM, LPARAM LPARAM);

On_message (Mm_mixm_line_change, Onmlchange)
On_message (Mm_mixm_control_change, Onmcchange)


In the Mm_mixm_control_change message, the two parameters that send the message represent the following meaning

WParam = (WParam) hmixer
LParam = (LParam) dwcontrolid


In the Mm_mixm_line_change message, the parameter that sends the message represents the following meaning

WParam = (WParam) hmixer
LParam = (LParam) Dwlineid


In our application, we can adjust our settings in these two message handlers to correspond to changes in the system, such as your code can write:

void Cmixercontroldlg::onmcchange (WPARAM WPARAM, LPARAM LPARAM)
{
DWORD Dwlvalue;
DWORD Dwrvalue;
Getvolume (Mixerline_componenttype_dst_speakers, &dwlvalue,&dwrvalue);
The definition of the Getvolume function is shown below, and the position of the slider is adjusted according to the value returned
M_slidervolr.setpos (Max_vol_value-dwlvalue);
M_slidervoll.setpos (Max_vol_value-dwrvalue);
You can also call Getmute here to see if volume is muted,
}


So your program can automatically respond to changes in system settings.

About Mixer API application development is introduced here, remember the last to close mixer so: Mixerclose (M_HMX);

Reprint--Adjust the audio settings of the control Panel with the mixer API function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.