📄 px_win_wmme.c
字号:
details.cChannels = 1 ; details.cbDetails = sizeof( MIXERCONTROLDETAILS_LISTTEXT ) ; details.paDetails = ( LPMIXERCONTROLDETAILS_LISTTEXT )&mixList[0] ; details.cMultipleItems = mixer->numInputs ; mmr = mixerGetControlDetails( ( HMIXEROBJ )( mixer->hInputMixer ), ( LPMIXERCONTROLDETAILS )&details, MIXER_GETCONTROLDETAILSF_LISTTEXT ) ; if ( mmr == MMSYSERR_NOERROR ) { int j = 0 ; for ( ; j < mixer->numInputs ; ++j ) { // record the control's name and line id strcpy( mixer->src[j].name, mixList[j].szName ) ; mixer->src[j].lineID = mixList[j].dwParam1 ; // now get the control's volume control MIXERCONTROL control ; MIXERLINECONTROLS controls ; controls.cbStruct = sizeof( MIXERLINECONTROLS ) ; controls.dwLineID = mixList[j].dwParam1 ; controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME ; controls.cbmxctrl = sizeof( MIXERCONTROL ) ; controls.pamxctrl = &control ; control.cbStruct = sizeof( MIXERCONTROL ) ; mmr = mixerGetLineControls( mixer->hInputMixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) break ; mixer->src[j].controlID = control.dwControlID ;// fprintf( stdout, "INPUT :: index => %d, name => %s, lineID => %u\n", // j, mixer->src[j].name, mixer->src[j].lineID, mixer->src[j].controlID ) ; } } } // if there was a problem with the muxID, // reset so we can try the line controls directly if ( mmr != MMSYSERR_NOERROR ) { mixer->useMuxID = 0 ; } if ( mixer->useMuxID == 0 ) { // no mux, use line controls instead // remember number of connections ( sources ) for this line int sources = mixerLine.cConnections ; int j ; for ( j = 0 ; j < sources ; ++j ) { // // get info about the current connection // MIXERLINE line ; line.cbStruct = sizeof( MIXERLINE ) ; line.dwSource = j ; line.dwDestination = mixerLine.dwDestination ; mmr = mixerGetLineInfo( ( HMIXEROBJ )( mixer->hInputMixer ), &line, MIXER_GETLINEINFOF_SOURCE ) ; if ( mmr != MMSYSERR_NOERROR ) continue ; // // save line info // strcpy( mixer->src[j].name, line.szName ) ; mixer->src[j].lineID = line.dwLineID ; mixer->src[j].controlID = -1 ; // unfortunately, dwControlID is unsigned.... if ( line.cControls == 0 ) continue ; // // find line's volume control // LPMIXERCONTROL mixerControl = malloc( sizeof( MIXERCONTROL ) * line.cControls ) ; // Find a volume control, if any, of the microphone line MIXERLINECONTROLS mixerLineControls ; mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ; mixerLineControls.dwLineID = line.dwLineID ; mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME ; mixerLineControls.cControls = line.cControls ; mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ; mixerLineControls.pamxctrl = mixerControl ; mmr = mixerGetLineControls( ( HMIXEROBJ )( mixer->hInputMixer ), &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) continue ; int x = 0 ; for ( ; x < line.cControls ; ++x ) { mixer->src[j].controlID = mixerControl[x].dwControlID ; // use first volume control break ; } // fprintf( stdout, "INPUT :: index => %d, name => %s, lineID => %u\n", // j, mixer->src[j].name, mixer->src[j].lineID ) ; free( mixerControl ) ; } } // // report findings // return MMSYSERR_NOERROR ;}MMRESULT_Px_InitOutputVolumeControls( PxInfo* mixer, int hWaveOut ) { MMRESULT mmr ; // cast void pointer PxInfo* info = ( PxInfo* )( mixer ) ; if ( info == NULL ) return MMSYSERR_ERROR ; // default win32 speaker control id mixer->speakerID = 0x00000000 ; // // open the mixer device // mmr = mixerOpen( ( LPHMIXER )( &mixer->hOutputMixer ), hWaveOut, 0, 0, MIXER_OBJECTF_HWAVEOUT ) ; if ( mmr != MMSYSERR_NOERROR ) return mmr ; // set default values mixer->speakerID = 0 ; mixer->waveID = 0 ; // // MASTER VOLUME // while ( 42 ) { // // get the line info for the dst speakers // MIXERLINE mixerLine ; mixerLine.cbStruct = sizeof( MIXERLINE ) ; mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ; mmr = mixerGetLineInfo( ( HMIXEROBJ )( mixer->hOutputMixer ), &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) { mixerClose( ( HMIXER )( mixer->hOutputMixer ) ) ; break ; } // no controls, don't go any further if ( mixerLine.cControls <= 0 ) break ; // // get volume control for dst speakers line // MIXERCONTROL mixerControl ; mixerControl.cbStruct = sizeof( MIXERCONTROL ) ; MIXERLINECONTROLS mixerLineControls ; mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ; mixerLineControls.dwLineID = mixerLine.dwLineID ; mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME ; mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ; mixerLineControls.pamxctrl = &mixerControl ; mmr = mixerGetLineControls( ( HMIXEROBJ )( mixer->hOutputMixer ), &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) { mixerClose( ( HMIXER )( mixer->hInputMixer ) ) ; } else { // save speaker_id mixer->speakerID = mixerControl.dwControlID ; } break ; } // // PCM VOLUME // while ( 42 ) { // // get the line info for the dst speakers // MIXERLINE mixerLine ; mixerLine.cbStruct = sizeof( MIXERLINE ) ; mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT ; mmr = mixerGetLineInfo( ( HMIXEROBJ )( mixer->hOutputMixer ), &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) { mixerClose( ( HMIXER )( mixer->hOutputMixer ) ) ; break ; } // no controls, don't go any further if ( mixerLine.cControls <= 0 ) break ; // // get volume control for dst speakers line // MIXERCONTROL mixerControl ; mixerControl.cbStruct = sizeof( MIXERCONTROL ) ; MIXERLINECONTROLS mixerLineControls ; mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ; mixerLineControls.dwLineID = mixerLine.dwLineID ; mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME ; mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ; mixerLineControls.pamxctrl = &mixerControl ; mmr = mixerGetLineControls( ( HMIXEROBJ )( mixer->hOutputMixer ), &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) { mixerClose( ( HMIXER )( mixer->hInputMixer ) ) ; } else { // save speaker_id mixer->waveID = mixerControl.dwControlID ; } break ; } return MMSYSERR_NOERROR ;}MMRESULT _Px_SetMicrophoneBoost( PxMixer* mixer, int enable ){ MMRESULT mmr = MMSYSERR_ERROR ; // cast void pointer PxInfo* info = ( PxInfo* )( mixer ) ; if ( info == NULL ) return MMSYSERR_ERROR ; // // get line info // MIXERLINE mixerLine ; mixerLine.cbStruct = sizeof( MIXERLINE ) ; mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ; mmr = mixerGetLineInfo( ( HMIXEROBJ )( info->hInputMixer ), &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) return mmr ; // // get all controls // LPMIXERCONTROL mixerControl = malloc( sizeof( MIXERCONTROL ) * mixerLine.cControls ) ; MIXERLINECONTROLS mixerLineControls ; mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ; mixerLineControls.dwLineID = mixerLine.dwLineID ; mixerLineControls.cControls = mixerLine.cControls ; mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ; mixerLineControls.pamxctrl = ( LPMIXERCONTROL )( mixerControl ) ; mmr = mixerGetLineControls( ( HMIXEROBJ )( info->hInputMixer ), &mixerLineControls, MIXER_GETLINECONTROLSF_ALL ) ; if ( mmr != MMSYSERR_NOERROR ) return mmr ; // // find boost control // DWORD boost_id = -1 ; int x = 0 ; for ( ; x < mixerLineControls.cControls ; ++x ) { // check control type if ( mixerControl[x].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF ) { // normalize control name char* name = _strupr( mixerControl[x].szName ) ; // check for 'mic' and 'boost' if ( ( strstr( name, "MIC" ) != NULL ) && ( strstr( name, "BOOST" ) != NULL ) ) { boost_id = mixerControl[x].dwControlID ; break ; } } } if ( boost_id == -1 ) return MMSYSERR_ERROR ; // // get control details // MIXERCONTROLDETAILS_BOOLEAN value ; MIXERCONTROLDETAILS mixerControlDetails ; mixerControlDetails.cbStruct = sizeof( MIXERCONTROLDETAILS ) ; mixerControlDetails.dwControlID = boost_id ; mixerControlDetails.cChannels = 1 ; mixerControlDetails.cMultipleItems = 0 ; mixerControlDetails.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ; mixerControlDetails.paDetails = &value ; mmr = mixerGetControlDetails( ( HMIXEROBJ )( info->hInputMixer ), &mixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE ) ; if ( mmr != MMSYSERR_NOERROR ) return mmr ; // // update value // value.fValue = ( enable == 0 ) ? 0L : 1L ; // // set control details // mmr = mixerSetControlDetails( ( HMIXEROBJ )( info->hInputMixer ), &mixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE ) ; if ( mmr != MMSYSERR_NOERROR ) return mmr ; return mmr ;}int _Px_GetMicrophoneBoost( PxMixer* mixer ){ MMRESULT mmr = MMSYSERR_ERROR ; // cast void pointer PxInfo* info = ( PxInfo* )( mixer ) ; if ( info == NULL ) return -1 ; // // get line info // MIXERLINE mixerLine ; mixerLine.cbStruct = sizeof( MIXERLINE ) ; mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ; mmr = mixerGetLineInfo( ( HMIXEROBJ )( info->hInputMixer ), &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ) ; if ( mmr != MMSYSERR_NOERROR ) return -1 ; // // get all controls // LPMIXERCONTROL mixerControl = malloc( sizeof( MIXERCONTROL ) * mixerLine.cControls ) ; MIXERLINECONTROLS mixerLineControls ; mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ; mixerLineControls.dwLineID = mixerLine.dwLineID ; mixerLineControls.cControls = mixerLine.cControls ; mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ; mixerLineControls.pamxctrl = ( LPMIXERCONTROL )( mixerControl ) ; mmr = mixerGetLineControls( ( HMIXEROBJ )( info->hInputMixer ), &mixerLineControls, MIXER_GETLINECONTROLSF_ALL ) ; if ( mmr != MMSYSERR_NOERROR ) return -1 ; // // find boost control // DWORD boost_id = -1 ; int x = 0 ; for ( ; x < mixerLineControls.cControls ; ++x ) { // check control type if ( mixerControl[x].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF ) { // normalize control name char* name = _strupr( mixerControl[x].szName ) ; // check for 'mic' and 'boost' if ( ( strstr( name, "MIC" ) != NULL ) && ( strstr( name, "BOOST" ) != NULL ) ) { boost_id = mixerControl[x].dwControlID ; break ; } } } if ( boost_id == -1 ) return -1 ; // // get control details // MIXERCONTROLDETAILS_BOOLEAN value ; MIXERCONTROLDETAILS mixerControlDetails ; mixerControlDetails.cbStruct = sizeof( MIXERCONTROLDETAILS ) ; mixerControlDetails.dwControlID = boost_id ; mixerControlDetails.cChannels = 1 ; mixerControlDetails.cMultipleItems = 0 ; mixerControlDetails.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ; mixerControlDetails.paDetails = &value ; mmr = mixerGetControlDetails( ( HMIXEROBJ )( info->hInputMixer ), &mixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE ) ; if ( mmr != MMSYSERR_NOERROR ) return -1 ; return ( int )( value.fValue ) ;}MMRESULT _Px_SetCurrentInputSourceByName( PxInfo* mixer, const char* name ) { // cast void pointer PxInfo* info = ( PxInfo* )( mixer ) ; // make sure we have a mixer if ( info == NULL ) return MMSYSERR_ERROR ; // make sure we have a search name if ( name == NULL ) return MMSYSERR_ERROR ; // // set input source // int x = 0 ; for ( ; x < info->numInputs ; ++x ) { // compare passed name with control name if ( strncasecmp( info->src[x].name, name, strlen( name ) ) == 0 ) { // set input source Px_SetCurrentInputSource( mixer, x ) ; // make sure set'ing worked if ( Px_GetCurrentInputSource( mixer ) == x ) return MMSYSERR_NOERROR ; else return MMSYSERR_ERROR ; } } return MMSYSERR_ERROR ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -