BOOL mixer_init(DWORD dwCallback) { MIXERLINE line; int i; int j; CHECK_MMRETURN(mixerOpen(&s_hMixer, 0, dwCallback, 0, CALLBACK_WINDOW | MIXER_OBJECTF_MIXER)); line.cbStruct = sizeof(MIXERLINE); line.dwDestination = 0; line.dwSource = 0; CHECK_MMRETURN(mixerGetLineInfo((HMIXEROBJ)s_hMixer, &line, MIXER_GETLINEINFOF_DESTINATION)); if (!mixer_getlinecontrols(&line)) return (FALSE); for (i = 0, j = line.cConnections; i < j; i++) { line.dwSource = i; CHECK_MMRETURN(mixerGetLineInfo((HMIXEROBJ)s_hMixer, &line, MIXER_GETLINEINFOF_SOURCE)); if (!mixer_getlinecontrols(&line)) return (FALSE); } return (TRUE); }
///////////////////////////////////////////////// // Component: value from dwComponentType member of MIXERLINE, eg:// MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE // Kind : 0 Wave ouput tunnle, 1 Wave input tunle, 2... other. CMixer::CMixer(DWORD ComponentType, DestKind dkKind): m_dwControlID(-1), m_bOK(false), m_dwChannels(0) { HMIXER hMixer; HRESULT hr; hr = mixerOpen(&hMixer, 0, 0, 0, 0); if (FAILED(hr)) return; MIXERLINE mxl; MIXERCONTROL mc; MIXERLINECONTROLS mxlc; DWORD kind, count; if (dkKind == Play) kind = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; else kind = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; mxl.cbStruct = sizeof(mxl); mxl.dwComponentType = kind; hr = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE); if (FAILED(hr)) { mixerClose(hMixer); return; } count = mxl.dwSource; for(UINT i = 0; i < count; i++) { mxl.dwSource = i; mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE); if (mxl.dwComponentType == ComponentType) { m_dwChannels = mxl.cChannels; mc.cbStruct = sizeof(mc); mxlc.cbStruct = sizeof(mxlc); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mc; hr = mixerGetLineControls((HMIXEROBJ)hMixer, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); m_dwControlID = mc.dwControlID; break; }; } mixerClose(hMixer); m_bOK = true; }
VOID GetMuteControl(PGLOBAL_DATA pGlobalData) { MIXERLINE mxln; MIXERCONTROL mxc; MIXERLINECONTROLS mxlctrl; if (pGlobalData->hMixer == NULL) return; mxln.cbStruct = sizeof(MIXERLINE); mxln.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; if (mixerGetLineInfo((HMIXEROBJ)pGlobalData->hMixer, &mxln, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR) return; mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS); mxlctrl.dwLineID = mxln.dwLineID; mxlctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE; mxlctrl.cControls = 1; mxlctrl.cbmxctrl = sizeof(MIXERCONTROL); mxlctrl.pamxctrl = &mxc; if (mixerGetLineControls((HMIXEROBJ)pGlobalData->hMixer, &mxlctrl, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) return; pGlobalData->muteControlID = mxc.dwControlID; }
//得到声音控制 bool SoundControl::GetVolumeControl(HMIXER hmixer, long componentType, long ctrlType, MIXERCONTROL *mxc) { MIXERLINECONTROLS mxlc; MIXERLINE mxl; mxl.cbStruct = sizeof (mxl); mxl.dwComponentType = componentType; if (!mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)) { mxlc.cbStruct = sizeof (mxlc); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = ctrlType; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof (MIXERCONTROL); mxlc.pamxctrl = mxc; if (mixerGetLineControls((HMIXEROBJ)hmixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE)) { return 0; } else { return 1; } } return 0; }
void Mixer::open(unsigned numChannels, unsigned samplingFrequency, unsigned granularityInMS) { HMIXER newHMixer = NULL; do { MIXERCAPS mc; if (mixerGetDevCaps(index, &mc, sizeof mc) != MMSYSERR_NOERROR) break; #ifdef UNICODE // Copy the mixer name: wcstombs(name, mc.szPname, MAXPNAMELEN); #else strncpy(name, mc.szPname, MAXPNAMELEN); #endif // Find the correct line for this mixer: unsigned i, uWavIn; unsigned nWavIn = waveInGetNumDevs(); for (i = 0; i < nWavIn; ++i) { WAVEINCAPS wic; if (waveInGetDevCaps(i, &wic, sizeof wic) != MMSYSERR_NOERROR) continue; MIXERLINE ml; ml.cbStruct = sizeof ml; ml.Target.dwType = MIXERLINE_TARGETTYPE_WAVEIN; #ifdef UNICODE wcsncpy(ml.Target.szPname, wic.szPname, MAXPNAMELEN); #else strncpy(ml.Target.szPname, wic.szPname, MAXPNAMELEN); #endif ml.Target.vDriverVersion = wic.vDriverVersion; ml.Target.wMid = wic.wMid; ml.Target.wPid = wic.wPid; if (mixerGetLineInfo((HMIXEROBJ)index, &ml, MIXER_GETLINEINFOF_TARGETTYPE/*|MIXER_OBJECTF_MIXER*/) == MMSYSERR_NOERROR) { // this is the right line uWavIn = i; dwRecLineID = ml.dwLineID; break; } } if (i >= nWavIn) break; // error: we couldn't find the right line if (mixerOpen(&newHMixer, index, (unsigned long)NULL, (unsigned long)NULL, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR) break; if (newHMixer == NULL) break; // Sanity check: re-call "mixerGetDevCaps()" using the mixer device handle: if (mixerGetDevCaps((UINT)newHMixer, &mc, sizeof mc) != MMSYSERR_NOERROR) break; if (mc.cDestinations < 1) break; // error: this mixer has no destinations if (!WindowsAudioInputDevice_common::openWavInPort(uWavIn, numChannels, samplingFrequency, granularityInMS)) break; hMixer = newHMixer; return; } while (0); // An error occurred: close(); }
bool CVolumeOutMaster::Initialize() { MMRESULT mmResult; if ( !m_bOK ) return false; ssi_wrn (".MasterOutputVolume: Initializing for Source MasterOut Line ..\n" ); MIXERLINE MixerLine; memset( &MixerLine, 0, sizeof(MIXERLINE) ); MixerLine.cbStruct = sizeof(MIXERLINE); MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; mmResult = mixerGetLineInfo( (HMIXEROBJ)m_dwMixerHandle, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); if ( mmResult != MMSYSERR_NOERROR ) { ssi_wrn (".MasterOutputVolume: FAILURE: Could not get Speakers Destionation Line for the MasterOut Source Line while initilaizing. mmResult=%d\n", mmResult ); return false; } MIXERCONTROL Control; memset( &Control, 0, sizeof(MIXERCONTROL) ); Control.cbStruct = sizeof(MIXERCONTROL); MIXERLINECONTROLS LineControls; memset( &LineControls, 0, sizeof(MIXERLINECONTROLS) ); LineControls.cbStruct = sizeof(MIXERLINECONTROLS); LineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; LineControls.dwLineID = MixerLine.dwLineID; LineControls.cControls = 1; LineControls.cbmxctrl = sizeof(MIXERCONTROL); LineControls.pamxctrl = &Control; mmResult = mixerGetLineControls( (HMIXEROBJ)m_dwMixerHandle, &LineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ); if ( mmResult == MMSYSERR_NOERROR ) { if ( !(Control.fdwControl & MIXERCONTROL_CONTROLF_DISABLED) ) { m_bAvailable = true; ssi_wrn (".MasterOutputVolume: \"%s\" Volume control for the Speakers Source Line adopted.\n", Control.szShortName ); } else { ssi_wrn (".MasterOutputVolume: WARNING: The Volume Control is disabled.\n" ); } } else { ssi_wrn (".MasterOutputVolume: WARNING: Could not get the Speakers Source line Volume Control while initilaizing. mmResult=%d\n", mmResult ); } m_nChannelCount = MixerLine.cChannels; m_dwLineID = LineControls.dwLineID; m_dwVolumeControlID = Control.dwControlID; m_dwMinimalVolume = Control.Bounds.dwMinimum; m_dwMaximalVolume = Control.Bounds.dwMaximum; m_dwVolumeStep = Control.Metrics.cSteps; m_bInitialized = true; return true; }
//################################################## //agenttype_mixer_menu_destlines //################################################## void agenttype_mixer_menu_destlines(Menu *menu, control *c, char *action, char *agentname, int format, UINT device, HMIXER mixer_handle, MIXERCAPS &mixer_capabilities) { //Variables MIXERLINE mixer_line; //Count the destination lines UINT count_destlines = mixer_capabilities.cDestinations; if (count_destlines < 1) { make_menuitem_nop(menu, "No destination lines available."); return; } //For every destination line for (UINT destline = 0; destline < count_destlines; destline++) { mixer_line.dwDestination = destline; mixer_line.cbStruct = sizeof(MIXERLINE); mixerGetLineInfo((HMIXEROBJ) mixer_handle, &mixer_line, MIXER_GETLINEINFOF_DESTINATION); //Load the device capabilities if (MMSYSERR_NOERROR == mixerGetLineInfo((HMIXEROBJ) mixer_handle, &mixer_line, MIXER_GETLINEINFOF_DESTINATION)) { //Create a submenu for source lines Menu *submenu; submenu = make_menu(mixer_line.szName, c); //Add the controls int controlcount = agenttype_mixer_menu_linecontrols(submenu, c, action, agentname, format, device, mixer_handle, mixer_line); //Add a spacer if (controlcount > 0) make_menuitem_nop(submenu, ""); //Add the source lines agenttype_mixer_menu_sourcelines(submenu, c, action, agentname, format, device, mixer_handle, mixer_line); make_submenu_item(menu, mixer_line.szName, submenu); } } return; }
void CMicVolume::GetDeviceCtrl(MCS *pData) { MIXERLINE mixer_line; mixer_line.cbStruct = sizeof(MIXERLINE); mixer_line.dwLineID = pData->nLineID; if(mixerGetLineInfo((HMIXEROBJ)h_mix, &mixer_line, MIXER_GETLINEINFOF_LINEID) != MMSYSERR_NOERROR) { #ifdef _DEBUG MessageBox(NULL,"내부함수 수행중 오류(MixerGetLineInfo)", "장치 정보 오류", MB_ICONSTOP); #endif return ; } else if(!mixer_line.cControls) { #ifdef _DEBUG MessageBox(NULL,"사용 가능한 기능 부재", "장치 오류", MB_ICONSTOP); #endif return ; } MIXERLINECONTROLS mixer_line_controls; MIXERCONTROL *mixer_control = (MIXERCONTROL *)LocalAlloc(LPTR, sizeof(MIXERCONTROL)*(unsigned int)mixer_line.cControls); mixer_line_controls.cbStruct = sizeof(MIXERLINECONTROLS); mixer_line_controls.dwLineID = pData->nLineID; mixer_line_controls.cControls = mixer_line.cControls; mixer_line_controls.cbmxctrl = sizeof(MIXERCONTROL); mixer_line_controls.pamxctrl = mixer_control; if(mixerGetLineControls((HMIXEROBJ)h_mix, &mixer_line_controls, MIXER_GETLINECONTROLSF_ALL) != MMSYSERR_NOERROR) { #ifdef _DEBUG MessageBox(NULL,"내부함수 수행중 오류(mixerGetLineControls)", "장치 정보 오류", MB_ICONSTOP); #endif } else { for(unsigned int i = 0; i < mixer_line_controls.cControls; i++){ if(mixer_control[i].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME){ pData->nMax = (int)min(32767, mixer_control[i].Metrics.cSteps - 1); int nPageIncrement = pData->nMax / 10; if(nPageIncrement <= 0) nPageIncrement = 1; nVolStep = (float)(pData->nMax / 9); // 장치의 카운터 적용 //if(pDevice != NULL) pDevice->SetRange(0, pData->nMax, TRUE); //if(pDevice != NULL && pData->nMax > 50) pDevice->SetTicFreq(5); //vol pData->m_ctlMixerSpeaker = mixer_control[i]; } else if (mixer_control[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE){ pData->m_ctlMixerMute = mixer_control[i]; } } } LocalFree((HLOCAL)mixer_control); }
int getMixerLineByDestination(HMIXER handle, DWORD dstIndex, MIXERLINE* mixerLine) { mixerLine->cbStruct = sizeof(MIXERLINE); mixerLine->dwDestination = dstIndex; if (mixerGetLineInfo((HMIXEROBJ) handle, mixerLine, MIXER_GETLINEINFOF_DESTINATION | MIXER_OBJECTF_HMIXER ) == MMSYSERR_NOERROR) { return TRUE; } mixerLine->cControls = 0; mixerLine->cConnections = 0; return FALSE; }
int getMixerLineByType(HMIXER handle, DWORD linetype, MIXERLINE* mixerLine) { mixerLine->cbStruct = sizeof(MIXERLINE); mixerLine->dwComponentType = linetype; if (mixerGetLineInfo((HMIXEROBJ) handle, mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE | MIXER_OBJECTF_HMIXER ) == MMSYSERR_NOERROR) { return TRUE; } mixerLine->cControls = 0; mixerLine->cConnections = 0; return FALSE; }
static void initMixerLine(mixerdata_t* mix, DWORD type) { memset(mix, 0, sizeof(*mix)); mix->line.cbStruct = sizeof(mix->line); mix->line.dwComponentType = type; if((res = mixerGetLineInfo((HMIXEROBJ) mixer, &mix->line, MIXER_GETLINEINFOF_COMPONENTTYPE)) != MMSYSERR_NOERROR) { if(verbose) Con_Message(" Error getting line info: Error %i", res); return; } if(verbose) { Con_Message(" Destination line idx: %i", mix->line.dwDestination); Con_Message(" Line ID: 0x%x", mix->line.dwLineID); Con_Message(" Channels: %i", mix->line.cChannels); Con_Message(" Controls: %i", mix->line.cControls); Con_Message(" Name: %s (%s)", mix->line.szName, mix->line.szShortName); } mix->controls.cbStruct = sizeof(mix->controls); mix->controls.dwLineID = mix->line.dwLineID; mix->controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mix->controls.cControls = 1; mix->controls.cbmxctrl = sizeof(mix->volume); mix->controls.pamxctrl = &mix->volume; if((res = mixerGetLineControls((HMIXEROBJ) mixer, &mix->controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)) != MMSYSERR_NOERROR) { if(verbose) Con_Message(" Error getting line controls " "(vol): error %i", res); return; } if(verbose) { Con_Message(" Volume control ID: 0x%x", mix->volume.dwControlID); Con_Message(" Name: %s (%s)", mix->volume.szName, mix->volume.szShortName); Con_Message(" Min/Max: %i/%i", mix->volume.Bounds.dwMinimum, mix->volume.Bounds.dwMaximum); } // This mixer line is now available. mix->available = true; }
void play() { int targetval = 65535; if (volume != 100) { targetval = (int)((volume / 100.0) * 65535); } //credits to http://www.codeproject.com/Articles/4754/mixerSetControlDetails printf("creating mixer,volume = %d, targetval = %d\n",volume,targetval); /* obtain handle to mixer device */ MMRESULT result; HMIXER hMixer; result = mixerOpen(&hMixer, MIXER_OBJECTF_MIXER, 0, 0, 0); /* get speaker line of the mixer device */ MIXERLINE ml = { 0 }; ml.cbStruct = sizeof(MIXERLINE); ml.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; result = mixerGetLineInfo((HMIXEROBJ)hMixer,&ml, MIXER_GETLINEINFOF_COMPONENTTYPE); /* get colume control of the speaker line */ MIXERLINECONTROLS mlc = { 0 }; MIXERCONTROL mc = { 0 }; mlc.cbStruct = sizeof(MIXERLINECONTROLS); mlc.dwLineID = ml.dwLineID; mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mlc.cControls = 1; mlc.pamxctrl = &mc; mlc.cbmxctrl = sizeof(MIXERCONTROL); result = mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); /* set the volume level */ MIXERCONTROLDETAILS mcd = { 0 }; MIXERCONTROLDETAILS_UNSIGNED mcdu = { 0 }; mcdu.dwValue = targetval; // the volume is a number between 0 and 65535 mcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mcd.hwndOwner = 0; mcd.dwControlID = mc.dwControlID; mcd.paDetails = &mcdu; mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mcd.cChannels = 1; result = mixerSetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_SETCONTROLDETAILSF_VALUE); PlaySound(filename, NULL, SND_FILENAME); }
BOOL CMixOut::Initialize() { if (m_hMixer) { TRACE("You haven't open the mixer.\n"); return FALSE; } MIXERLINE MixerLine; memset( &MixerLine, 0, sizeof(MIXERLINE) ); MixerLine.cbStruct = sizeof(MIXERLINE); MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; m_mmr = mixerGetLineInfo( (HMIXEROBJ)m_hMixer, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); if ( m_mmr != MMSYSERR_NOERROR ) { return false; } MIXERCONTROL Control; memset( &Control, 0, sizeof(MIXERCONTROL) ); Control.cbStruct = sizeof(MIXERCONTROL); MIXERLINECONTROLS LineControls; memset( &LineControls, 0, sizeof(MIXERLINECONTROLS) ); LineControls.cbStruct = sizeof(MIXERLINECONTROLS); LineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; LineControls.dwLineID = MixerLine.dwLineID; LineControls.cControls = 1; LineControls.cbmxctrl = sizeof(MIXERCONTROL); LineControls.pamxctrl = &Control; m_mmr = mixerGetLineControls( (HMIXEROBJ)m_hMixer, &LineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ); if ( m_mmr == MMSYSERR_NOERROR ) { if ((Control.fdwControl & MIXERCONTROL_CONTROLF_DISABLED) ) { return FALSE; } } else { return FALSE; } m_dwMinimalVolume = Control.Bounds.dwMinimum; m_dwMaximalVolume = Control.Bounds.dwMaximum; return TRUE; }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: _print_src_lines // Description: This function prints in the screen the source lines present //-------------------------------------------------------------------------------------- void SoundResources::_print_src_lines() { for (int i = 0; i < m_numSrc; i++) { m_mixerLine.cbStruct = sizeof(MIXERLINE); m_mixerLine.dwSource = i; if (!(m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_SOURCE))) { if (m_mixerLine.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER) printf("\t\t#%lu: %s\n", i, m_mixerLine.szName); } } }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: _print_dst_lines // Description: This function prints in the screen the source lines present //-------------------------------------------------------------------------------------- void SoundResources::_print_dst_lines() { MIXERCAPS mixerCaps; mixerGetDevCaps(0,&mixerCaps, sizeof(mixerCaps)); for (int i = 0; i < mixerCaps.cDestinations; i++) { m_mixerLine.cbStruct = sizeof(MIXERLINE); m_mixerLine.dwSource = 0; m_mixerLine.dwDestination = i; if (!(m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_DESTINATION))) { printf("\t#%lu: %s\n", i, m_mixerLine.szName); } m_numSrc = m_mixerLine.cConnections; _print_src_lines(); } }
BOOL CMicVolume::GetDevice() { MIXERCAPS mixer_caps; MIXERLINE mixer_line; if(mixerGetDevCaps((unsigned int)h_mix, &mixer_caps, sizeof(mixer_caps)) != MMSYSERR_NOERROR) { #ifdef _DEBUG MessageBox(NULL, "등록된 장치의 정보를 읽을 수 없습니다.", "시스템 정보 오류", MB_ICONSTOP); #endif mixer_caps.cDestinations = 0; return FALSE; } for(unsigned int i = 0; i < mixer_caps.cDestinations; i++){ mixer_line.cbStruct = sizeof(mixer_line); mixer_line.dwDestination = i; if(mixerGetLineInfo((HMIXEROBJ)h_mix, &mixer_line, MIXER_GETLINEINFOF_DESTINATION) != MMSYSERR_NOERROR) continue; if(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS == mixer_line.dwComponentType){ m_WavOut.nDeviceNum = (short)mixer_line.cConnections; m_WavOut.nIndex = (short)i; m_WavOut.nLineID = mixer_line.dwLineID; strcpy(m_WavOut.DeviceName, mixer_line.szName); //GetDeviceCtrl(&m_WavOut, &m_ctlSpeaker); } else if(MIXERLINE_COMPONENTTYPE_DST_WAVEIN == mixer_line.dwComponentType){ m_WavIn.nDeviceNum = (short)mixer_line.cConnections; m_WavIn.nIndex = (short)i; m_WavIn.nLineID = mixer_line.dwLineID; strcpy(m_WavIn.DeviceName, mixer_line.szName); } } GetMicDevice(); if(VolDevice(&m_MicIn) < 0) { return FALSE; } return TRUE; }
BOOL CMyVolume::GetVolumeControl(HMIXER hmixer ,long componentType,long ctrlType,MIXERCONTROL* mxc) { MIXERLINE mxl; mxl.cbStruct = sizeof(mxl); mxl.dwComponentType = componentType; if (MMSYSERR_NOERROR == mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)) { MIXERLINECONTROLS mxls; mxls.cbStruct = sizeof(mxls); mxls.dwLineID = mxl.dwLineID; mxls.dwControlType = ctrlType; mxls.cControls = 1; mxls.cbmxctrl = sizeof(MIXERCONTROL); mxls.pamxctrl = mxc; if (MMSYSERR_NOERROR == mixerGetLineControls((HMIXEROBJ)hmixer, &mxls, MIXER_GETLINECONTROLSF_ONEBYTYPE )) { return TRUE; } } return FALSE; }
//返回音量值 unsigned WINAPI GetVolume() { unsigned rt=0; MIXERCONTROL volCtrl; HMIXER hmixer; if(mixerOpen(&hmixer, 0, 0, 0, 0)) return 0; MIXERLINE mxl = {0}; mxl.cbStruct = sizeof(mxl); mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; MMRESULT mr = mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_DESTINATION); mixerGetLineControls() if(!GetVolumeControl(hmixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,MIXERCONTROL_CONTROLTYPE_VOLUME,&volCtrl)) return 0; int ChangeValue=volCtrl.Bounds.lMaximum/INTERVAL; //每一次调用函数改变的音量值 rt=GetVolumeValue(hmixer,&volCtrl)/ChangeValue; //GetVolumeValue得到的是具体值 mixerClose(hmixer); return rt; }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: (public)_select_line // Description: This method sets the active source line in the m_mixer_line variable. The idea // is that externally one can chose the source line (microfone, in line...etc). Then, by // chosing the control type (volume, mute, on/off) one can control the selected line. //-------------------------------------------------------------------------------------- int SoundResources::_select_line(unsigned int type) { for(int i = 0; i < m_numSrc; i++) { m_mixerLine.cbStruct = sizeof(MIXERLINE); m_mixerLine.dwSource = i; m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_SOURCE); if (m_err != MMSYSERR_NOERROR) continue; if (m_mixerLine.dwComponentType == type) { printf("yarpsounddriver: source line found\n"); return YARP_OK; } } printf("yarpsounddriver: -warning- source line not found\n"); return YARP_FAIL; }
void CMicVolume::GetMicDevice() { MIXERCAPS mixer_caps; MIXERLINE mixer_line; mixerGetDevCaps((unsigned int)h_mix, &mixer_caps, sizeof(mixer_caps)); for(int i = 0; i < m_WavIn.nDeviceNum; i++){ mixer_line.cbStruct = sizeof(mixer_line); mixer_line.dwDestination = m_WavIn.nIndex; mixer_line.dwSource = i; if(mixerGetLineInfo((HMIXEROBJ)h_mix, &mixer_line, MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR) continue; if(mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) { m_MicIn.nIndex = (short)i; m_MicIn.nLineID = mixer_line.dwLineID; GetDeviceCtrl(&m_MicIn); break; } } }
bool GetVolumeControl(HMIXER hmixer ,long componentType,long ctrlType,MIXERCONTROL* mxc) { MIXERLINECONTROLS mxlc; MIXERLINE mxl; mxl.cbStruct = sizeof(mxl); mxl.dwComponentType = componentType; MMRESULT mr = mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE); if(MMSYSERR_NOERROR == mr) { mxlc.cbStruct = sizeof(mxlc); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = ctrlType; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = mxc; if(mixerGetLineControls((HMIXEROBJ)hmixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE)) return 0; else return 1; } return 0; }
//################################################## //agenttype_mixer_menu_sourcelines //################################################## void agenttype_mixer_menu_sourcelines(Menu *menu, control *c, char *action, char *agentname, int format, UINT device, HMIXER mixer_handle, MIXERLINE &mixer_destline) { //Variables MIXERLINE mixer_line; //Count the devices UINT count_sourcelines = mixer_destline.cConnections; if (count_sourcelines < 1) { make_menuitem_nop(menu, "No source lines available."); return; } //For every source line for (UINT sourceline = 0; sourceline < count_sourcelines; sourceline++) { mixer_line.cbStruct = sizeof(MIXERLINE); mixer_line.dwDestination = mixer_destline.dwDestination; mixer_line.dwSource = sourceline; //Load the device capabilities if (MMSYSERR_NOERROR == mixerGetLineInfo((HMIXEROBJ) mixer_handle, &mixer_line, MIXER_GETLINEINFOF_SOURCE)) { //Create a submenu for source lines Menu *submenu; submenu = make_menu(mixer_line.szName, c); int controlcount = agenttype_mixer_menu_linecontrols(submenu, c, action, agentname, format, device, mixer_handle, mixer_line); if (controlcount == 0) { make_menuitem_nop(submenu, "No options available for this item."); } make_submenu_item(menu, mixer_line.szName, submenu); } } return; }
static DWORD find_ctrl(HMIXEROBJ mixer, DWORD lineID, DWORD ctrlID) { MMRESULT res; MIXERLINE line; MIXERLINECONTROLS controls; MIXERCONTROL control; line.cbStruct = sizeof(MIXERLINE); line.dwComponentType = lineID; res = mixerGetLineInfo(mixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE); if (res != MMSYSERR_NOERROR) { return -1; } controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = line.dwLineID; controls.dwControlType = ctrlID; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = &control; control.cbStruct = sizeof(MIXERCONTROL); res = mixerGetLineControls(mixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (res != MMSYSERR_NOERROR) { return -1; } return control.dwControlID; }
int main(int argc , char ** argv) { MMRESULT err; WAVEFORMATEX waveFormat; MIXERLINE mixerLine; HANDLE waveInThread; unsigned long n, numSrc; waveInThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)waveInProc, 0, 0, &err); if (!waveInThread) { printf("Can't create WAVE recording thread! -- %08X\n", GetLastError()); return(-1); } CloseHandle(waveInThread); ZeroMemory(&WaveHeader[0], sizeof(WAVEHDR) * 2); waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = 2; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nBlockAlign = waveFormat.nChannels * (waveFormat.wBitsPerSample/8); waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; err = waveInOpen(&WaveInHandle, WAVE_MAPPER, &waveFormat, (DWORD)err, 0, CALLBACK_THREAD); if (err) { PrintWaveErrorMsg(err, "Can't open WAVE In Device!"); return(-2); } else { err = mixerOpen(&MixerHandle, (DWORD)WaveInHandle, 0, 0, MIXER_OBJECTF_HWAVEIN); if (err) { printf("Device does not have mixer support! -- %08X\n", err); } else { mixerLine.cbStruct = sizeof(MIXERLINE); mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; err = mixerGetLineInfo((HMIXEROBJ)MixerHandle, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE); if (err) { printf("Device does not have a WAVE recording control! -- %08X\n", err); goto record; } numSrc = mixerLine.cConnections; mixerLine.dwSource = mixerLine.dwDestination; set_mute(&mixerLine, 1, ERRMSG_NONE); /* Make sure that there is at least one WAVEIN source line available. If not, then just go with the * WAVEIN master volume and mute above */ if (!numSrc) { printf("ERROR: There are no WAVE inputs to adjust!\n"); goto record; } remute: printf("The device has the following WAVE inputs. Choose which one to mute,\nor press ENTER to start recording.\n\n"); /* Print the names of the source lines for the MIXERLINE_COMPONENTTYPE_DST_WAVEIN destination. But, * omit any MIDI In */ for (n = 0; n < numSrc; n++) { mixerLine.cbStruct = sizeof(MIXERLINE); mixerLine.dwSource = n; if (!(err = mixerGetLineInfo((HMIXEROBJ)MixerHandle, &mixerLine, MIXER_GETLINEINFOF_SOURCE))) { if (mixerLine.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER) printf("\t#%lu: %s\n", n, mixerLine.szName); } } /* Get his choice of source line to mute, or ENTER to continue with recording */ { TCHAR buffer[3]; fgets(&buffer[0], 3, stdin); if (buffer[0] >= '1' && buffer[0] <= '9') { buffer[0] -= '1'; if ((unsigned long)buffer[0] < numSrc) { mixerLine.cbStruct = sizeof(MIXERLINE); mixerLine.dwSource = buffer[0]; mixerGetLineInfo((HMIXEROBJ)MixerHandle, &mixerLine, MIXER_GETLINEINFOF_SOURCE); set_mute(&mixerLine, 0, ERRMSG_PRINT); } /* Go back to check for more muted sources */ goto remute; } } record: mixerClose(MixerHandle); } WaveFileHandle = CreateFile("test.snd", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (WaveFileHandle == INVALID_HANDLE_VALUE) { printf("Can't create test.snd disk file!\n"); } else { WaveHeader[1].dwBufferLength = WaveHeader[0].dwBufferLength = waveFormat.nAvgBytesPerSec << 1; if (!(WaveHeader[0].lpData = (char *)VirtualAlloc(0, WaveHeader[0].dwBufferLength * 2, MEM_COMMIT, PAGE_READWRITE))) { printf("ERROR: Can't allocate memory for WAVE buffer!\n"); } else { WaveHeader[1].lpData = WaveHeader[0].lpData + WaveHeader[0].dwBufferLength; if ((err = waveInPrepareHeader(WaveInHandle, &WaveHeader[0], sizeof(WAVEHDR)))) { printf("Error preparing WAVEHDR 1! -- %08X\n", err); } else { if ((err = waveInPrepareHeader(WaveInHandle, &WaveHeader[1], sizeof(WAVEHDR)))) { printf("Error preparing WAVEHDR 2! -- %08X\n", err); } else { /* Queue first WAVEHDR (recording hasn't started yet) */ if ((err = waveInAddBuffer(WaveInHandle, &WaveHeader[0], sizeof(WAVEHDR)))) { printf("Error queueing WAVEHDR 1! -- %08X\n", err); } else { if ((err = waveInAddBuffer(WaveInHandle, &WaveHeader[1], sizeof(WAVEHDR)))) { printf("Error queueing WAVEHDR 2! -- %08X\n", err); DoneAll = 1; goto abort; } else { //record InRecord = TRUE; if ((err = waveInStart(WaveInHandle))) { printf("Error starting record! -- %08X\n", err); } else { printf("Recording has started. Press ENTER key to stop recording...\n"); getchar(); } /* Tell our recording thread not to queue any WAVEHDRs it gets back via MM_WIM_DONE */ abort: InRecord = FALSE; waveInReset(WaveInHandle); while (DoneAll < 2) Sleep(100); } } if ((err = waveInPrepareHeader(WaveInHandle, &WaveHeader[1], sizeof(WAVEHDR)))) { printf("Error unpreparing WAVEHDR 2! -- %08X\n", err); } } if ((err = waveInPrepareHeader(WaveInHandle, &WaveHeader[0], sizeof(WAVEHDR)))) { printf("Error unpreparing WAVEHDR 1! -- %08X\n", err); } } } } } /* Close the WAVE In device */ do { err = waveInClose(WaveInHandle); if (err) PrintWaveErrorMsg(err, "Can't close WAVE In Device!"); } while (err); /* Close the disk file if it opened */ if (WaveFileHandle != INVALID_HANDLE_VALUE) CloseHandle(WaveFileHandle); /* Free any memory allocated for our buffers */ if (WaveHeader[0].lpData) VirtualFree(WaveHeader[0].lpData, 0, MEM_RELEASE); return(0); }
static void gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc) { gint i, k; gboolean found_mic; MMRESULT mmres; MIXERCAPS mixer_caps; MIXERLINE mixer_line; MIXERLINECONTROLS ml_ctrl; PMIXERCONTROL pamixer_ctrls; if (!gst_directsound_src_mixer_find (dsoundsrc, &mixer_caps)) goto mixer_init_fail; /* Find the MIXERLINE related to MICROPHONE */ found_mic = FALSE; for (i = 0; i < mixer_caps.cDestinations && !found_mic; i++) { gint j, num_connections; mixer_line.cbStruct = sizeof (mixer_line); mixer_line.dwDestination = i; mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer, &mixer_line, MIXER_GETLINEINFOF_DESTINATION); if (mmres != MMSYSERR_NOERROR) goto mixer_init_fail; num_connections = mixer_line.cConnections; for (j = 0; j < num_connections && !found_mic; j++) { mixer_line.cbStruct = sizeof (mixer_line); mixer_line.dwDestination = i; mixer_line.dwSource = j; mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer, &mixer_line, MIXER_GETLINEINFOF_SOURCE); if (mmres != MMSYSERR_NOERROR) goto mixer_init_fail; if (mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE || mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LINE) found_mic = TRUE; } } if (found_mic == FALSE) { GST_DEBUG ("Can't find mixer line related to input"); goto mixer_init_fail; } /* Get control associated with microphone audio line */ pamixer_ctrls = g_malloc (sizeof (MIXERCONTROL) * mixer_line.cControls); ml_ctrl.cbStruct = sizeof (ml_ctrl); ml_ctrl.dwLineID = mixer_line.dwLineID; ml_ctrl.cControls = mixer_line.cControls; ml_ctrl.cbmxctrl = sizeof (MIXERCONTROL); ml_ctrl.pamxctrl = pamixer_ctrls; mmres = mixerGetLineControls ((HMIXEROBJ) dsoundsrc->mixer, &ml_ctrl, MIXER_GETLINECONTROLSF_ALL); /* Find control associated with volume and mute */ for (k = 0; k < mixer_line.cControls; k++) { if (strstr (pamixer_ctrls[k].szName, "Volume") != NULL) { dsoundsrc->control_id_volume = pamixer_ctrls[k].dwControlID; dsoundsrc->dw_vol_max = pamixer_ctrls[k].Bounds.dwMaximum; dsoundsrc->dw_vol_min = pamixer_ctrls[k].Bounds.dwMinimum; } else if (strstr (pamixer_ctrls[k].szName, "Mute") != NULL) { dsoundsrc->control_id_mute = pamixer_ctrls[k].dwControlID; } else { GST_DEBUG ("Control not handled: %s", pamixer_ctrls[k].szName); } } g_free (pamixer_ctrls); if (dsoundsrc->control_id_volume < 0 && dsoundsrc->control_id_mute < 0) goto mixer_init_fail; /* Save cChannels information to properly changes in volume */ dsoundsrc->mixerline_cchannels = mixer_line.cChannels; return; mixer_init_fail: GST_WARNING ("Failed to get Volume and Mute controls"); if (dsoundsrc->mixer != NULL) { mixerClose (dsoundsrc->mixer); dsoundsrc->mixer = NULL; } }
static BOOL SndMixerQueryDestinations(PSND_MIXER Mixer) { UINT i; BOOL Ret = TRUE; for (i = Mixer->Caps.cDestinations; i > 0; i--) { PSND_MIXER_DESTINATION Line; Line = (SND_MIXER_DESTINATION*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SND_MIXER_DESTINATION)); if (Line != NULL) { Line->Info.cbStruct = sizeof(Line->Info); Line->Info.dwDestination = i - 1; if (mixerGetLineInfo((HMIXEROBJ)Mixer->hmx, &Line->Info, MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR) { DPRINT("+ Destination: %ws (0x%x, %d)\n", Line->Info.szName, Line->Info.dwLineID, Line->Info.dwComponentType); if (!SndMixerQueryControls(Mixer, &Line->DisplayControls, &Line->Info, &Line->Controls)) { DPRINT("Failed to query mixer controls!\n"); Ret = FALSE; break; } if (!SndMixerQueryConnections(Mixer, Line)) { DPRINT("Failed to query mixer connections!\n"); Ret = FALSE; break; } Line->Next = Mixer->Lines; Mixer->Lines = Line; } else { DPRINT("Failed to get line information for id %d!\n", i); HeapFree(GetProcessHeap(), 0, Line); Ret = FALSE; break; } } else { DPRINT("Allocation of SND_MIXER_DEST structure for id %d failed!\n", i); Ret = FALSE; break; } } return Ret; }
static BOOL SndMixerQueryConnections(PSND_MIXER Mixer, PSND_MIXER_DESTINATION Line) { UINT i, DispControls; MIXERLINE LineInfo; MMRESULT Result; BOOL Ret = TRUE; LineInfo.cbStruct = sizeof(LineInfo); for (i = Line->Info.cConnections; i > 0; i--) { LineInfo.dwDestination = Line->Info.dwDestination; LineInfo.dwSource = i - 1; Result = mixerGetLineInfo((HMIXEROBJ)Mixer->hmx, &LineInfo, MIXER_GETLINEINFOF_SOURCE); if (Result == MMSYSERR_NOERROR) { LPMIXERCONTROL Controls = NULL; PSND_MIXER_CONNECTION Con; DPRINT("++ Source: %ws\n", LineInfo.szName); DispControls = 0; if (!SndMixerQueryControls(Mixer, &DispControls, &LineInfo, &Controls)) { DPRINT("Failed to query connection controls\n"); Ret = FALSE; break; } Con = (SND_MIXER_CONNECTION*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SND_MIXER_CONNECTION)); if (Con != NULL) { Con->Info = LineInfo; Con->Controls = Controls; Con->DisplayControls = DispControls; Con->Next = Line->Connections; Line->Connections = Con; } else { HeapFree(GetProcessHeap(), 0, Controls); } } else { DPRINT("Failed to get connection information: %d\n", Result); Ret = FALSE; break; } } return Ret; }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: (protected) _init // Description: This is the internal class init method //-------------------------------------------------------------------------------------- int SoundResources::_init (const SoundOpenParameters& params) { //---------------------------------------------------------------------- // Initalize local parameters with the open params. It the open param // is != 0 then the local param is updated if not the default value is // used. // Default configuration: // 16-bit, 44KHz, stereo //---------------------------------------------------------------------- if (params.m_Channels != 0) channels = params.m_Channels; if (params.m_SamplesPerSec != 0) freqSample = params.m_SamplesPerSec; if (params.m_BitsPerSample != 0) nBitsSample = params.m_BitsPerSample; if (params.m_BufferLength != 0) dwBufferLength = params.m_BufferLength; //---------------------------------------------------------------------- // Initialize the wave in //---------------------------------------------------------------------- m_waveFormat.wFormatTag = WAVE_FORMAT_PCM; m_waveFormat.nChannels = channels; m_waveFormat.nSamplesPerSec = freqSample; m_waveFormat.wBitsPerSample = nBitsSample; m_waveFormat.nBlockAlign = m_waveFormat.nChannels * (m_waveFormat.wBitsPerSample/8); m_waveFormat.nAvgBytesPerSec = m_waveFormat.nSamplesPerSec * m_waveFormat.nBlockAlign; m_waveFormat.cbSize = 0; m_err = waveInOpen(&m_WaveInHandle, WAVE_MAPPER, &m_waveFormat, (DWORD)params.m_callbackthread_identifier, //Here I have to add the thread ID (DWORD)this, CALLBACK_THREAD); if (m_err != MMSYSERR_NOERROR) { printf("Can't open WAVE In Device! %d",m_err); return(-2); } //---------------------------------------------------------------------- // Initialize Mixter //---------------------------------------------------------------------- m_err = mixerOpen(&m_MixerHandle, (DWORD)m_WaveInHandle, 0, 0, MIXER_OBJECTF_HWAVEIN); if (m_err != MMSYSERR_NOERROR) { printf("yarpsounddriver: Device does not have mixer support! -- %08X\n", m_err); } //---------------------------------------------------------------------- // Print all the present lines in the audio interface //---------------------------------------------------------------------- printf("yarpsounddriver: LINES PRESENT\n"); _print_dst_lines(); //---------------------------------------------------------------------- // This device should have a WAVEIN destination line. Let's get its ID so // that we can determine what source lines are available to record from //---------------------------------------------------------------------- m_mixerLine.cbStruct = sizeof(MIXERLINE); m_mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE); if (m_err != MMSYSERR_NOERROR) { printf("Device does not have a WAVE recording control! -- %08X\n", m_err); } m_numSrc = m_mixerLine.cConnections; // Get how many source lines are available from which to record. m_err = _select_line(MIXERLINE_COMPONENTTYPE_SRC_LINE); //select default source line if (m_err == YARP_FAIL){ //Not line found, trying the auxiliary.... m_err = _select_line(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY); } if (m_err != YARP_OK) printf("yarpsounddriver: Atention Source line not found!!!\n"); //---------------------------------------------------------------------- // Initialize the local buffers //---------------------------------------------------------------------- _bmutex.Wait (); _rawBuffer = new unsigned char [dwBufferLength]; ACE_ASSERT (_rawBuffer != NULL); _bmutex.Post (); return YARP_OK; }
int SelectRecordingLine(unsigned int nMixerId, unsigned int nComponentID, char *user_mixer_line, unsigned int nLeftVolume, unsigned int nRightVolume) { // check windows version because this can't work on VIsta and Windows 7 OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if(GetVersionEx(&osvi) == 0) return 1; // don't fail, just exit function // check if we have Vista or WIndows / if(osvi.dwMajorVersion > 5) return 1; unsigned int dwVolumeControlID = 0; unsigned int dwControlType = 0; unsigned int dwSelectControlID = 0; unsigned int dwMultipleItems = 0; unsigned int dwIndex = 0xFFFFFFFF; HMIXER hMixer = NULL; MIXERCAPS mxcaps; ::ZeroMemory(&mxcaps, sizeof(MIXERCAPS)); if(nComponentID >= WAVE_IN_NUM) return 0; // open mixer if(mixerOpen(&hMixer, (unsigned int) nMixerId, 0, 0, MIXER_OBJECTF_HWAVEIN) != MMSYSERR_NOERROR) return 0; if(mixerGetDevCaps((unsigned int) hMixer, &mxcaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR) { ::mixerClose(hMixer); return 0; } // get control we need if (hMixer == NULL) return 0; // get dwLineID MIXERLINE mxl; mxl.cbStruct = sizeof(MIXERLINE); mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; if (mixerGetLineInfo((HMIXEROBJ) hMixer, &mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR) { mixerClose(hMixer); return 0; } // get dwControlID MIXERCONTROL mxc; MIXERLINECONTROLS mxlc; dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER; mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = dwControlType; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if (mixerGetLineControls((HMIXEROBJ) hMixer, &mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) { // no mixer, try MUX dwControlType = MIXERCONTROL_CONTROLTYPE_MUX; mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = dwControlType; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if (mixerGetLineControls((HMIXEROBJ) hMixer, &mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) { mixerClose(hMixer); return 0; } } // store dwControlID, cMultipleItems dwSelectControlID = mxc.dwControlID; dwMultipleItems = mxc.cMultipleItems; if (dwMultipleItems == 0) { mixerClose(hMixer); return 0; } DWORD dwControlID = 0; DWORD dwLine = 0; // get the index of the specified Select control MIXERCONTROLDETAILS_LISTTEXT *pmxcdSelectText = new MIXERCONTROLDETAILS_LISTTEXT[dwMultipleItems]; DWORD dwi = 0; if (pmxcdSelectText != NULL) { MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = dwSelectControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = dwMultipleItems; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT); mxcd.paDetails = pmxcdSelectText; if (mixerGetControlDetails((HMIXEROBJ) hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_LISTTEXT) == MMSYSERR_NOERROR) { for (dwi = 0; dwi < dwMultipleItems; dwi++) { // get the line information MIXERLINE mxl; mxl.cbStruct = sizeof(MIXERLINE); mxl.dwLineID = pmxcdSelectText[dwi].dwParam1; if (mixerGetLineInfo((HMIXEROBJ) hMixer, &mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_LINEID) == MMSYSERR_NOERROR && mxl.dwComponentType == g_wavein_id[nComponentID].id) { // check specified user name if(user_mixer_line) { if(strcmp(user_mixer_line, mxl.szShortName) != 0 && strcmp(user_mixer_line, mxl.szName) != 0) continue; } // found, dwi is the index. dwIndex = dwi; dwLine = pmxcdSelectText[dwIndex].dwParam1; break; } } if (dwi >= dwMultipleItems) { if(user_mixer_line) { // could not find it using line IDs, some mixer drivers have // different meaning for MIXERCONTROLDETAILS_LISTTEXT.dwParam1. // let's try comparing the item names. for (dwi = 0; dwi < dwMultipleItems; dwi++) { if (stricmp(pmxcdSelectText[dwi].szName, user_mixer_line) == 0) { // found, dwi is the index. dwIndex = dwi; dwLine = pmxcdSelectText[dwIndex].dwParam1; break; } } // error if (dwi >= dwMultipleItems) { mixerClose(hMixer); delete []pmxcdSelectText; return 0; } } } if (dwi >= dwMultipleItems) { // could not find it using line IDs, some mixer drivers have // different meaning for MIXERCONTROLDETAILS_LISTTEXT.dwParam1. // let's try comparing the item names. for (dwi = 0; dwi < dwMultipleItems; dwi++) { if (stricmp(pmxcdSelectText[dwi].szName, g_wavein_id[nComponentID].string_name1) == 0) { // found, dwi is the index. dwIndex = dwi; dwLine = pmxcdSelectText[dwIndex].dwParam1; break; } } } if (dwi >= dwMultipleItems) { // could not find it using line IDs, some mixer drivers have // different meaning for MIXERCONTROLDETAILS_LISTTEXT.dwParam1. // let's try comparing the item names. for (dwi = 0; dwi < dwMultipleItems; dwi++) { if (stricmp(pmxcdSelectText[dwi].szName, g_wavein_id[nComponentID].string_name2) == 0) { // found, dwi is the index. dwIndex = dwi; dwLine = pmxcdSelectText[dwIndex].dwParam1; break; } } } if (dwi >= dwMultipleItems) { // could not find it using line IDs, some mixer drivers have // different meaning for MIXERCONTROLDETAILS_LISTTEXT.dwParam1. // let's try comparing the item names. for (dwi = 0; dwi < dwMultipleItems; dwi++) { if (stricmp(pmxcdSelectText[dwi].szName, g_wavein_id[nComponentID].string_name3) == 0) { // found, dwi is the index. dwIndex = dwi; dwLine = pmxcdSelectText[dwIndex].dwParam1; break; } } } } delete []pmxcdSelectText; } // select component if (dwIndex >= dwMultipleItems) { mixerClose(hMixer); return 0; } // get the line information int ret = 0; // get all the values first MIXERCONTROLDETAILS_BOOLEAN *pmxcdSelectValue = new MIXERCONTROLDETAILS_BOOLEAN[dwMultipleItems]; if (pmxcdSelectValue != NULL) { // select control MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = dwSelectControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = dwMultipleItems; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); mxcd.paDetails = pmxcdSelectValue; if (mixerGetControlDetails((HMIXEROBJ) hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR) { // MUX restricts the line selection to one source line at a time. if (dwControlType == MIXERCONTROL_CONTROLTYPE_MUX) ZeroMemory(pmxcdSelectValue, dwMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN)); // set the value pmxcdSelectValue[dwIndex].fValue = 1; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = dwSelectControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = dwMultipleItems; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); mxcd.paDetails = pmxcdSelectValue; if (mixerSetControlDetails((HMIXEROBJ) hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR) { ret = 1; } } delete []pmxcdSelectValue; } // set volume, if volume is larger than 100 skip volume change if(nLeftVolume <= 100 && nRightVolume <= 100) { mxl.cbStruct = sizeof(MIXERLINE); mxl.dwLineID = dwLine; if (mixerGetLineInfo((HMIXEROBJ) hMixer, &mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_LINEID) == MMSYSERR_NOERROR) { mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = dwLine; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if (mixerGetLineControls((HMIXEROBJ) hMixer, &mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) { if(nLeftVolume > 100) nLeftVolume = 100; if(nRightVolume > 100) nRightVolume = 100; MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[2] = { mxc.Bounds.dwMaximum * nLeftVolume / 100, mxc.Bounds.dwMaximum * nRightVolume / 100}; MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = mxc.dwControlID; mxcd.cChannels = mxl.cChannels; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.paDetails = mxcdVolume; if (mixerSetControlDetails((HMIXEROBJ) hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) { // error, can't set volume } } else { // error can't set volume } } } mixerClose(hMixer); return ret; }
/* ------------------------------------------------------------------------------------ */ CMixer::CMixer(HWND hwnd, DWORD DstType, DWORD SrcType, DWORD ControlType) : m_HMixer(NULL), m_iMixerControlID(0), mmr(MMSYSERR_NOERROR), m_dwChannels(0), m_bSuccess(FALSE) { if(mixerGetNumDevs() < 1) return; mmr = mixerOpen(&m_HMixer, 0, reinterpret_cast<DWORD>(hwnd), 0L, CALLBACK_WINDOW); if(mmr != MMSYSERR_NOERROR) return; // get dwLineID MIXERLINE mxl; mxl.cbStruct = sizeof(MIXERLINE); // DstType mxl.dwComponentType = DstType; if(mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(m_HMixer), &mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR) return; // SrcType if(SrcType != NO_SOURCE) { UINT nconn = mxl.cConnections; DWORD DstIndex = mxl.dwDestination; for(UINT j=0; j<nconn; ++j) { mxl.cbStruct = sizeof(MIXERLINE); mxl.dwSource = j; mxl.dwDestination = DstIndex; if(mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(m_HMixer), &mxl, MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR) return; if(mxl.dwComponentType == SrcType) break; } } // get dwControlID MIXERCONTROL mxc; MIXERLINECONTROLS mxlc; mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = ControlType; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mxc; if(mixerGetLineControls(reinterpret_cast<HMIXEROBJ>(m_HMixer), &mxlc, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) return; m_iMixerControlID = mxc.dwControlID; m_dwChannels = mxl.cChannels; if(MIXERCONTROL_CONTROLF_UNIFORM & mxc.fdwControl) m_dwChannels = 1; m_bSuccess = TRUE; }