📄 mixerdrv.cpp
字号:
index = LookupMxControl(usLineID, pQuery->dwControlType);
if (index >= ncontrols) {
// not to be alarmed: SndVol32 queries for LOTS of control types we don't have
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: line %04x (%s) has no control of type %s (%08x)\r\n"), usLineID, pFound->szName, COMPTYPE(pQuery->dwControlType), pQuery->dwControlType));
return MMSYSERR_INVALPARAM;
}
CopyMixerControl(pDstControl, &g_controls[index], index);
return MMSYSERR_NOERROR;
// if we fall out of the search loop, we return failure
}
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid query %08x\r\n"), dwFlags & MIXER_GETLINECONTROLSF_QUERYMASK));
break;
}
return MMSYSERR_NOERROR;
}
DWORD
wdev_MXDM_GETCONTROLDETAILS (PMIXERCONTROLDETAILS pQuery, DWORD dwFlags)
{
PMXCONTROLDESC pSrcControlDesc;
PMXLINEDESC pLine;
ULONG ulControlValue = 0;
// API guarantees that pQuery points to accessible, aligned, properly sized MIXERCONTROLDETAILS structure
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerControlDetails(%d)\r\n"), pQuery->dwControlID));
if (pQuery->dwControlID >= ncontrols) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: invalid control %d (max %d)\r\n"), pQuery->dwControlID, ncontrols));
return MIXERR_INVALCONTROL;
}
pSrcControlDesc = &g_controls[pQuery->dwControlID];
pLine = LookupMxLine(pSrcControlDesc->usLineID);
if (pLine == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: inconsistent internal mixer line table\r\n")));
return MMSYSERR_ERROR;
}
switch (dwFlags & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
case MIXER_GETCONTROLDETAILSF_VALUE:
switch(pSrcControlDesc->dwType) {
case MIXERCONTROL_CONTROLTYPE_VOLUME:
{
switch (GET_MXLINE_DST(pSrcControlDesc->usLineID)) {
case LINE_OUT:
ulControlValue = g_pHWContext->GetOutputGain();
break;
case PCM_IN:
ulControlValue = g_pHWContext->GetInputGain();
break;
default:
DEBUGCHK(0);
break;
}
MIXERCONTROLDETAILS_UNSIGNED * pValue = (MIXERCONTROLDETAILS_UNSIGNED * ) pQuery->paDetails;
ULONG ulVolR, ulVolL;
ulVolR = ulControlValue & 0xffff;
if (pLine->ucChannels == 2) {
ulVolL = (ulControlValue >> 16) & 0xffff;
}
else {
ulVolL = ulVolR;
}
if (pQuery->cChannels == 1) {
pValue[0].dwValue = (ulVolR + ulVolL)/2;
}
else {
pValue[0].dwValue = ulVolL;
pValue[1].dwValue = ulVolR;
}
}
break;
case MIXERCONTROL_CONTROLTYPE_ONOFF:
case MIXERCONTROL_CONTROLTYPE_MUTE:
{
switch (GET_MXLINE_DST(pSrcControlDesc->usLineID)) {
case LINE_OUT:
ulControlValue = g_pHWContext->GetOutputMute();
break;
case PCM_IN:
ulControlValue = g_pHWContext->GetInputMute();
break;
default:
DEBUGCHK(0);
break;
}
MIXERCONTROLDETAILS_BOOLEAN * pValue = (MIXERCONTROLDETAILS_BOOLEAN *) pQuery->paDetails;
pValue[0].fValue = ulControlValue;
}
break;
default:
DEBUGCHK(0);
break;
}
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: invalid query %08x\r\n"), dwFlags & MIXER_GETCONTROLDETAILSF_QUERYMASK));
break;
}
return MMSYSERR_NOERROR;
}
DWORD
wdev_MXDM_SETCONTROLDETAILS (PMIXERCONTROLDETAILS pDetail, DWORD dwFlags)
{
PMXCONTROLDESC pSrcControlDesc;
PMXLINEDESC pLine;
MIXERCONTROLDETAILS_UNSIGNED * pValue = (MIXERCONTROLDETAILS_UNSIGNED * ) pDetail->paDetails;
DWORD dwSetting;
// API guarantees that pDetail points to accessible, aligned, properly siezd MIXERCONTROLDETAILS structure
DEBUGMSG(ZONE_HWMIXER, (TEXT("SetMixerControlDetails(%d)\r\n"), pDetail->dwControlID));
if (pDetail->dwControlID >= ncontrols) {
DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: invalid control %d (max %d)\r\n"), pDetail->dwControlID, ncontrols));
return MIXERR_INVALCONTROL;
}
pSrcControlDesc = &g_controls[pDetail->dwControlID];
pLine = LookupMxLine(pSrcControlDesc->usLineID);
if (pLine == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: inconsistent internal mixer line table\r\n")));
return MMSYSERR_ERROR;
}
switch(pSrcControlDesc->dwType) {
case MIXERCONTROL_CONTROLTYPE_VOLUME:
{
DWORD dwSettingL, dwSettingR;
dwSettingL = pValue[0].dwValue;
// setting might be mono or stereo. For mono, apply same volume to both channels
if (pDetail->cChannels == 2) {
dwSettingR = pValue[1].dwValue;
}
else {
dwSettingR = dwSettingL;
}
if ( (dwSettingL > LOGICAL_VOLUME_MAX) || (dwSettingR > LOGICAL_VOLUME_MAX) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: Volume exceeds bounds\r\n")));
return MMSYSERR_INVALPARAM;
}
if (pLine->ucChannels == 1) {
dwSetting = (dwSettingL + dwSettingR) / 2;
}
else {
dwSetting = (dwSettingL << 16) | dwSettingR;
}
// now apply the setting to the hardware
switch (GET_MXLINE_DST(pSrcControlDesc->usLineID)) {
case LINE_OUT:
g_pHWContext->SetOutputGain(dwSetting);
break;
case PCM_IN:
g_pHWContext->SetInputGain(dwSetting);
break;
default:
DEBUGCHK(0);
break;
}
DEBUGMSG(ZONE_VOLUME, (TEXT("wdev_MXDM_SETCONTROLDETAILS: %08x %08x %08x\r\n"), dwSettingL, dwSettingR, dwSetting));
}
break;
case MIXERCONTROL_CONTROLTYPE_ONOFF:
case MIXERCONTROL_CONTROLTYPE_MUTE:
{
// now apply the setting to the hardware
switch (GET_MXLINE_DST(pSrcControlDesc->usLineID)) {
case LINE_OUT:
g_pHWContext->SetOutputMute(pValue[0].dwValue);
break;
case PCM_IN:
g_pHWContext->SetInputMute(pValue[0].dwValue);
break;
default:
DEBUGCHK(0);
break;
}
}
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: unexpected control type %08x\r\n"), pSrcControlDesc->dwType));
ASSERT(0);
return MMSYSERR_ERROR;
}
PerformMixerCallbacks (MM_MIXM_CONTROL_CHANGE, GET_MXCONTROL_ID(pSrcControlDesc));
return MMSYSERR_NOERROR;
}
BOOL HandleMixerMessage(PMMDRV_MESSAGE_PARAMS pParams, DWORD *pdwResult)
{
MMRESULT dwRet;
switch (pParams->uMsg) {
case MXDM_GETNUMDEVS:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_GETNUMDEVS\r\n")));
dwRet = 1;
break;
case MXDM_GETDEVCAPS:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_GETDEVCAPS\r\n")));
dwRet = wdev_MXDM_GETDEVCAPS((PMIXERCAPS) pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_OPEN:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_OPEN\r\n")));
dwRet = wdev_MXDM_OPEN((PDWORD) pParams->dwUser, (PMIXEROPENDESC) pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_CLOSE:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_CLOSE\r\n")));
dwRet = wdev_MXDM_CLOSE(pParams->dwUser);
break;
case MXDM_GETLINEINFO:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_GETLINEINFO\r\n")));
dwRet = wdev_MXDM_GETLINEINFO((PMIXERLINE) pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETLINECONTROLS:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_GETLINECONTROLS\r\n")));
dwRet = wdev_MXDM_GETLINECONTROLS((PMIXERLINECONTROLS) pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETCONTROLDETAILS:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_GETCONTROLDETAILS\r\n")));
dwRet = wdev_MXDM_GETCONTROLDETAILS((PMIXERCONTROLDETAILS) pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_SETCONTROLDETAILS:
PRINTMSG(ZONE_WODM, (TEXT("MXDM_SETCONTROLDETAILS\r\n")));
dwRet = wdev_MXDM_SETCONTROLDETAILS((PMIXERCONTROLDETAILS) pParams->dwParam1, pParams->dwParam2);
break;
default:
ERRMSG("Unsupported mixer message");
dwRet = MMSYSERR_NOTSUPPORTED;
break;
} // switch (pParams->uMsg)
*pdwResult = dwRet;
return TRUE;
}
struct _global_volume
{
ULONG dwMasterVolume;
BOOL fMasterMute;
ULONG dwMicVolume;
BOOL fMicMute;
} g_VolumeSettings;
MMRESULT GetMixerValue(DWORD dwControl, PDWORD pdwSetting)
{
switch (dwControl) {
case WPDMX_MASTER_VOL:
*pdwSetting = g_VolumeSettings.dwMasterVolume;
break;
case WPDMX_MASTER_MUTE:
*pdwSetting = g_VolumeSettings.fMasterMute;
break;
case WPDMX_MIC_VOL:
*pdwSetting = g_VolumeSettings.dwMicVolume;
break;
case WPDMX_MIC_MUTE:
*pdwSetting = g_VolumeSettings.fMicMute;
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerValue: unrecognized control")));
return MMSYSERR_NOTSUPPORTED;
}
return MMSYSERR_NOERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -