INT CMixer::ProcessLine(BOOL bIsSet, UINT iCardIndex, DWORD dwType,LPVOID paDetails,DWORD cbDetails,long *plMin,long *plMax)
{
MMRESULT rc; // Return code.
HMIXER hMixer; // Mixer handle used in mixer API calls.
MIXERCONTROL mxc; // Holds the mixer control data.
MIXERLINE mxl; // Holds the mixer line data.
MIXERLINECONTROLS mxlc; // Obtains the mixer control.
// Open the mixer. This opens the mixer with a deviceID of 0. If you
// have a single sound card/mixer, then this will open it. If you have
// multiple sound cards/mixers, the deviceIDs will be 0, 1, 2, and
// so on.
rc = mixerOpen(&hMixer, iCardIndex,0,0,0);
if (MMSYSERR_NOERROR != rc) { // Couldn't open the mixer.
mixerClose(hMixer);
return 1;
}
// Initialize MIXERLINE structure.
ZeroMemory(&mxl,sizeof(mxl));
mxl.cbStruct = sizeof(mxl);
// Specify the line you want to get. You are getting the input line
// here. If you want to get the output line, you need to use
// MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT.
mxl.dwComponentType = dwType;
rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE);
if (MMSYSERR_NOERROR != rc) { // Couldn't get the mixer line.
mixerClose(hMixer);
return 2;
}
// Get the control.
ZeroMemory(&mxlc, sizeof(mxlc));
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeof(mxc);
mxlc.pamxctrl = &mxc;
ZeroMemory(&mxc, sizeof(mxc));
mxc.cbStruct = sizeof(mxc);
rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,
MIXER_GETLINECONTROLSF_ONEBYTYPE);
if (MMSYSERR_NOERROR != rc) { // Couldn't get the control.
mixerClose(hMixer);
return 3;
}
if (plMin) *plMin = mxc.Bounds.lMinimum;
if (plMax) *plMax = mxc.Bounds.lMaximum;
// After successfully getting the peakmeter control, the volume range
// will be specified by mxc.Bounds.lMinimum to mxc.Bounds.lMaximum.
MIXERCONTROLDETAILS mxcd; // Gets the control values.
// Initialize the MIXERCONTROLDETAILS structure
ZeroMemory(&mxcd, sizeof(mxcd));
mxcd.cbStruct = sizeof(mxcd);
mxcd.cbDetails = cbDetails;
mxcd.dwControlID = mxc.dwControlID;
mxcd.paDetails = paDetails;
mxcd.cChannels = 1;
// Get the current value of the peakmeter control. Typically, you
// would set a timer in your program to query the volume every 10th
// of a second or so.
if (bIsSet)
{
rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
if (MMSYSERR_NOERROR != rc) { // Couldn't get the current volume.
mixerClose(hMixer);
return 4;
}
}
else
{
rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
if (MMSYSERR_NOERROR != rc) { // Couldn't get the current volume.
mixerClose(hMixer);
return 5;
}
}
return 0;
}
STDMETHODIMP CMixer::GetMicVolume(short iCardIndex, long *plVolume, long *plMin, long *plMax)
{
// TODO: Add your implementation code here
MIXERCONTROLDETAILS_SIGNED volStruct;
INT iRet = ProcessLine(FALSE,iCardIndex,
MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,
&volStruct,sizeof(volStruct),plMin,plMax);
*plVolume = volStruct.lValue;
if (iRet)
return S_FALSE;
else
return S_OK;
}
STDMETHODIMP CMixer::SetMicVolume(short iCardIndex, long lVolume)
{
// TODO: Add your implementation code here
MIXERCONTROLDETAILS_SIGNED volStruct;
volStruct.lValue = lVolume;
INT iRet = ProcessLine(TRUE,iCardIndex,
MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,
&volStruct,sizeof(volStruct));
if (iRet)
return S_FALSE;
else
return S_OK;
}
STDMETHODIMP CMixer::GetWaveoutVolume(short iCardIndex, long *plVolume, long *plMin, long *plMax)
{
// TODO: Add your implementation code here
MIXERCONTROLDETAILS_SIGNED volStruct;
INT iRet = ProcessLine(FALSE,iCardIndex,
MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
&volStruct,sizeof(volStruct),plMin,plMax);
*plVolume = volStruct.lValue;
if (iRet)
return S_FALSE;
else
return S_OK;
}
STDMETHODIMP CMixer::SetWaveoutVolume(short iCardIndex, long lVolume)
{
// TODO: Add your implementation code here
MIXERCONTROLDETAILS_SIGNED volStruct;
volStruct.lValue = lVolume;
INT iRet = ProcessLine(TRUE,iCardIndex,
MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
&volStruct,sizeof(volStruct));
if (iRet)
return S_FALSE;
else
return S_OK;
}