⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixer.cpp

📁 CIRRUS 93XX系列windows mobile 6.0 BSP
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            // to find the indexed source.
            if (pQuery->dwDestination >= NELEMS(g_dst_lines)) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid destination line %d\r\n"), pQuery->dwDestination));
                return MIXERR_INVALLINE;
            }
            pLine = LookupMxLine(g_dst_lines[pQuery->dwDestination]);
            if (pLine == NULL) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: inconsistent internal mixer line table\r\n")));
                return MMSYSERR_ERROR;
            }
            if (pQuery->dwSource >= pLine->ucConnections) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid source line %d\r\n"), pQuery->dwSource));
                return MIXERR_INVALLINE;
            }
            usLineID = pLine->pSources[pQuery->dwSource];
        }
        break;
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
		DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo COMPONENT\r\n")));
        break;

    case MIXER_GETLINEINFOF_TARGETTYPE:
		DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo TARGET\r\n")));
        // valid query, but we're not going to form usLineID
        break;
    default:
        DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid query %08x\r\n"), dwFlags & MIXER_GETLINEINFOF_QUERYMASK));
        return MMSYSERR_INVALPARAM;
    }

    switch (dwFlags & MIXER_GETLINEINFOF_QUERYMASK) {
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
        // scan for line of proper type
        for (i = 0; i < nlines; i++) {
            if (g_mixerline[i].dwComponentType == pQuery->dwComponentType) {
                pFound = &g_mixerline[i];
                break;
            }
        }
#ifdef DEBUG
        if (pFound == NULL) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: no line of component type %08x\r\n"), pQuery->dwComponentType));
        }
#endif
        break;
    case MIXER_GETLINEINFOF_TARGETTYPE:
        // scan for target type
        for (i = 0; i < nlines; i++) {
            if (g_mixerline[i].dwTargetType == pQuery->Target.dwType) {
                pFound = &g_mixerline[i];
                break;
            }
        }
#ifdef DEBUG
        if (pFound == NULL) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: no line of target type %08x\r\n"), pQuery->Target.dwType));
        }
#endif
        break;

    case MIXER_GETLINEINFOF_DESTINATION:
    case MIXER_GETLINEINFOF_LINEID:
    case MIXER_GETLINEINFOF_SOURCE:
        pFound = LookupMxLine(usLineID);
        if (pFound == NULL) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid line ID %08x\r\n"), usLineID));
            return MMSYSERR_ERROR;
        }
        break;
    default:
        // should never happen - we filter for this in the first switch()
        break;

    }

    if (pFound != NULL) {
        pQuery->cChannels = pFound->ucChannels;
        pQuery->cConnections = pFound->ucConnections;
        pQuery->cControls = pFound->ucControls;
        pQuery->dwComponentType = pFound->dwComponentType;
        pQuery->dwLineID = pFound->usLineID;
        pQuery->dwDestination = pFound->ucDstIndex;
        pQuery->dwSource = pFound->ucSrcIndex;
        pQuery->fdwLine = pFound->ucFlags;
        pQuery->Target.dwDeviceID = 0;
        pQuery->Target.dwType = pFound->dwTargetType;
        pQuery->Target.vDriverVersion = DRIVER_VERSION;
        pQuery->Target.wMid = MM_MICROSOFT;
        pQuery->Target.wPid = MM_MSFT_WSS_MIXER;
        wcscpy(pQuery->szName, pFound->szName);
        wcscpy(pQuery->szShortName, pFound->szShortName);
        wcscpy(pQuery->Target.szPname, DEVICE_NAME);
        mmRet = MMSYSERR_NOERROR;

		DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo: \"%s\" %08x\r\n"), pFound->szName, pFound->ucFlags));
    
	}

    return mmRet;
}

DWORD 
MixerDevice::wdev_MXDM_GETLINECONTROLS (PMIXERLINECONTROLS pQuery, DWORD dwFlags)
{
 UINT i;

    PMIXERCONTROL pDstControl = pQuery->pamxctrl;
    USHORT usLineID = (USHORT) pQuery->dwLineID;
    DWORD dwCount = pQuery->cControls;

    switch (dwFlags & MIXER_GETLINECONTROLSF_QUERYMASK) {
    case MIXER_GETLINECONTROLSF_ALL:
		DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ALL %x\r\n"), usLineID));
        // retrieve all controls for the line pQuery->dwLineID
        {
            PMXLINEDESC pFound = LookupMxLine(usLineID);
            if (pFound == NULL) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid line ID %04x\r\n"), usLineID));
                return MIXERR_INVALLINE;
            }
            if (pFound->ucControls != dwCount) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: incorrect number of controls. Expect %d, found %d.\r\n"),dwCount,pFound->ucControls));
                return MMSYSERR_INVALPARAM;
            }
            for (i = 0; i < ncontrols && dwCount > 0; i++) {
                PMXCONTROLDESC pSrcControl = &g_controls[i];
                if (pSrcControl->usLineID == usLineID) {
                    CopyMixerControl(pDstControl, pSrcControl, i);
                    pDstControl++;
                    dwCount--;
                }
            }
        }
        break;

    case MIXER_GETLINECONTROLSF_ONEBYID: 
		DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ONEBYID %x\r\n"), pQuery->dwControlID));
        // retrieve the control specified by pQuery->dwControlID
        if (pQuery->dwControlID >= ncontrols) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid control ID %d (max %d)\r\n"), pQuery->dwControlID, ncontrols));
            return MIXERR_INVALCONTROL;
        }
        if (dwCount < 1) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: control count must be nonzero\r\n")));
            return MMSYSERR_INVALPARAM;
        }
        CopyMixerControl(pDstControl, &g_controls[pQuery->dwControlID], pQuery->dwControlID);
        pQuery->dwLineID = g_controls[pQuery->dwControlID].usLineID;
        break;

    case MIXER_GETLINECONTROLSF_ONEBYTYPE: 
        // retrieve the control specified by pQuery->dwLineID and pQuery->dwControlType
        {
            UINT index;
            PMXLINEDESC pFound = LookupMxLine(usLineID);
            if (pFound == NULL) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid line ID %04x\r\n"), usLineID));
                return MIXERR_INVALLINE;
            }
			DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ONEBYTYPE %x \"%s\"\r\n"), usLineID, pFound->szName));
            if (dwCount < 1) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: control count must be non zero\r\n")));
                return MMSYSERR_INVALPARAM;
            }
            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 
MixerDevice::wdev_MXDM_GETCONTROLDETAILS (PMIXERCONTROLDETAILS pQuery, DWORD dwFlags)
{
    PMXCONTROLDESC pSrcControlDesc;
    PMXLINEDESC pLine;
    UINT i;
    MIXERCONTROLDETAILS_LISTTEXT * pValue;
    ULONG ulControlValue;

    // 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;
    }
 
    AudioDevice_WaveProc( WPDM_GETMIXERVAL, pSrcControlDesc->usPddMsg, (DWORD) &ulControlValue);

    switch (dwFlags & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
        // only support this for the Record Select mux
        if (pSrcControlDesc->usLineID != MXLINEID(PCM_IN,NOLINE)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: invalid line ID %04x\r\n"), pSrcControlDesc->usLineID));
            return MMSYSERR_INVALPARAM;
        }
        {
            if (pQuery->cMultipleItems != pLine->ucConnections) {
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: incorrect cMultipleItems. Expected %d, found %d\r\n"),
                    pLine->ucConnections, pQuery->cMultipleItems));
                return MMSYSERR_INVALPARAM;
            }
            pValue = (MIXERCONTROLDETAILS_LISTTEXT * ) pQuery->paDetails;
            for (i = 0; i < pLine->ucConnections; i++) {
                PMXLINEDESC pl = LookupMxLine(pLine->pSources[i]);
                if (pl == NULL) {
                    DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails - inconsistent internal mixer line table\r\n")));
                    return MMSYSERR_ERROR;
                }
                pValue[i].dwParam1 = pl->usLineID;
                pValue[i].dwParam2 = pl->dwComponentType;
                wcscpy(pValue[i].szName, pl->szShortName);
            }
        }
        break;
    case MIXER_GETCONTROLDETAILSF_VALUE:
        switch(pSrcControlDesc->dwType) {
            case MIXERCONTROL_CONTROLTYPE_VOLUME:
                {
                    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:
                {
                    MIXERCONTROLDETAILS_BOOLEAN * pValue = (MIXERCONTROLDETAILS_BOOLEAN *) pQuery->paDetails;
                    pValue[0].fValue = ulControlValue;
                }
                break;
            case MIXERCONTROL_CONTROLTYPE_MUX:
                {
                    MIXERCONTROLDETAILS_BOOLEAN * pValue = (MIXERCONTROLDETAILS_BOOLEAN *) pQuery->paDetails;
                    memset(pValue, 0, pQuery->cMultipleItems * sizeof(pValue[0])); // set all entries to FALSE
                    switch (ulControlValue) {
                        case WPDMX_LINE_IN:
                            pValue[0].fValue = TRUE;
                            break;
                        case WPDMX_LINE_MIC:
                            pValue[1].fValue = TRUE;
                            break;
                        default:
                        DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: PDD returned weird index (%d)\r\n"), ulControlValue));
                        return MMSYSERR_ERROR;
                    }
                }
                break;
            default:
                DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: unexpected control type %08x\r\n"), pSrcControlDesc->dwType));
                ASSERT(0);
                break;
        }
        break;
    default:
        DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: invalid query %08x\r\n"), dwFlags & MIXER_GETCONTROLDETAILSF_QUERYMASK));
        break;
    }
    return MMSYSERR_NOERROR;
}

