//得到声音控制 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 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; }
int getControlInfo(HMIXER handle, MIXERLINE* line, MIXERLINECONTROLS* controls) { int ret = FALSE; //TRACE2(">getControlInfo for line %s with %d controls\n", line->szName, line->cControls); controls->pamxctrl = NULL; if (line->cControls > 0) { // line points to the requested line. // Reserve memory for the control infos controls->cbStruct = sizeof(MIXERLINECONTROLS); controls->dwLineID = line->dwLineID; controls->cControls = line->cControls; controls->cbmxctrl = sizeof(MIXERCONTROL); controls->pamxctrl = (MIXERCONTROL*) malloc(sizeof(MIXERCONTROL) * line->cControls); if (controls->pamxctrl) { //TRACE0(" calling mixerGetLineControls\n"); ret = mixerGetLineControls((HMIXEROBJ) handle, controls, MIXER_GETLINECONTROLSF_ALL | MIXER_OBJECTF_HMIXER) == MMSYSERR_NOERROR; } } if (!ret) { if (controls->pamxctrl) { free(controls->pamxctrl); controls->pamxctrl = NULL; } } //TRACE0("<getControlInfo \n"); return ret; }
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; }
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); }
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; }
BOOL mixer_getlinecontrols(const LPMIXERLINE line) { int i; int lines; int mutes; MIXERLINECONTROLS controls; controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = line->dwLineID; controls.cControls = line->cControls; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = NULL; if (!my_realloc(&controls.pamxctrl, sizeof(MIXERCONTROL) * controls.cControls)) return (FALSE); CHECK_MMRETURN(mixerGetLineControls((HMIXEROBJ)s_hMixer, &controls, MIXER_GETLINECONTROLSF_ALL)); for (i = 0, lines = s_lines.count, mutes = s_mutes.count; i < (int)controls.cControls; i++) { switch (controls.pamxctrl[i].dwControlType) { case MIXERCONTROL_CONTROLTYPE_VOLUME: lines++; break; case MIXERCONTROL_CONTROLTYPE_MUTE: mutes++; break; } } if (!my_realloc((void **)&s_lines.mixers, sizeof(MIXERCONTROL) * lines)) return (FALSE); if (!my_realloc((void **)&s_mutes.mixers, sizeof(MIXERCONTROL) * mutes)) return (FALSE); for (i = 0; i < (int)controls.cControls; i++) { switch (controls.pamxctrl[i].dwControlType) { case MIXERCONTROL_CONTROLTYPE_VOLUME: s_lines.mixers[s_lines.count++] = controls.pamxctrl[i]; break; case MIXERCONTROL_CONTROLTYPE_MUTE: s_mutes.mixers[s_mutes.count++] = controls.pamxctrl[i]; break; } } free(controls.pamxctrl); return (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); }
///////////////////////////////////////////////// // 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; }
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; }
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; }
bool CVolumeOutMaster::isMute() { MMRESULT mmResult; 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_MUTE; LineControls.dwLineID = m_dwLineID; LineControls.cControls = 1; LineControls.cbmxctrl = sizeof(MIXERCONTROL); LineControls.pamxctrl = &Control; mmResult = mixerGetLineControls( (HMIXEROBJ)m_dwMixerHandle, &LineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ); if ( !m_bAvailable ) return false; MIXERCONTROLDETAILS_BOOLEAN* aDetails = (MIXERCONTROLDETAILS_BOOLEAN*)malloc(m_nChannelCount*sizeof(MIXERCONTROLDETAILS_BOOLEAN)); if ( !aDetails ) return false; MIXERCONTROLDETAILS mcd; memset( &mcd, 0, sizeof(MIXERCONTROLDETAILS) ); mcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mcd.dwControlID = Control.dwControlID; mcd.cChannels = m_nChannelCount; mcd.cMultipleItems = 0; mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); mcd.paDetails = &aDetails[0]; mmResult = mixerGetControlDetails((HMIXEROBJ)m_dwMixerHandle, &mcd, MIXER_GETCONTROLDETAILSF_VALUE); if(aDetails[0].fValue == 1) return true; return false; }
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; }
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; }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: (public)_select_control // Description: This methos allows to select the type of control in the selected line //-------------------------------------------------------------------------------------- int SoundResources::_select_control(unsigned int control_type) { //---------------------------------------------------------------------- // Fill the mixerLineControls structure //---------------------------------------------------------------------- m_mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS); m_mixerLineControls.dwLineID = m_mixerLine.dwLineID; m_mixerLineControls.cControls = 1; m_mixerLineControls.dwControlType = control_type; m_mixerLineControls.pamxctrl = &m_mixerControlArray; m_mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL); m_err = mixerGetLineControls((HMIXEROBJ)m_MixerHandle, &m_mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (m_err != MMSYSERR_NOERROR) printf("yarpsounddriver: %s has no %s control!\n", m_mixerLine.szName, m_mixerLineControls.pamxctrl->szName); return YARP_OK; }
int iKX::mixer(int op,int j,int channel,int *ret) { int res=-10; dword val[2]={0,0}; if(j<0 || j>=KX_MIXER_LAST) { debug("iKX mixer: incorrect call [op=%d j=%d chn=%d]\n",op,j,channel); return -1; } HMIXER mixer=0; // open mixer for(int ttt=0;ttt<KX_MAX_WAVE_DEVICES;ttt++) { switch(j) { case KX_MIXER_WAVE23: case KX_MIXER_WAVE23_MUTE: ttt=1; break; case KX_MIXER_WAVE45: case KX_MIXER_WAVE45_MUTE: ttt=2; break; case KX_MIXER_WAVE67: case KX_MIXER_WAVE67_MUTE: ttt=3; break; case KX_MIXER_WAVEHQ: case KX_MIXER_WAVEHQ_MUTE: ttt=4; break; } if(ttt==KX_MAX_WAVE_DEVICES-1) // 4; 'HQ' if(mixer_handler[ttt]==0) continue; /* if(mixerOpen(&mixer,mixer_num[ttt],0,0,MIXER_OBJECTF_MIXER)!=MMSYSERR_NOERROR) { debug("iKX mixer: mixerOpen failed [%x] #%d\n",GetLastError(),mixer_num[ttt]); strcpy(error_name,"error opening mixer"); return -2; } */ mixer=(HMIXER)mixer_handler[ttt]; if(!mixer) break; //-------- // MIXERCAPS mc; // mixerGetDevCaps(mixer_num[ttt],&mc,sizeof(mc)); // debug("****** -- %s: [ttt=%d; #=%d]\n",mc.szPname,ttt,mixer_num[ttt]); //-------- int id=-1; for(int cnt=0;cnt<20;cnt++) { MIXERLINECONTROLS lc; MIXERCONTROL mc; lc.cbStruct=sizeof(lc); lc.dwControlID=cnt; lc.cControls=1; lc.cbmxctrl=sizeof(mc); lc.pamxctrl=&mc; mc.cbStruct=sizeof(lc); MMRESULT rr=mixerGetLineControls((HMIXEROBJ)mixer,&lc,MIXER_GETLINECONTROLSF_ONEBYID); if(rr!=MMSYSERR_NOERROR) { // debug("ikX: mmsystem: bug: %x [%x] -- %d %d %d [cnt=%d]\n",GetLastError(),rr,j,mixer_handler[ttt],ttt,cnt); continue; } id=-1; // ---- // debug("(tmp) kxmixer: [%d] %s/%s [ttt=%d]; type: %x\n",cnt,mc.szName,mc.szShortName,ttt,mc.dwControlType); // ---- // all names correspond to GUIDs if((strcmp(mc.szName,_KX_MASTERV_NAME)==0) && (j==KX_MIXER_MASTER)) id=cnt; else if((strcmp(mc.szName,_KX_MASTERM_NAME)==0) && (j==KX_MIXER_MASTER_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_SYNTH1V_NAME)==0) && (j==KX_MIXER_SYNTH)) id=cnt; else if((strcmp(mc.szName,_KX_SYNTH1M_NAME)==0) && (j==KX_MIXER_SYNTH_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_RECINV_NAME)==0) && (j==KX_MIXER_REC)) id=cnt; else if((strcmp(mc.szName,_KX_RECINM_NAME)==0) && (j==KX_MIXER_REC_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_LINEIN_NAME)==0) && (j==KX_MIXER_LINEIN)) id=cnt; else if((strcmp(mc.szName,_KX_LINEIN_MUTE_NAME)==0) && (j==KX_MIXER_LINEIN_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_MICIN_NAME)==0) && (j==KX_MIXER_MICIN)) id=cnt; else if((strcmp(mc.szName,_KX_MICIN_MUTE_NAME)==0) && (j==KX_MIXER_MICIN_MUTE)) id=cnt; else { // these are usually translated by Windows into 'Volume' and 'Mute', // and coincide with 'CD Player' and 'SW Synth' controls... if((strcmp(mc.szName,_KX_WAVEV_NAME)==0) && (j==KX_MIXER_WAVE)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEM_NAME)==0) && (j==KX_MIXER_WAVE_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEV_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT23V_NAME)==0) && (j==KX_MIXER_WAVE23)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEM_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT23M_NAME)==0) && (j==KX_MIXER_WAVE23_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEV_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT45V_NAME)==0) && (j==KX_MIXER_WAVE45)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEM_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT45M_NAME)==0) && (j==KX_MIXER_WAVE45_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEV_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT67V_NAME)==0) && (j==KX_MIXER_WAVE67)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEM_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUT67M_NAME)==0) && (j==KX_MIXER_WAVE67_MUTE)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEV_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUTHQV_NAME)==0) && (j==KX_MIXER_WAVEHQ)) id=cnt; else if((strcmp(mc.szName,_KX_WAVEM_NAME)==0 || strcmp(mc.szName,_KX_WAVEOUTHQM_NAME)==0) && (j==KX_MIXER_WAVEHQ_MUTE)) id=cnt; else if((strcmp(mc.szName,"Volume")==0) && (j==KX_MIXER_WAVE || j==KX_MIXER_WAVE23 || j==KX_MIXER_WAVE45 || j==KX_MIXER_WAVE67 || j==KX_MIXER_WAVEHQ)) id=cnt; else if((strcmp(mc.szName,"Mute")==0) && (j==KX_MIXER_WAVE_MUTE || j==KX_MIXER_WAVE23_MUTE || j==KX_MIXER_WAVE45_MUTE || j==KX_MIXER_WAVE67_MUTE || j==KX_MIXER_WAVEHQ_MUTE)) id=cnt; } if(id==-1) { // debug(" not found -- /* %s [%d] - %d */\n",mc.szName,j,cnt); // fight with localization stuff if(j==KX_MIXER_WAVE || j==KX_MIXER_WAVE23 || j==KX_MIXER_WAVE45 || j==KX_MIXER_WAVE67 || j==KX_MIXER_WAVEHQ) { // Wave Volume / Wave Mute have following ids: // Wave 0/1 device: 2,3 // Wave 2/3, 4/5, 6/7 devices: 0,1 if(ttt==0 && cnt==2) id=2; else if(ttt!=0 && cnt==0) id=0; else continue; } else if(j==KX_MIXER_WAVE_MUTE || j==KX_MIXER_WAVE23_MUTE || j==KX_MIXER_WAVE45_MUTE || j==KX_MIXER_WAVE67_MUTE || j==KX_MIXER_WAVEHQ_MUTE) { if(ttt==0 && cnt==3) id=3; else if(ttt!=0 && cnt==1) id=1; else continue; } else continue; } // debug("setting '%s' [%d; cnt=%d; ttt=%d]\n",mc.szName,j,cnt,ttt); MIXERCONTROLDETAILS dets; memset(&dets,0,sizeof(dets)); dets.cbStruct=sizeof(MIXERCONTROLDETAILS); dets.dwControlID=id; dets.cMultipleItems=0; dets.paDetails=&val; if(j==KX_MIXER_MASTER_MUTE || j==KX_MIXER_SYNTH_MUTE || j==KX_MIXER_WAVE_MUTE || j==KX_MIXER_WAVE23_MUTE || j==KX_MIXER_WAVE45_MUTE || j==KX_MIXER_WAVE67_MUTE || j==KX_MIXER_WAVEHQ_MUTE || j==KX_MIXER_LINEIN_MUTE || j==KX_MIXER_MICIN_MUTE || j==KX_MIXER_REC_MUTE) // mutes { dets.cbDetails=sizeof(MIXERCONTROLDETAILS_UNSIGNED)*2; dets.cChannels=1; } else { dets.cbDetails=sizeof(MIXERCONTROLDETAILS_UNSIGNED); dets.cChannels=2; } if(mixerGetControlDetails((HMIXEROBJ)mixer,&dets,MIXER_GETCONTROLDETAILSF_VALUE)!=MMSYSERR_NOERROR) { debug("iKX mixer: getcontroldetails failed [%x]\n",GetLastError()); // error // mixerClose(mixer); return -3; } if(op&KX_PROP_GET) { // mixerClose(mixer); if(channel==0) *ret=val[0]; else *ret=val[1]; return 0; } if(channel==0) val[0]=*ret; else val[1]=*ret; if(mixerSetControlDetails((HMIXEROBJ)mixer,&dets,MIXER_SETCONTROLDETAILSF_VALUE)!=MMSYSERR_NOERROR) { debug("iKX mixer: setcontroldetails failed [%x]\n",GetLastError()); // error // mixerClose(mixer); return -5; } // success -- next mixer res=0; break; } // for each control if(id==-1) // still not found { // debug("kxmixer: [warning] mixer api: control '%d' not found [ttt=%d]\n",j,ttt); } // mixerClose(mixer); if((j==KX_MIXER_REC)||(j==KX_MIXER_REC_MUTE)||(j==KX_MIXER_WAVE23)||(j==KX_MIXER_WAVE45)||(j==KX_MIXER_WAVE67)||(j==KX_MIXER_WAVEHQ) ||(j==KX_MIXER_WAVE23_MUTE)||(j==KX_MIXER_WAVE45_MUTE)||(j==KX_MIXER_WAVE67_MUTE)||(j==KX_MIXER_WAVEHQ_MUTE)) break; } // for each wave device [ttt] return res; }
BOOL SndMixerQueryControls(PSND_MIXER Mixer, PUINT DisplayControls, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls) { if (LineInfo->cControls > 0) { *Controls = (MIXERCONTROL*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LineInfo->cControls * sizeof(MIXERCONTROL)); if (*Controls != NULL) { MIXERLINECONTROLS LineControls; MMRESULT Result; UINT j; LineControls.cbStruct = sizeof(LineControls); LineControls.dwLineID = LineInfo->dwLineID; LineControls.cControls = LineInfo->cControls; LineControls.cbmxctrl = sizeof(MIXERCONTROL); LineControls.pamxctrl = (MIXERCONTROL*)(*Controls); Result = mixerGetLineControls((HMIXEROBJ)Mixer->hmx, &LineControls, MIXER_GETLINECONTROLSF_ALL); if (Result == MMSYSERR_NOERROR) { for (j = 0; j < LineControls.cControls; j++) { if (SndMixerIsDisplayControl(Mixer, &(*Controls)[j])) { (*DisplayControls)++; } DPRINT("Line control: %ws (0x%x, 0x%x)\n", (*Controls)[j].szName, (*Controls)[j].fdwControl, (*Controls)[j].dwControlType); } return TRUE; } else { HeapFree(GetProcessHeap(), 0, *Controls); *Controls = NULL; DPRINT("Failed to get line (ID: 0x%x) controls: %d\n", LineInfo->dwLineID, Result); } } else { DPRINT("Failed to allocate memory for %d line (ID: 0x%x) controls!\n", LineInfo->dwLineID, LineInfo->cControls); } return FALSE; } else { return TRUE; } }
void Mixer::getPortsInfo() { MIXERCAPS mc; mixerGetDevCaps((UINT)hMixer, &mc, sizeof mc); MIXERLINE mlt; unsigned i; for (i = 0; i < mc.cDestinations; ++i) { memset(&mlt, 0, sizeof mlt); mlt.cbStruct = sizeof mlt; mlt.dwDestination = i; if (mixerGetLineInfo((HMIXEROBJ)hMixer, &mlt, MIXER_GETLINEINFOF_DESTINATION) != MMSYSERR_NOERROR) continue; if (mlt.dwLineID == dwRecLineID) break; // this is the destination we're interested in } ports = new AudioInputPort[mlt.cConnections]; numPorts = mlt.cConnections; for (i = 0; i < numPorts; ++i) { MIXERLINE mlc; memcpy(&mlc, &mlt, sizeof mlc); mlc.dwSource = i; mixerGetLineInfo((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINEINFOF_SOURCE/*|MIXER_OBJECTF_HMIXER*/); ports[i].tag = mlc.dwLineID; ports[i].dwComponentType = mlc.dwComponentType; #ifdef UNICODE wcstombs(ports[i].name, mlc.szName, MIXER_LONG_NAME_CHARS); #else strncpy(ports[i].name, mlc.szName, MIXER_LONG_NAME_CHARS); #endif } // Make the microphone the first port in the list: for (i = 1; i < numPorts; ++i) { #ifdef OLD_MICROPHONE_TESTING_CODE if (_strnicmp("mic", ports[i].name, 3) == 0 || _strnicmp("mik", ports[i].name, 3) == 0) { #else if (ports[i].dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) { #endif AudioInputPort tmp = ports[0]; ports[0] = ports[i]; ports[i] = tmp; } } } Boolean Mixer::enableInputPort(unsigned portIndex, char const*& errReason, MMRESULT& errCode) { errReason = NULL; // unless there's an error AudioInputPort& port = ports[portIndex]; MIXERCONTROL mc; mc.cMultipleItems = 1; // in case it doesn't get set below MIXERLINECONTROLS mlc; #if 0 // the following doesn't seem to be needed, and can fail: mlc.cbStruct = sizeof mlc; mlc.pamxctrl = &mc; mlc.cbmxctrl = sizeof (MIXERCONTROL); mlc.dwLineID = port.tag; mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; if ((errCode = mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) { errReason = "mixerGetLineControls()"; return False; } #endif MIXERLINE ml; memset(&ml, 0, sizeof (MIXERLINE)); ml.cbStruct = sizeof (MIXERLINE); ml.dwLineID = port.tag; if ((errCode = mixerGetLineInfo((HMIXEROBJ)hMixer, &ml, MIXER_GETLINEINFOF_LINEID)) != MMSYSERR_NOERROR) { errReason = "mixerGetLineInfo()1"; return False; } #ifdef UNICODE wchar_t portname[MIXER_LONG_NAME_CHARS+1]; wcsncpy(portname, ml.szName, MIXER_LONG_NAME_CHARS); #else char portname[MIXER_LONG_NAME_CHARS+1]; strncpy(portname, ml.szName, MIXER_LONG_NAME_CHARS); #endif memset(&ml, 0, sizeof (MIXERLINE)); ml.cbStruct = sizeof (MIXERLINE); ml.dwLineID = dwRecLineID; if ((errCode = mixerGetLineInfo((HMIXEROBJ)hMixer, &ml, MIXER_GETLINEINFOF_LINEID/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) { errReason = "mixerGetLineInfo()2"; return False; } // Get Mixer/MUX control information (need control id to set and get control details) mlc.cbStruct = sizeof mlc; mlc.dwLineID = ml.dwLineID; mlc.cControls = 1; mc.cbStruct = sizeof mc; // Needed???##### mc.dwControlID = 0xDEADBEEF; // For testing ##### mlc.pamxctrl = &mc; mlc.cbmxctrl = sizeof mc; mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX; // Single Select if ((errCode = mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) { mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER; // Multiple Select mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/); } unsigned matchLine = 0; if (mc.cMultipleItems > 1) { // Before getting control, we need to know which line to grab. // We figure this out by listing the lines, and comparing names: MIXERCONTROLDETAILS mcd; mcd.cbStruct = sizeof mcd; mcd.cChannels = ml.cChannels; mcd.cMultipleItems = mc.cMultipleItems; MIXERCONTROLDETAILS_LISTTEXT* mcdlText = new MIXERCONTROLDETAILS_LISTTEXT[mc.cMultipleItems]; mcd.cbDetails = sizeof (MIXERCONTROLDETAILS_LISTTEXT); mcd.paDetails = mcdlText; if (mc.dwControlID != 0xDEADBEEF) { // we know the control id for real mcd.dwControlID = mc.dwControlID; if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) { delete[] mcdlText; errReason = "mixerGetControlDetails()1"; return False; } } else { // Hack: We couldn't find a MUX or MIXER control, so try to guess the control id: for (mc.dwControlID = 0; mc.dwControlID < 32; ++mc.dwControlID) { mcd.dwControlID = mc.dwControlID; if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT/*|MIXER_OBJECTF_HMIXER*/)) == MMSYSERR_NOERROR) break; } if (mc.dwControlID == 32) { // unable to guess mux/mixer control id delete[] mcdlText; errReason = "mixerGetControlDetails()2"; return False; } } #ifdef UNICODE for (unsigned i = 0; i < mcd.cMultipleItems; ++i) { if (wcscmp(mcdlText[i].szName, portname) == 0) { matchLine = i; break; } } #else for (unsigned i = 0; i < mcd.cMultipleItems; ++i) { if (strcmp(mcdlText[i].szName, portname) == 0) { matchLine = i; break; } } #endif delete[] mcdlText; } // Now get control itself: MIXERCONTROLDETAILS mcd; mcd.cbStruct = sizeof mcd; mcd.dwControlID = mc.dwControlID; mcd.cChannels = ml.cChannels; mcd.cMultipleItems = mc.cMultipleItems; MIXERCONTROLDETAILS_BOOLEAN* mcdbState = new MIXERCONTROLDETAILS_BOOLEAN[mc.cMultipleItems]; mcd.paDetails = mcdbState; mcd.cbDetails = sizeof (MIXERCONTROLDETAILS_BOOLEAN); if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) { delete[] mcdbState; errReason = "mixerGetControlDetails()3"; return False; } for (unsigned j = 0; j < mcd.cMultipleItems; ++j) { mcdbState[j].fValue = (j == matchLine); } if ((errCode = mixerSetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_OBJECTF_HMIXER)) != MMSYSERR_NOERROR) { delete[] mcdbState; errReason = "mixerSetControlDetails()"; return False; } delete[] mcdbState; return True; }
static UINT get_ctrls(HMIXEROBJ mixer, DWORD lineID, PxCtrl **pctrls) { MMRESULT res; MIXERLINE line; MIXERLINECONTROLS controls; MIXERCONTROL control; PxCtrl *ctrls = NULL; UINT num; UINT s; do { line.cbStruct = sizeof(MIXERLINE); line.dwComponentType = lineID; res = mixerGetLineInfo(mixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE); if (res != MMSYSERR_NOERROR) { break; } num = (UINT) line.cConnections; ctrls = calloc(num, sizeof(PxInfo)); if (ctrls == NULL) { break; } for (s = 0; s < num; s++) { line.dwSource = s; res = mixerGetLineInfo(mixer, &line, MIXER_GETLINEINFOF_SOURCE); if (res != MMSYSERR_NOERROR) { break; } ctrls[s].lineID = line.dwLineID; ctrls[s].name = strdup(line.szName); if (ctrls[s].name == NULL) { break; } controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = line.dwLineID; controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = &control; control.cbStruct = sizeof(MIXERCONTROL); res = mixerGetLineControls(mixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (res == MMSYSERR_NOERROR) ctrls[s].controlID = control.dwControlID; else ctrls[s].controlID = 0; } if (s != num) { break; } *pctrls = ctrls; return num; } while (FALSE); if (ctrls) { for (s = 0; s < num; s++) { if (ctrls[s].name) { free(ctrls[s].name); } } free(ctrls); } return 0; }
static void PlatGetCDDAVolumeControl(void) { int i; int numDev = mixerGetNumDevs(); //go through the mixer devices searching for one that can deal with the cd volume for(i=0;i<numDev;i++) { HMIXER handle; if(mixerOpen(&handle,i,0,0,MIXER_OBJECTF_MIXER ) == MMSYSERR_NOERROR ) { //try to get the compact disc mixer line MIXERLINE line; line.cbStruct=sizeof(MIXERLINE); line.dwComponentType=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; if(mixerGetLineInfo(handle,&line,MIXER_GETLINEINFOF_COMPONENTTYPE) == MMSYSERR_NOERROR) { MIXERLINECONTROLS lineControls; MIXERCONTROL control; lineControls.cbStruct=sizeof(MIXERLINECONTROLS); lineControls.dwLineID=line.dwLineID; lineControls.pamxctrl=&control; lineControls.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME ; lineControls.cControls=1; lineControls.cbmxctrl=sizeof(MIXERCONTROL); control.cbStruct=sizeof(MIXERCONTROL); //try to get the volume control if(mixerGetLineControls(handle,&lineControls,MIXER_GETLINECONTROLSF_ONEBYTYPE)==MMSYSERR_NOERROR) { MIXERCONTROLDETAILS details; MIXERCONTROLDETAILS_UNSIGNED detailValue; details.cbStruct=sizeof(MIXERCONTROLDETAILS); details.dwControlID=control.dwControlID; details.cChannels=1; details.cMultipleItems=0; details.cbDetails=sizeof(MIXERCONTROLDETAILS_UNSIGNED); details.paDetails=&detailValue; //get the current volume so that we can restore it later if(mixerGetControlDetails(handle,&details,MIXER_GETCONTROLDETAILSF_VALUE)==MMSYSERR_NOERROR) { PreGameCDVolume = detailValue.dwValue; mixerClose(handle); return; //success } } } mixerClose(handle); } } return; }
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; }
BOOL MicMute::getMicControl() { int mmret; MIXERLINE mxln; MIXERCONTROL mxcon; MIXERLINECONTROLS mxlncon; log.WriteString("\n In the getMicControl"); mxln.cbStruct=(sizeof(MIXERLINE)); mxln.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ; mmret=mixerGetLineInfo( (HMIXEROBJ)m_mixer,&mxln,MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE ); if(mmret!=MMSYSERR_NOERROR) { return FALSE; } int count=mxln.cConnections; int id=mxln.dwDestination; for(int j=0;j<count;j++) { mxln.cbStruct=sizeof(MIXERLINE); mxln.dwDestination=id; mxln.dwSource=j; mmret=mixerGetLineInfo((HMIXEROBJ)m_mixer,&mxln,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE); if(mmret!=MMSYSERR_NOERROR) { return FALSE; } if(mxln.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ) { log.WriteString("\nGot the source line id"); break; } } if(j==count) { log.WriteString("\n Unable to get source line"); return FALSE; } log.WriteString("\n Got the line info"); //Initialize the MIXERLINECONTROLS structure mcontype=MIXERCONTROL_CONTROLTYPE_MUTE; mxlncon.cbStruct=sizeof(MIXERLINECONTROLS); mxlncon.dwControlType=mcontype; mxlncon.cControls=1; mxlncon.dwLineID=mxln.dwLineID; mxlncon.cbmxctrl=sizeof(MIXERCONTROL); mxlncon.pamxctrl=&mxcon; mmret=mixerGetLineControls((HMIXEROBJ)m_mixer,&mxlncon,MIXER_GETLINECONTROLSF_ONEBYTYPE | MIXER_OBJECTF_HMIXER ); if(mmret!=MMSYSERR_NOERROR) { log.WriteString("\n Failed to get the line control"); return FALSE; } mxcd.cbStruct=sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID=mxcon.dwControlID; mxcd.cChannels=mxln.cChannels; char str[200]; sprintf(str,"\nno of items = %d , id = %d , channel = %d",mxcon.cMultipleItems,mxcon.dwControlID,mxln.cChannels); log.WriteString(str); return TRUE; }
void VolumeControl::init() { //initialize audio mixer interface #if defined (__APPLE__) #warning TODO: Not implemented for MacOS yet!!! #elif defined(__linux__) //try to open mixer device if (mixerHandle == nullptr) { snd_mixer_selem_id_alloca(&mixerSelemId); //sets simple-mixer index and name snd_mixer_selem_id_set_index(mixerSelemId, mixerIndex); snd_mixer_selem_id_set_name(mixerSelemId, mixerName); //open mixer if (snd_mixer_open(&mixerHandle, 0) >= 0) { LOG(LogDebug) << "VolumeControl::init() - Opened ALSA mixer"; //ok. attach to defualt card if (snd_mixer_attach(mixerHandle, mixerCard) >= 0) { LOG(LogDebug) << "VolumeControl::init() - Attached to default card"; //ok. register simple element class if (snd_mixer_selem_register(mixerHandle, NULL, NULL) >= 0) { LOG(LogDebug) << "VolumeControl::init() - Registered simple element class"; //ok. load registered elements if (snd_mixer_load(mixerHandle) >= 0) { LOG(LogDebug) << "VolumeControl::init() - Loaded mixer elements"; //ok. find elements now mixerElem = snd_mixer_find_selem(mixerHandle, mixerSelemId); if (mixerElem != nullptr) { //wohoo. good to go... LOG(LogDebug) << "VolumeControl::init() - Mixer initialized"; } else { LOG(LogError) << "VolumeControl::init() - Failed to find mixer elements!"; snd_mixer_close(mixerHandle); mixerHandle = nullptr; } } else { LOG(LogError) << "VolumeControl::init() - Failed to load mixer elements!"; snd_mixer_close(mixerHandle); mixerHandle = nullptr; } } else { LOG(LogError) << "VolumeControl::init() - Failed to register simple element class!"; snd_mixer_close(mixerHandle); mixerHandle = nullptr; } } else { LOG(LogError) << "VolumeControl::init() - Failed to attach to default card!"; snd_mixer_close(mixerHandle); mixerHandle = nullptr; } } else { LOG(LogError) << "VolumeControl::init() - Failed to open ALSA mixer!"; } } #elif defined(WIN32) || defined(_WIN32) //get windows version information OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)}; ::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer)); //check windows version if(osVer.dwMajorVersion < 6) { //Windows older than Vista. use mixer API. open default mixer if (mixerHandle == nullptr) { if (mixerOpen(&mixerHandle, 0, NULL, 0, 0) == MMSYSERR_NOERROR) { //retrieve info on the volume slider control for the "Speaker Out" line MIXERLINECONTROLS mixerLineControls; mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS); mixerLineControls.dwLineID = 0xFFFF0000; //Id of "Speaker Out" line mixerLineControls.cControls = 1; //mixerLineControls.dwControlID = 0x00000000; //Id of "Speaker Out" line's volume slider mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; //Get volume control mixerLineControls.pamxctrl = &mixerControl; mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL); if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) { LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume control!"; mixerClose(mixerHandle); mixerHandle = nullptr; } } else { LOG(LogError) << "VolumeControl::init() - Failed to open mixer!"; } } } else { //Windows Vista or above. use EndpointVolume API. get device enumerator if (endpointVolume == nullptr) { CoInitialize(nullptr); IMMDeviceEnumerator * deviceEnumerator = nullptr; CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator); if (deviceEnumerator != nullptr) { //get default endpoint IMMDevice * defaultDevice = nullptr; deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice); if (defaultDevice != nullptr) { //retrieve endpoint volume defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&endpointVolume); if (endpointVolume == nullptr) { LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint volume!"; } //release default device. we don't need it anymore defaultDevice->Release(); } else { LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint!"; } //release device enumerator. we don't need it anymore deviceEnumerator->Release(); } else { LOG(LogError) << "VolumeControl::init() - Failed to get audio endpoint enumerator!"; CoUninitialize(); } } } #endif }
void CVolumeOutMaster::EnableLine( bool bEnable ) { if ( !m_bInitialized ) return; bool bAnyEnabled = false; MMRESULT mmResult; MIXERLINE lineDestination; memset( &lineDestination, 0, sizeof(MIXERLINE) ); lineDestination.cbStruct = sizeof(MIXERLINE); lineDestination.dwLineID = m_dwLineID; mmResult = mixerGetLineInfo( (HMIXEROBJ)m_dwMixerHandle, &lineDestination, MIXER_GETLINEINFOF_LINEID ); if ( mmResult != MMSYSERR_NOERROR ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: FAILURE: Could not get the Speakers Destination Line while enabling. mmResult=%d\n", mmResult ); } else { ssi_wrn (".MasterOutputVolume: FAILURE: Could not get the Speakers Destination Line while disabling. mmResult=%d\n", mmResult ); } return; } // Getting all line's controls int nControlCount = lineDestination.cControls; int nChannelCount = lineDestination.cChannels; MIXERLINECONTROLS LineControls; memset( &LineControls, 0, sizeof(MIXERLINECONTROLS) ); MIXERCONTROL* aControls = (MIXERCONTROL*)malloc( nControlCount * sizeof(MIXERCONTROL) ); if ( !aControls ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while enabling the line.\n" ); } else { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while disabling the line.\n" ); } return; } memset( &aControls[0], 0, sizeof(nControlCount * sizeof(MIXERCONTROL)) ); for ( int i = 0; i < nControlCount; i++ ) { aControls[i].cbStruct = sizeof(MIXERCONTROL); } LineControls.cbStruct = sizeof(MIXERLINECONTROLS); LineControls.dwLineID = lineDestination.dwLineID; LineControls.cControls = nControlCount; LineControls.cbmxctrl = sizeof(MIXERCONTROL); LineControls.pamxctrl = &aControls[0]; mmResult = mixerGetLineControls( (HMIXEROBJ)m_dwMixerHandle, &LineControls, MIXER_GETLINECONTROLSF_ALL ); if ( mmResult == MMSYSERR_NOERROR ) { for (int i = 0; i < nControlCount; i++ ) { LONG lValue; bool bReadyToSet = false; switch (aControls[i].dwControlType) { case MIXERCONTROL_CONTROLTYPE_MUTE: lValue = (BOOL)!bEnable; bReadyToSet = true; break; case MIXERCONTROL_CONTROLTYPE_SINGLESELECT: lValue = (BOOL)bEnable; bReadyToSet = true; break; case MIXERCONTROL_CONTROLTYPE_MUX: lValue = (BOOL)bEnable; bReadyToSet = true; break; case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT: lValue = (BOOL)bEnable; bReadyToSet = true; break; case MIXERCONTROL_CONTROLTYPE_MIXER: lValue = (BOOL)bEnable; bReadyToSet = true; break; } if ( bReadyToSet ) { MIXERCONTROLDETAILS_BOOLEAN* aDetails = NULL; int nMultipleItems = aControls[i].cMultipleItems; int nChannels = nChannelCount; // MIXERCONTROLDETAILS MIXERCONTROLDETAILS ControlDetails; memset( &ControlDetails, 0, sizeof(MIXERCONTROLDETAILS) ); ControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); ControlDetails.dwControlID = aControls[i].dwControlID; if ( aControls[i].fdwControl & MIXERCONTROL_CONTROLF_UNIFORM ) { nChannels = 1; } if ( aControls[i].fdwControl & MIXERCONTROL_CONTROLF_MULTIPLE ) { nMultipleItems = aControls[i].cMultipleItems; aDetails = (MIXERCONTROLDETAILS_BOOLEAN*)malloc(nMultipleItems*nChannels*sizeof(MIXERCONTROLDETAILS_BOOLEAN)); if ( !aDetails ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while enabling the line.\n" ); } else { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while disabling the line.\n" ); } continue; } for ( int nItem = 0; nItem < nMultipleItems; nItem++ ) { /* if ( ( aControls[i].dwControlType & MIXERCONTROL_CONTROLTYPE_SINGLESELECT ) && ( nItem > 0 ) ) { lValue = (LONG)!((BOOL)lValue); } */ for ( int nChannel = 0; nChannel < nChannels; nChannel++ ) { aDetails[nItem+nChannel].fValue = lValue; } } } else { nMultipleItems = 0; aDetails = (MIXERCONTROLDETAILS_BOOLEAN*)malloc(nChannels*sizeof(MIXERCONTROLDETAILS_BOOLEAN)); if ( !aDetails ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while enabling the line.\n" ); } else { ssi_wrn (".MasterOutputVolume: FAILURE: Out of memory while disabling the line.\n" ); } continue; } for ( int nChannel = 0; nChannel < nChannels; nChannel++ ) { aDetails[nChannel].fValue = (LONG)lValue; } } ControlDetails.cChannels = nChannels; ControlDetails.cMultipleItems = nMultipleItems; ControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN); ControlDetails.paDetails = &aDetails[0]; mmResult = mixerSetControlDetails( (HMIXEROBJ)m_dwMixerHandle, &ControlDetails, 0L ); if ( mmResult == MMSYSERR_NOERROR ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: Enabling Line: Speakers Line control \"%s\"(0x%X) has been set to %d.\n", aControls[i].szShortName, aControls[i].dwControlType, lValue ); } else { ssi_wrn (".MasterOutputVolume: Disabling Line: Speakers Line control \"%s\"(0x%X) has been set to %d.\n", aControls[i].szShortName, aControls[i].dwControlType, lValue ); } bAnyEnabled = true; } free( aDetails ); } } } else { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: FAILURE: Could not get the line controls while enabling. mmResult=%d\n", mmResult ); } else { ssi_wrn (".MasterOutputVolume: FAILURE: Could not get the line controls while disabling. mmResult=%d\n", mmResult ); } } free( aControls ); if ( !bAnyEnabled ) { if ( bEnable ) { ssi_wrn (".MasterOutputVolume: WARNING: No controls were found for enabling the line.\n" ); } else { ssi_wrn (".MasterOutputVolume: WARNING: No controls were found for disabling the line.\n" ); } } }
PxMixer *Px_OpenMixer( void *pa_stream, int index ) { internalPortAudioStream *past; PaWMMEStreamData *wmmeStreamData; HWAVEIN hWaveIn; HWAVEOUT hWaveOut; PxInfo *mixer; MMRESULT result; MIXERLINE line; MIXERLINECONTROLS controls; MIXERCONTROL control; MIXERCONTROLDETAILS details; MIXERCONTROLDETAILS_LISTTEXT mixList[32]; int j; mixer = (PxMixer *)malloc(sizeof(PxInfo)); mixer->hInputMixer = NULL; mixer->hOutputMixer = NULL; past = (internalPortAudioStream *) pa_stream; wmmeStreamData = (PaWMMEStreamData *) past->past_DeviceData; hWaveIn = wmmeStreamData->hWaveIn; if (hWaveIn) { result = mixerOpen((HMIXER *)&mixer->hInputMixer, (UINT)hWaveIn, 0, 0, MIXER_OBJECTF_HWAVEIN); if (result != MMSYSERR_NOERROR) { free(mixer); return NULL; } } hWaveOut = wmmeStreamData->hWaveOut; if (hWaveOut) { result = mixerOpen((HMIXER *)&mixer->hOutputMixer, (UINT)hWaveOut, 0, 0, MIXER_OBJECTF_HWAVEOUT); if (result != MMSYSERR_NOERROR) { free(mixer); return NULL; } } mixer->numInputs = 0; mixer->muxID = 0; /* * Find the input source selector (mux or mixer) and * get the names and IDs of all of the input sources */ if (mixer->hInputMixer) { line.cbStruct = sizeof(MIXERLINE); line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN; result = mixerGetLineInfo(mixer->hInputMixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE); if (result == MMSYSERR_NOERROR) { controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = line.dwLineID; controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = &control; control.cbStruct = sizeof(MIXERCONTROL); result = mixerGetLineControls(mixer->hInputMixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (result != MMSYSERR_NOERROR) { controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER; result = mixerGetLineControls(mixer->hInputMixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); } if (result == MMSYSERR_NOERROR) { mixer->numInputs = control.cMultipleItems; mixer->muxID = control.dwControlID; details.cbStruct = sizeof(MIXERCONTROLDETAILS); details.dwControlID = mixer->muxID; details.cChannels = 1; details.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT); details.paDetails = (LPMIXERCONTROLDETAILS_LISTTEXT)&mixList[0]; details.cMultipleItems = mixer->numInputs; result = mixerGetControlDetails(mixer->hInputMixer, (LPMIXERCONTROLDETAILS)&details, MIXER_GETCONTROLDETAILSF_LISTTEXT); if (result != MMSYSERR_NOERROR) mixer->numInputs = 0; for(j=0; j<mixer->numInputs; j++) { mixer->src[j].lineID = mixList[j].dwParam1; strcpy(mixer->src[j].name, mixList[j].szName); } } /* * We've found the names - now we need to find the volume * controls for each one */ for(j=0; j<mixer->numInputs; j++) { controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = mixer->src[j].lineID; controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = &control; control.cbStruct = sizeof(MIXERCONTROL); result = mixerGetLineControls(mixer->hInputMixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (result == MMSYSERR_NOERROR) mixer->src[j].controlID = control.dwControlID; else mixer->src[j].controlID = 0; } } } /* * Find the ID of the output speaker volume control */ mixer->speakerID = 0; if (mixer->hOutputMixer) { line.cbStruct = sizeof(MIXERLINE); line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; result = mixerGetLineInfo(mixer->hOutputMixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE); if (result == MMSYSERR_NOERROR) { controls.cbStruct = sizeof(MIXERLINECONTROLS); controls.dwLineID = line.dwLineID; controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; controls.cbmxctrl = sizeof(MIXERCONTROL); controls.pamxctrl = &control; control.cbStruct = sizeof(MIXERCONTROL); result = mixerGetLineControls(mixer->hInputMixer, &controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); if (result == MMSYSERR_NOERROR) mixer->speakerID = control.dwControlID; } } return (PxMixer *)mixer; }
int PlatChangeCDDAVolume(int volume) { MMRESULT mmres; unsigned int newVolume; int i; int numDev = mixerGetNumDevs(); /* check the cdDeviceId */ if(cdDeviceID==NO_DEVICE) return SOUND_PLATFORMERROR; //go through the mixer devices searching for one that can deal with the cd volume for(i=0;i<numDev;i++) { HMIXER handle; if(mixerOpen(&handle,i,0,0,MIXER_OBJECTF_MIXER ) == MMSYSERR_NOERROR ) { //try to get the compact disc mixer line MIXERLINE line; line.cbStruct=sizeof(MIXERLINE); line.dwComponentType=MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; if(mixerGetLineInfo(handle,&line,MIXER_GETLINEINFOF_COMPONENTTYPE) == MMSYSERR_NOERROR) { MIXERLINECONTROLS lineControls; MIXERCONTROL control; lineControls.cbStruct=sizeof(MIXERLINECONTROLS); lineControls.dwLineID=line.dwLineID; lineControls.pamxctrl=&control; lineControls.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME ; lineControls.cControls=1; lineControls.cbmxctrl=sizeof(MIXERCONTROL); control.cbStruct=sizeof(MIXERCONTROL); //try to get the volume control if(mixerGetLineControls(handle,&lineControls,MIXER_GETLINECONTROLSF_ONEBYTYPE)==MMSYSERR_NOERROR) { MIXERCONTROLDETAILS details; MIXERCONTROLDETAILS_UNSIGNED detailValue; details.cbStruct=sizeof(MIXERCONTROLDETAILS); details.dwControlID=control.dwControlID; details.cChannels=1; details.cMultipleItems=0; details.cbDetails=sizeof(MIXERCONTROLDETAILS_UNSIGNED); details.paDetails=&detailValue; if(volume==CDDA_VOLUME_RESTOREPREGAMEVALUE) { //set the volume to what it was before the game started newVolume=PreGameCDVolume; } else { //scale the volume newVolume = control.Bounds.dwMinimum + WideMulNarrowDiv(volume, (control.Bounds.dwMaximum-control.Bounds.dwMinimum), (CDDA_VOLUME_MAX-CDDA_VOLUME_MIN)); if(newVolume<control.Bounds.dwMinimum) newVolume=control.Bounds.dwMinimum; if(newVolume>control.Bounds.dwMaximum) newVolume=control.Bounds.dwMaximum; } //fill in the volume in the control details structure detailValue.dwValue=newVolume; mmres = mixerSetControlDetails(handle,&details,MIXER_SETCONTROLDETAILSF_VALUE); mixerClose(handle); if(mmres==MMSYSERR_NOERROR) return 1; else return SOUND_PLATFORMERROR; } } mixerClose(handle); } } return SOUND_PLATFORMERROR; }
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; } }
/* ------------------------------------------------------------------------------------ */ 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; }
//################################################## //agenttype_mixer_menu_linecontrols //################################################## int agenttype_mixer_menu_linecontrols(Menu *menu, control *c, char *action, char *agentname, int format, UINT device, HMIXER mixer_handle, MIXERLINE &mixer_line) { //Variables MIXERLINECONTROLS mixer_linecontrols; MIXERCONTROL mixer_controls[8]; int elementcount = 0; char text_item[256]; char text_params[256]; const char *type; //Setup the function call with required values UINT count_control = mixer_line.cControls; if (count_control > 8) count_control = 8; //Maximum 8 controls per line mixer_linecontrols.cbStruct = sizeof(MIXERLINECONTROLS); mixer_linecontrols.cControls = count_control; mixer_linecontrols.dwLineID = mixer_line.dwLineID; mixer_linecontrols.pamxctrl = &mixer_controls[0]; mixer_linecontrols.cbmxctrl = sizeof(MIXERCONTROL); //Figure out the type if (format == CONTROL_FORMAT_SCALE) { type = mixer_name_scale; } else if (format == CONTROL_FORMAT_BOOL) { type = mixer_name_bool; } else return 0; //Get the line controls if (MMSYSERR_NOERROR != mixerGetLineControls((HMIXEROBJ)mixer_handle, &mixer_linecontrols, MIXER_GETLINECONTROLSF_ALL)) { return 0; } //For every control for (unsigned int control = 0; control < count_control; control++) { bool passestest = false; switch (format) { case CONTROL_FORMAT_SCALE: passestest = (mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_BASS || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_TREBLE || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_FADER); break; case CONTROL_FORMAT_BOOL: passestest = (mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_BOOLEAN || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_BUTTON || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_LOUDNESS || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_MONO || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF || mixer_controls[control].dwControlType == MIXERCONTROL_CONTROLTYPE_STEREOENH); break; } if (passestest) { elementcount++; sprintf(text_item, "- %s", mixer_controls[control].szName); sprintf(text_params, "%d %d %d", device, (int)mixer_line.dwLineID, (int)mixer_controls[control].dwControlID); make_menuitem_cmd(menu, text_item, config_getfull_control_setagent_c(c, action, type, text_params)); } } return elementcount; }
///////////////////////////////////////////////// // 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, int dkKind): m_dwControlID(-1), m_bOK(false), m_dwChannels(0) { HRESULT hr=0; HMIXER hMixer=0; hr = mixerOpen(&hMixer, 0, 0, 0, 0); if (FAILED(hr)) return; MIXERLINE mxl; memset(&mxl,0,sizeof(mxl)); DWORD kind=0, count=0; // �הוס� למו mxl.cbStruct = sizeof(mxl); mxl.dwComponentType = ComponentType; mxl.dwDestination=0; mxl.dwSource=0; hr = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE); if (FAILED(hr)) { mixerClose(hMixer); return; } m_dwChannels = mxl.cChannels; if(dkKind==0 || dkKind==2){ MIXERCONTROL mc; memset(&mc,0,sizeof(mc)); mc.cbStruct = sizeof(mc); MIXERLINECONTROLS mxlc; memset(&mxlc,0,sizeof(mxlc)); 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; } if(dkKind==1){ MIXERCONTROL mc; memset(&mc,0,sizeof(mc)); mc.cbStruct = sizeof(mc); MIXERLINECONTROLS mxlc; memset(&mxlc,0,sizeof(mxlc)); mxlc.cbStruct = sizeof(mxlc); mxlc.dwLineID = mxl.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE; mxlc.cControls = 1; mxlc.cbmxctrl = sizeof(MIXERCONTROL); mxlc.pamxctrl = &mc; hr = mixerGetLineControls((HMIXEROBJ)hMixer, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE); m_dwControlMID = mc.dwControlID; } // �הוס� סעאנמו /*MIXERCONTROL mc; memset(&mc,0,sizeof(mc)); mc.cbStruct = sizeof(mc); MIXERLINECONTROLS mxlc; memset(&mxlc,0,sizeof(mxlc)); mxlc.cbStruct = sizeof(mxlc); kind = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 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; }