📄 mixhw.cpp
字号:
}
wVal = WORD(dwLeft/1.5) | wMuted | wAmplifierFlag;
if (!pCX5530Audio->WriteAC97(USHORT(dwAddr), (USHORT)wVal))
dwRet = ERROR_WRITE_FAULT;
}
break;
case LINE_IN_VOLUME:
case LINE_OUT_VOLUME:
case PCM_VOLUME:
case WAVE_IN_GAIN:
// each hardware bit represents 1.5 db, except for the PC Beep where it's 3 db
dwLeft /= 150;
dwRight /= 150;
if (!pCX5530Audio->ReadAC97(USHORT(dwAddr), wMuted))
{
dwRet = ERROR_READ_FAULT;
break;
}
// separate mute flag
wMuted &= AC97_MIXER_MUTE;
// is the attenuation higher than the hardware range?
if (dwLeft > g_Controls[dwId].dwMinimum)
{
bMute = TRUE;
dwLeft = g_Controls[dwId].dwMinimum;
}
if (dwRight > g_Controls[dwId].dwMinimum)
{
bMute = TRUE;
dwRight = g_Controls[dwId].dwMinimum;
}
if (bMute) // hack-mute
{
wMuted |= AC97_MIXER_MUTE;
}
else if (wMuted)
{
// muted, but volume set to something large: need to know if this was really mute, or
// transparently muted by the driver during a previous volume setting
DWORD dwMute = GetAssociatedMuteID(dwId);
if (dwMute != (DWORD)-1)
{
if (!g_Controls[dwMute].dwLogicalValue)
{
wMuted = 0;
}
}
}
if (dwId == WAVE_IN_GAIN)
{ // for this control the register setting is really a gain, not an attenuation
// so convert here.
dwRight = 0x0F - dwRight;
dwLeft = 0x0F - dwLeft;
}
wVal = (dwLeft << 8) | dwRight | wMuted;
if (!pCX5530Audio->WriteAC97(USHORT(dwAddr), (USHORT)wVal))
dwRet = ERROR_WRITE_FAULT;
break;
default:
//error: we received an ID for a control that's not a volume!
ASSERT(FALSE);
MIXERRMSG1("SetMixerVolume: bad ID: %d", dwId);
dwRet = ERROR_NOT_SUPPORTED;
}
MIXMSG1("-SetMixerVolume: 0x%08x\r\n", dwRet);
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
SetMixerMute
Description:
Sets muting for one of the mixer controls. Only works with MUTE controls
Arguments:
PDRIVER_CONTEXT pDriverContext :
DWORD dwId :
BOOL bMute : TRUE: mute line; FALSE: unmute line
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD SetMixerMute(PDRIVER_CONTEXT pDriverContext, DWORD dwId, BOOL bMute)
{
DWORD dwAddr;
WORD wVal = 0;
DWORD dwRet = NO_ERROR;
CCX5530Audio* pCX5530Audio = CCX5530Audio::GetCX5530AudioObject();
ASSERT(pCX5530Audio && pDriverContext && dwId >= 0 && dwId < MAX_CONTROLS);
MIXMSG3("+SetMixerMute id %d -%s: %s",
dwId, g_Controls[dwId].szShortName, bMute?TEXT("MUTE"):TEXT("UNMUTE"));
dwAddr = g_Controls[dwId].dwRegister;
g_Controls[dwId].dwLogicalValue = bMute;
pCX5530Audio->ReadAC97(USHORT(dwAddr), wVal );
MIXMSG1("ReadAC97 reports dwVal = %d", wVal);
switch (dwId)
{
case LINE_IN_MUTE:
case LINE_OUT_MUTE:
case PCM_MUTE:
case WAVE_IN_MUTE:
case MIC_MUTE:
wVal = bMute? (wVal | AC97_MIXER_MUTE):
(wVal & ~AC97_MIXER_MUTE);
if (!pCX5530Audio->WriteAC97(USHORT(dwAddr), wVal))
dwRet = ERROR_WRITE_FAULT;
break;
default:
//error: we received an ID for a control that's not a mute!
ASSERT(FALSE);
MIXERRMSG1("SetMixerMute: bad ID: %d", dwId);
dwRet = ERROR_NOT_SUPPORTED;
}
MIXMSG1("-SetMixerMute: 0x%08x", dwRet);
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
GetMixerVolume
Description:
Gets the volume for one of the mixer controls
Arguments:
PDRIVER_CONTEXT pDriverContext : the context
DWORD dwId : the ID of the control
PDWORD *pdwLeft : the volume for the left channel
PDWORD *pdwRight : the volume for the right channel
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD GetMixerVolume(PDRIVER_CONTEXT pDriverContext, DWORD dwId, DWORD *pdwLeft, DWORD *pdwRight )
{
DWORD dwRet = NO_ERROR;
ASSERT(pDriverContext && pdwLeft && pdwRight);
ASSERT(dwId >= 0 && dwId < MAX_CONTROLS);
MIXMSG1("+GetMixerVolume id %d ", dwId);
switch (dwId)
{
case LINE_IN_VOLUME:
case LINE_OUT_VOLUME:
case PCM_VOLUME:
case WAVE_IN_GAIN:
case MIC_VOLUME:
*pdwLeft = HIWORD(g_Controls[dwId].dwLogicalValue);
*pdwRight = LOWORD(g_Controls[dwId].dwLogicalValue);
break;
default:
//error: we received an ID for a control that's not a volume!
ASSERT(FALSE);
MIXERRMSG1("GetMixerVolume: bad ID: %d", dwId);
dwRet = ERROR_NOT_SUPPORTED;
}
MIXMSG2("-GetMixerVolume : dwRet, (%d, %d)\r\n", *pdwLeft, *pdwRight);
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
GetMixerMute
Description:
Arguments:
PDRIVER_CONTEXT pDriverContext :
DWORD dwId :
BOOL *pbMute :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD GetMixerMute(PDRIVER_CONTEXT pDriverContext, DWORD dwId, BOOL *pbMute )
{
DWORD dwRet= NO_ERROR;
ASSERT(pDriverContext && pbMute);
ASSERT(dwId >= 0 && dwId < MAX_CONTROLS);
MIXMSG1("+GetMixerMute id: %d\r\n", dwId);
*pbMute = g_Controls[dwId].dwLogicalValue != 0;
MIXMSG2("-GetMixerMute: 0x%08x, report %s\r\n", dwRet, (*pbMute)?TEXT("MUTED"):TEXT("UNMUTED"));
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
GetMuxValue
Description:
Arguments:
PDRIVER_CONTEXT pDriverContext :
DWORD dwControlID :
PDWORD pdwValue :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD GetMuxValue(PDRIVER_CONTEXT pDriverContext, DWORD dwControlID, PDWORD pdwValue)
{
// which mux?
DWORD dwRet = NO_ERROR, dwAddr = g_Controls[dwControlID].dwRegister;
ASSERT (pdwValue);
*pdwValue = 0;
switch(dwControlID)
{
case WAVE_IN_SELECTOR:
{
CCX5530Audio* pCX5530Audio = CCX5530Audio::GetCX5530AudioObject();
USHORT uVal;
pCX5530Audio->ReadAC97(USHORT(dwAddr), uVal);
*pdwValue = uVal & 0x07;
}
break;
default:
ERRMSG1("GetMuxValue: bad ID: %d\r\n", dwControlID);
dwRet = ERROR_NOT_SUPPORTED;
}
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
SetMuxValue
Description:
Arguments:
PDRIVER_CONTEXT pDriverContext :
DWORD dwControlID :
DWORD dwValue :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD SetMuxValue(PDRIVER_CONTEXT pDriverContext, DWORD dwControlID, DWORD dwValue)
{
DWORD dwRet = NO_ERROR;
WORD wVal;
ASSERT(pDriverContext);
FUNCMSG2("+SetMuxValue control %d, value %d", dwControlID, dwValue);
switch(dwControlID)
{
case WAVE_IN_SELECTOR:
switch (dwValue)
{
case 0: // mic
wVal = AC97_RECORDSOURCE_MIC;
break;
case 1: // line in
wVal = AC97_RECORDSOURCE_LINE_IN;
break;
case 2: //
wVal = AC97_RECORDSOURCE_LINE_OUT;
break;
default:
ERRMSG1("SetMuxValue: bad ID: %d\r\n", dwControlID);
dwRet = ERROR_NOT_SUPPORTED;
}
break;
default:
ERRMSG1("SetMuxValue: bad ID: %d\r\n", dwControlID);
dwRet = ERROR_NOT_SUPPORTED;
}
if (dwRet == NO_ERROR)
{
CCX5530Audio* pCX5530Audio = CCX5530Audio::GetCX5530AudioObject();
ASSERT(pCX5530Audio);
if (!pCX5530Audio->WriteAC97(AC97_RECORD_SELECT, wVal | wVal << 8))
dwRet = ERROR_WRITE_FAULT;
}
MIXMSG1("-SetMuxValue: %d\r\n", dwRet);
return dwRet;
}
DWORD SetUnsignedValue(PDRIVER_CONTEXT pDriverContext, DWORD dwControlID, DWORD dwValue)
{
// which mux?
DWORD dwRet = ERROR_NOT_SUPPORTED;
ASSERT(pDriverContext);
MIXMSG1("-SetUnsignedValue: %d\r\n", dwRet);
return dwRet;
}
DWORD GetUnsignedValue(PDRIVER_CONTEXT pDriverContext, DWORD dwControlID, DWORD *pdwValue)
{
// which mux?
DWORD dwRet = ERROR_NOT_SUPPORTED;
ASSERT(pDriverContext && pdwValue);
*pdwValue = 0;
MIXMSG1("-GetUnsignedValue: %d\r\n", dwRet);
return dwRet;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
FindMixerLine
Description:
Returns a pointer to the mixerline struct for the appropriate ID
Arguments:
DWORD mxLine : the line ID for the line requested
Return Value: LPMIXERLINE
NULL if the line doesn't exist on the current platform
-------------------------------------------------------------------*/
LPMIXERLINE FindMixerLine(DWORD mxLine)
{
// this array maps line IDs to indexes in the g_mixerLines array
// it's not needed for the clipper, because the mapping is direct;
// logical lines are all at the same index as the ones in the g_mixerLines array
/*
static mapLines[LINES_COUNT] =
{ // for the DCT5000_EPR
0, //LINE_OUT
1, //PCM,
};
*/
if (mxLine < LINE_OUT || mxLine >= LINES_COUNT)
return NULL;
//if (mapLines[mxLine] == -1)
// return NULL;
//return &g_mixerLines[mapLines[mxLine]];
return &g_mixerLines[mxLine];
}
DWORD GetAssociatedMuteID(DWORD dwVolumeControlID)
{
int i;
for (i = 0; i < sizeof(g_ControlsPairs)/(2 * sizeof(g_ControlsPairs[0][0])); i++)\
{
if (g_ControlsPairs[i][0] == dwVolumeControlID)
return g_ControlsPairs[i][1];
}
MIXERRMSG1("Error in GetAssociatedMuteID Id : %d!!!\r\n", dwVolumeControlID);
return (DWORD)-1;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
mix_InitMixer
Description:
initialize mixer to a default state, that allows the wave driver to behave correctly (i.e., play)
without having the user fiddle with the mix device
Arguments:
PMIXER_CONTEXT pMixer :
Return Value: void
-------------------------------------------------------------------*/
void mix_InitMixer( PDRIVER_CONTEXT pDriverContext )
{
// set all multiplexers
// switch the mixer output to line out
MIXMSG("+mix_InitMixer\r\n");
// disable mute all
SetMixerMute(pDriverContext, LINE_IN_MUTE, MUTE);
SetMixerMute(pDriverContext, LINE_OUT_MUTE, UNMUTE);
SetMixerMute(pDriverContext, PCM_MUTE, UNMUTE);
SetMixerMute(pDriverContext, WAVE_IN_MUTE, MUTE);
// set all volume/mute registers
SetMixerVolume(pDriverContext, LINE_OUT_VOLUME, 0, 0);
SetMixerVolume(pDriverContext, PCM_VOLUME, 0, 0);
MIXMSG("-mix_InitMixer\r\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -