486 lines
18 KiB
C++
486 lines
18 KiB
C++
|
/*==========================================================================
|
||
|
*
|
||
|
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* File: MixLine.cpp
|
||
|
* Content: Class for managing the mixerLine API.
|
||
|
*
|
||
|
* History:
|
||
|
* Date By Reason
|
||
|
* ==== == ======
|
||
|
* 11/30/99 rodtoll Created based on source from dsound
|
||
|
* 01/24/2000 rodtoll Mirroring changes from dsound bug #128264
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "dxvutilspch.h"
|
||
|
|
||
|
|
||
|
#undef DPF_SUBCOMP
|
||
|
#define DPF_SUBCOMP DN_SUBCOMP_VOICE
|
||
|
|
||
|
|
||
|
#define DVF_MIXERLINE_PROCEDURE_DEBUG_LEVEL DVF_INFOLEVEL
|
||
|
|
||
|
#define DPFLVL_INFO 5
|
||
|
#define DPF_MIXER DPFX
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::CMixerLine"
|
||
|
CMixerLine::CMixerLine(
|
||
|
): m_fAcquiredVolCtrl(FALSE),
|
||
|
m_pmxMuxFlags(NULL),
|
||
|
m_dwRangeMin(0),
|
||
|
m_dwRangeSize(0xFFFF),
|
||
|
m_uWaveDeviceId(0),
|
||
|
m_pfMicValue(NULL)
|
||
|
{
|
||
|
ZeroMemory( &m_mxcdMasterVol, sizeof( MIXERCONTROLDETAILS ) );
|
||
|
ZeroMemory( &m_mxcdMasterMute, sizeof( MIXERCONTROLDETAILS ) );
|
||
|
ZeroMemory( &m_mxcdMasterMux, sizeof( MIXERCONTROLDETAILS ) );
|
||
|
ZeroMemory( &m_mxcdMicVol, sizeof( MIXERCONTROLDETAILS ) );
|
||
|
ZeroMemory( &m_mxcdMicMute, sizeof( MIXERCONTROLDETAILS ) );
|
||
|
ZeroMemory( &m_mxVolume, sizeof( MIXERCONTROLDETAILS_UNSIGNED ) );
|
||
|
ZeroMemory( &m_mxMute, sizeof( MIXERCONTROLDETAILS_BOOLEAN ) );
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::~CMixerLine"
|
||
|
CMixerLine::~CMixerLine()
|
||
|
{
|
||
|
if( m_pmxMuxFlags != NULL )
|
||
|
{
|
||
|
delete [] m_pmxMuxFlags;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::Initialize"
|
||
|
HRESULT CMixerLine::Initialize( UINT uiDeviceID )
|
||
|
{
|
||
|
if( m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_INITIALIZED;
|
||
|
}
|
||
|
|
||
|
m_uWaveDeviceId = uiDeviceID;
|
||
|
|
||
|
// Set up the master waveIn destination mixer line
|
||
|
MIXERLINE mxMastLine;
|
||
|
ZeroMemory(&mxMastLine, sizeof mxMastLine);
|
||
|
mxMastLine.cbStruct = sizeof mxMastLine;
|
||
|
mxMastLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
|
||
|
|
||
|
// Set up the microphone source line
|
||
|
MIXERLINE mxMicLine;
|
||
|
ZeroMemory(&mxMicLine, sizeof mxMicLine);
|
||
|
|
||
|
// Set up the mixer-line control structure
|
||
|
MIXERCONTROL mxCtrl;
|
||
|
ZeroMemory(&mxCtrl, sizeof mxCtrl);
|
||
|
mxCtrl.cbStruct = sizeof mxCtrl;
|
||
|
|
||
|
// Set up the 1-element array of controls
|
||
|
MIXERLINECONTROLS mxLineCtrls;
|
||
|
ZeroMemory(&mxLineCtrls, sizeof mxLineCtrls);
|
||
|
mxLineCtrls.cbStruct = sizeof mxLineCtrls;
|
||
|
mxLineCtrls.cControls = 1;
|
||
|
mxLineCtrls.cbmxctrl = sizeof mxCtrl;
|
||
|
mxLineCtrls.pamxctrl = &mxCtrl;
|
||
|
|
||
|
// Set up the control details structures
|
||
|
m_mxcdMasterVol.cbDetails = sizeof m_mxVolume;
|
||
|
m_mxcdMasterVol.paDetails = &m_mxVolume;
|
||
|
m_mxcdMasterVol.cChannels = 1;
|
||
|
m_mxcdMasterMute.cbDetails = sizeof m_mxMute;
|
||
|
m_mxcdMasterMute.paDetails = &m_mxMute;
|
||
|
m_mxcdMasterMute.cChannels = 1;
|
||
|
m_mxcdMicVol.cbDetails = sizeof m_mxVolume;
|
||
|
m_mxcdMicVol.paDetails = &m_mxVolume;
|
||
|
m_mxcdMicVol.cChannels = 1;
|
||
|
m_mxcdMicMute.cbDetails = sizeof m_mxMute;
|
||
|
m_mxcdMicMute.paDetails = &m_mxMute;
|
||
|
m_mxcdMicMute.cChannels = 1;
|
||
|
|
||
|
// We use the waveIn device ID instead of a "real" mixer device below
|
||
|
HMIXEROBJ hMixObj;
|
||
|
MMRESULT mmr = mixerGetID((HMIXEROBJ) ((UINT_PTR)m_uWaveDeviceId), (LPUINT)&hMixObj, MIXER_OBJECTF_WAVEIN);
|
||
|
|
||
|
if (MMSYSERR_NOERROR == mmr)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "mixerGetID failed.");
|
||
|
}
|
||
|
|
||
|
// Find the master recording destination line
|
||
|
mmr = mixerGetLineInfo(hMixObj, &mxMastLine, MIXER_GETLINEINFOF_COMPONENTTYPE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found the master recording mixer line");
|
||
|
// Look for a volume fader control on the master line
|
||
|
mxLineCtrls.dwLineID = mxMastLine.dwLineID;
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
// Found it - use the cbStruct field to flag success
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found a volume fader on the master line");
|
||
|
m_mxcdMasterVol.cbStruct = sizeof m_mxcdMasterVol;
|
||
|
m_mxcdMasterVol.dwControlID = mxCtrl.dwControlID;
|
||
|
m_dwRangeMin = mxCtrl.Bounds.dwMinimum;
|
||
|
m_dwRangeSize = mxCtrl.Bounds.dwMaximum - mxCtrl.Bounds.dwMinimum;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMasterVol, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
if (mmr != MMSYSERR_NOERROR)
|
||
|
m_mxcdMasterVol.cbStruct = 0;
|
||
|
|
||
|
// Look for a mute control on the master line
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found a mute control on the master line");
|
||
|
m_mxcdMasterMute.cbStruct = sizeof m_mxcdMasterMute;
|
||
|
m_mxcdMasterMute.dwControlID = mxCtrl.dwControlID;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMasterMute, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
if (mmr != MMSYSERR_NOERROR)
|
||
|
m_mxcdMasterMute.cbStruct = 0;
|
||
|
|
||
|
// Look for the microphone source line
|
||
|
mxMicLine.cbStruct = sizeof mxMicLine;
|
||
|
mxMicLine.dwDestination = mxMastLine.dwDestination;
|
||
|
for (UINT i=0; i < mxMastLine.cConnections; ++i)
|
||
|
{
|
||
|
mxMicLine.dwSource = i;
|
||
|
// Note: for some mysterious reason, I had to remove MIXER_OBJECTF_WAVEIN
|
||
|
// from this call to mixerGetLineInfo() to make it work.
|
||
|
mmr = mixerGetLineInfo(hMixObj, &mxMicLine, MIXER_GETLINEINFOF_SOURCE);
|
||
|
if (mmr != MMSYSERR_NOERROR || mxMicLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
|
||
|
break;
|
||
|
}
|
||
|
if (mxMicLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found a microphone mixer line");
|
||
|
// Look for a volume fader control on the mic line
|
||
|
mxLineCtrls.dwLineID = mxMicLine.dwLineID;
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found a volume fader on the mic line");
|
||
|
m_mxcdMicVol.cbStruct = sizeof m_mxcdMicVol;
|
||
|
m_mxcdMicVol.dwControlID = mxCtrl.dwControlID;
|
||
|
m_dwRangeMin = mxCtrl.Bounds.dwMinimum;
|
||
|
m_dwRangeSize = mxCtrl.Bounds.dwMaximum - mxCtrl.Bounds.dwMinimum;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMicVol, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
if (mmr != MMSYSERR_NOERROR)
|
||
|
m_mxcdMicVol.cbStruct = 0;
|
||
|
|
||
|
// Look for a mute control on the mic line
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found a mute control on the mic line");
|
||
|
m_mxcdMicMute.cbStruct = sizeof m_mxcdMicMute;
|
||
|
m_mxcdMicMute.dwControlID = mxCtrl.dwControlID;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMicMute, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
if (mmr != MMSYSERR_NOERROR)
|
||
|
m_mxcdMicMute.cbStruct = 0;
|
||
|
|
||
|
// Look for a MUX or MIXER control on the master line
|
||
|
mxLineCtrls.dwLineID = mxMastLine.dwLineID;
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;
|
||
|
m_fMasterMuxIsMux = TRUE;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
if (mmr != MMSYSERR_NOERROR)
|
||
|
{
|
||
|
mxLineCtrls.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER;
|
||
|
m_fMasterMuxIsMux = FALSE;
|
||
|
mmr = mixerGetLineControls(hMixObj, &mxLineCtrls, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
}
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Found an item list control on the master line");
|
||
|
m_mxcdMasterMux.cbStruct = sizeof m_mxcdMasterMux;
|
||
|
m_mxcdMasterMux.dwControlID = mxCtrl.dwControlID;
|
||
|
m_mxcdMasterMux.cMultipleItems = mxCtrl.cMultipleItems;
|
||
|
|
||
|
// We save the cChannels value, because some evil VxD drivers (read: Aureal
|
||
|
// Vortex) will set it to 0 in the call to mixerGetControlDetails() below
|
||
|
int nChannels = (mxCtrl.fdwControl & MIXERCONTROL_CONTROLF_UNIFORM) ? 1 : mxMastLine.cChannels;
|
||
|
m_mxcdMasterMux.cChannels = nChannels;
|
||
|
|
||
|
// Get the MUX or MIXER list items
|
||
|
m_mxcdMasterMux.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
|
||
|
MIXERCONTROLDETAILS_LISTTEXT *pList = new MIXERCONTROLDETAILS_LISTTEXT [ m_mxcdMasterMux.cbDetails * m_mxcdMasterMux.cChannels * mxCtrl.cMultipleItems ];
|
||
|
if (pList != NULL)
|
||
|
{
|
||
|
m_mxcdMasterMux.paDetails = pList;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMasterMux, MIXER_GETCONTROLDETAILSF_LISTTEXT);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Got the list controls's LISTTEXT details");
|
||
|
// Get the MUX or MIXER list values
|
||
|
m_mxcdMasterMux.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
|
||
|
m_mxcdMasterMux.cChannels = nChannels;
|
||
|
m_pmxMuxFlags = new MIXERCONTROLDETAILS_BOOLEAN [ m_mxcdMasterMux.cbDetails * m_mxcdMasterMux.cChannels * mxCtrl.cMultipleItems ];
|
||
|
if (m_pmxMuxFlags != NULL)
|
||
|
{
|
||
|
m_mxcdMasterMux.paDetails = m_pmxMuxFlags;
|
||
|
mmr = mixerGetControlDetails(hMixObj, &m_mxcdMasterMux, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
if (mmr == MMSYSERR_NOERROR) // Enable the item corresponding to the mic line
|
||
|
{
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Got the list controls's VALUE details");
|
||
|
for (UINT i=0; i < mxCtrl.cMultipleItems; ++i)
|
||
|
{
|
||
|
if (pList[i].dwParam1 == mxMicLine.dwLineID)
|
||
|
m_pfMicValue = &m_pmxMuxFlags[i].fValue;
|
||
|
else if (mxLineCtrls.dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
|
||
|
m_pmxMuxFlags[i].fValue = FALSE;
|
||
|
DPF_MIXER(DPFPREP, DPFLVL_INFO, "Set list item %d to %d", i, pList[i].dwParam1 == mxMicLine.dwLineID);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
delete[] pList;
|
||
|
pList = NULL;
|
||
|
}
|
||
|
if (!m_pmxMuxFlags || !m_pfMicValue || mmr != MMSYSERR_NOERROR)
|
||
|
m_mxcdMasterMux.cbStruct = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// To be able to control the recording level, we minimally require
|
||
|
// a volume fader on the master line or one on the microphone line:
|
||
|
m_fAcquiredVolCtrl = m_mxcdMasterVol.cbStruct || m_mxcdMicVol.cbStruct;
|
||
|
|
||
|
HRESULT hr = m_fAcquiredVolCtrl ? DS_OK : DSERR_CONTROLUNAVAIL;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::SetMicrophoneVolume"
|
||
|
HRESULT CMixerLine::SetMicrophoneVolume( LONG lMicrophoneVolume )
|
||
|
{
|
||
|
if( !m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_NOTINITIALIZED;
|
||
|
}
|
||
|
|
||
|
MMRESULT mmr = MMSYSERR_NOTSUPPORTED; // Default return code
|
||
|
|
||
|
// Set the microphone recording level control if available
|
||
|
if (m_mxcdMicVol.cbStruct)
|
||
|
{
|
||
|
// Convert the DSBVOLUME level to an amplification factor from 0 to 0xFFFF
|
||
|
m_mxVolume.dwValue = DBToAmpFactor(lMicrophoneVolume);
|
||
|
|
||
|
// Adjust range if necessary
|
||
|
if (m_dwRangeMin != 0 || m_dwRangeSize != 0xFFFF)
|
||
|
m_mxVolume.dwValue = DWORD(m_dwRangeMin + m_dwRangeSize*double(m_mxVolume.dwValue)/0xFFFF);
|
||
|
|
||
|
mmr = mixerSetControlDetails((HMIXEROBJ)((UINT_PTR)m_uWaveDeviceId),
|
||
|
&m_mxcdMicVol, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
|
||
|
HRESULT hr = MMRESULTtoHRESULT(mmr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::GetMicrophoneVolume"
|
||
|
HRESULT CMixerLine::GetMicrophoneVolume( LPLONG plMicrophoneVolume )
|
||
|
{
|
||
|
if( !m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_NOTINITIALIZED;
|
||
|
}
|
||
|
|
||
|
MMRESULT mmr = MMSYSERR_NOTSUPPORTED; // Default return code
|
||
|
|
||
|
DNASSERT(plMicrophoneVolume != NULL);
|
||
|
|
||
|
// Get the microphone recording level if available
|
||
|
if (m_mxcdMicVol.cbStruct != 0)
|
||
|
{
|
||
|
mmr = mixerGetControlDetails( (HMIXEROBJ)((UINT_PTR)m_uWaveDeviceId),
|
||
|
&m_mxcdMicVol, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DNASSERT(m_mxVolume.dwValue >= m_dwRangeMin && m_mxVolume.dwValue <= m_dwRangeMin + m_dwRangeSize);
|
||
|
|
||
|
// Adjust range if necessary
|
||
|
if (m_dwRangeMin != 0 || m_dwRangeSize != 0xFFFF)
|
||
|
m_mxVolume.dwValue = DWORD(double(m_mxVolume.dwValue-m_dwRangeMin) / m_dwRangeSize * 0xFFFF);
|
||
|
|
||
|
// Convert the amplification factor to a DSBVOLUME level
|
||
|
*plMicrophoneVolume = AmpFactorToDB(m_mxVolume.dwValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT hr = MMRESULTtoHRESULT(mmr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::SetMasterRecordVolume"
|
||
|
HRESULT CMixerLine::SetMasterRecordVolume( LONG lRecordVolume )
|
||
|
{
|
||
|
if( !m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_NOTINITIALIZED;
|
||
|
}
|
||
|
|
||
|
MMRESULT mmr = MMSYSERR_NOTSUPPORTED; // Default return code
|
||
|
|
||
|
// Set the master recording level control if available
|
||
|
if (m_mxcdMasterVol.cbStruct)
|
||
|
{
|
||
|
// Convert the DSBVOLUME level to an amplification factor from 0 to 0xFFFF
|
||
|
m_mxVolume.dwValue = DBToAmpFactor(lRecordVolume);
|
||
|
|
||
|
// Adjust range if necessary
|
||
|
if (m_dwRangeMin != 0 || m_dwRangeSize != 0xFFFF)
|
||
|
m_mxVolume.dwValue = DWORD(m_dwRangeMin + m_dwRangeSize*double(m_mxVolume.dwValue)/0xFFFF);
|
||
|
|
||
|
mmr = mixerSetControlDetails((HMIXEROBJ)((UINT_PTR)m_uWaveDeviceId),
|
||
|
&m_mxcdMasterVol, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
|
||
|
HRESULT hr = MMRESULTtoHRESULT(mmr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::GetMasterRecordVolume"
|
||
|
HRESULT CMixerLine::GetMasterRecordVolume( LPLONG plRecordVolume )
|
||
|
{
|
||
|
if( !m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_NOTINITIALIZED;
|
||
|
}
|
||
|
|
||
|
DNASSERT(plRecordVolume != NULL);
|
||
|
|
||
|
MMRESULT mmr = MMSYSERR_NOTSUPPORTED; // Default return code
|
||
|
|
||
|
// Get the master recording level if available
|
||
|
if (m_mxcdMasterVol.cbStruct != 0)
|
||
|
{
|
||
|
mmr = mixerGetControlDetails((HMIXEROBJ)((UINT_PTR)m_uWaveDeviceId),
|
||
|
&m_mxcdMasterVol, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
if (mmr == MMSYSERR_NOERROR)
|
||
|
{
|
||
|
DNASSERT(m_mxVolume.dwValue >= m_dwRangeMin && m_mxVolume.dwValue <= m_dwRangeMin + m_dwRangeSize);
|
||
|
|
||
|
// Adjust range if necessary
|
||
|
if (m_dwRangeMin != 0 || m_dwRangeSize != 0xFFFF)
|
||
|
m_mxVolume.dwValue = DWORD(double(m_mxVolume.dwValue-m_dwRangeMin) / m_dwRangeSize * 0xFFFF);
|
||
|
|
||
|
// Convert the amplification factor to a DSBVOLUME level
|
||
|
*plRecordVolume = AmpFactorToDB(m_mxVolume.dwValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT hr = MMRESULTtoHRESULT(mmr);
|
||
|
return hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::SelectMicrophone"
|
||
|
HRESULT CMixerLine::EnableMicrophone( BOOL fEnable )
|
||
|
{
|
||
|
if( !m_fAcquiredVolCtrl )
|
||
|
{
|
||
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Initialize has not been called" );
|
||
|
return DVERR_NOTINITIALIZED;
|
||
|
}
|
||
|
|
||
|
HMIXEROBJ hMixObj = (HMIXEROBJ)((UINT_PTR)m_uWaveDeviceId);
|
||
|
MMRESULT mmr = MMSYSERR_NOERROR;
|
||
|
HRESULT hr;
|
||
|
|
||
|
// Check for presence of microphone controls
|
||
|
if (!m_mxcdMasterMux.cbStruct && !m_mxcdMasterMute.cbStruct && !m_mxcdMicMute.cbStruct)
|
||
|
{
|
||
|
// We cannot do anything to enable the microphone line
|
||
|
hr = DSERR_UNSUPPORTED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Select the mic on the Mux control, if available
|
||
|
//
|
||
|
if (m_mxcdMasterMux.cbStruct && !(m_fMasterMuxIsMux && !fEnable))
|
||
|
{
|
||
|
*m_pfMicValue = fEnable;
|
||
|
mmr = mixerSetControlDetails(hMixObj, &m_mxcdMasterMux, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
}
|
||
|
|
||
|
// Mute/unmute the lines, if mute controls are available
|
||
|
m_mxMute.fValue = !fEnable;
|
||
|
if (m_mxcdMasterMute.cbStruct && mmr == MMSYSERR_NOERROR)
|
||
|
mmr = mixerSetControlDetails(hMixObj, &m_mxcdMasterMute, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
if (m_mxcdMicMute.cbStruct && mmr == MMSYSERR_NOERROR)
|
||
|
mmr = mixerSetControlDetails(hMixObj, &m_mxcdMicMute, MIXER_OBJECTF_WAVEIN | MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
|
||
|
hr = MMRESULTtoHRESULT(mmr);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
#undef DPF_MODNAME
|
||
|
#define DPF_MODNAME "CMixerLine::MMRESULTtoHRESULT"
|
||
|
HRESULT CMixerLine::MMRESULTtoHRESULT( MMRESULT mmr )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
switch(mmr)
|
||
|
{
|
||
|
case MMSYSERR_NOERROR:
|
||
|
hr = DS_OK;
|
||
|
break;
|
||
|
|
||
|
case MMSYSERR_BADDEVICEID:
|
||
|
case MMSYSERR_NODRIVER:
|
||
|
hr = DSERR_NODRIVER;
|
||
|
break;
|
||
|
|
||
|
case MMSYSERR_ALLOCATED:
|
||
|
hr = DSERR_ALLOCATED;
|
||
|
break;
|
||
|
|
||
|
case MMSYSERR_NOMEM:
|
||
|
hr = DSERR_OUTOFMEMORY;
|
||
|
break;
|
||
|
|
||
|
case MMSYSERR_NOTSUPPORTED:
|
||
|
hr = DSERR_UNSUPPORTED;
|
||
|
break;
|
||
|
|
||
|
case WAVERR_BADFORMAT:
|
||
|
hr = DSERR_BADFORMAT;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hr = DSERR_GENERIC;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|