DWORD 
MixerDevice::wdev_MXDM_SETCONTROLDETAILS (PMIXERCONTROLDETAILS pDetail, DWORD dwFlags)
{
    PMXCONTROLDESC pSrcControlDesc;
    PMXLINEDESC pLine;
    DWORD dwSetting; // what to set the control to
    MIXERCONTROLDETAILS_UNSIGNED * pValue = (MIXERCONTROLDETAILS_UNSIGNED * ) pDetail->paDetails;

    // 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 & 0xffff;
			// setting might be mono or stereo. For mono, apply same volume to both channels
			if (pDetail->cChannels == 2) {
                dwSettingR = pValue[1].dwValue & 0xffff;
			}
			else {
				dwSettingR = dwSettingL; 
			}

            if (pLine->ucChannels == 1) {
				dwSetting = (dwSettingL + dwSettingR) / 2;
			}
			else {
                dwSetting = (dwSettingL << 16) | dwSettingR;
			}
			DEBUGMSG(ZONE_VOLUME, (TEXT("wdev_MXDM_SETCONTROLDETAILS: %08x %08x %04x %08x\r\n"), dwSettingL, dwSettingR, pSrcControlDesc->usPddMsg, dwSetting));
        }
        break;
    case MIXERCONTROL_CONTROLTYPE_ONOFF:
    case MIXERCONTROL_CONTROLTYPE_MUTE:
        {
            dwSetting = pValue[0].dwValue;
        }
        break;
    case MIXERCONTROL_CONTROLTYPE_MUX:
        {
            // this is very specific to the input-select mux, since it's the only mux-control we support
            if (pDetail->cMultipleItems != pLine->ucConnections) {
                DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: incorrect cMultipleItems. Expect %d, found %d\r\n"),
                    pLine->ucConnections, pDetail->cMultipleItems));
                return MMSYSERR_INVALPARAM;
            }
            // in fact, we should have exactly two items
            if (pDetail->cMultipleItems != INPUT_SELECT_COUNT) {
                DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: incorrect cMultipleItems. Expect %d, found %d\r\n"),
                    pDetail->cMultipleItems, pDetail->cMultipleItems));
                return MMSYSERR_INVALPARAM;
            }
            if (pValue[0].dwValue) {
                dwSetting = WPDMX_LINE_IN;
            }
            else if (pValue[1].dwValue) {
                dwSetting = WPDMX_LINE_MIC;
            }
            else {
                DEBUGMSG(ZONE_ERROR, (TEXT("SetMixerControlDetails: invalid MUX setting\r\n")));
                return MMSYSERR_INVALPARAM;
            }
        }
        break;
    default:
        DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerControlDetails: unexpected control type %08x\r\n"), pSrcControlDesc->dwType));
        ASSERT(0);
        return MMSYSERR_ERROR;
    }

    AudioDevice_WaveProc( WPDM_SETMIXERVAL, pSrcControlDesc->usPddMsg, dwSetting);

	m_pfnCallback(m_hmx, MM_MIXM_CONTROL_CHANGE, 0, GET_MXCONTROL_ID(pSrcControlDesc), 0);

    //PerformMixerCallbacks (MM_MIXM_CONTROL_CHANGE, GET_MXCONTROL_ID(pSrcControlDesc));

    return MMSYSERR_NOERROR;
}




MMRESULT
MixerDevice::AudioDevice_WaveProc(
    DWORD      dwCode,
    DWORD      dwParam1,
    DWORD      dwParam2
    )

{
	return m_pAudioCodec->MixerVolumeSettings( dwCode,  dwParam1, dwParam2 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -