예제 #1
0
int Px_GetCurrentInputSource( PxMixer *mixer )
{
   PxInfo *info = (PxInfo *)mixer;
   MIXERCONTROLDETAILS details;
   MIXERCONTROLDETAILS_BOOLEAN flags[32];
   MMRESULT result;
   int i;

   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
   details.dwControlID = info->muxID;
   details.cMultipleItems = info->numInputs;
   details.cChannels = 1;   
   details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
   details.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&flags[0];

   result = mixerGetControlDetails(info->hInputMixer,
                                   (LPMIXERCONTROLDETAILS)&details,
                                   MIXER_GETCONTROLDETAILSF_VALUE);

   if (result == MMSYSERR_NOERROR) {
      for(i=0; i<info->numInputs; i++)
         if (flags[i].fValue)
            return i;
   }

   return 0;
}
예제 #2
0
DWORD CVolumeOutMaster::GetCurrentVolume()
{
	if ( !m_bAvailable )
		return BAD_DWORD;
	MIXERCONTROLDETAILS_UNSIGNED* aDetails = (MIXERCONTROLDETAILS_UNSIGNED*)malloc(m_nChannelCount*sizeof(MIXERCONTROLDETAILS_UNSIGNED));
	if ( !aDetails )
		return BAD_DWORD;
	MIXERCONTROLDETAILS ControlDetails;
	memset( &ControlDetails, 0, sizeof(MIXERCONTROLDETAILS) );
	ControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
	ControlDetails.dwControlID = m_dwVolumeControlID;
	ControlDetails.cChannels = m_nChannelCount;
	ControlDetails.cMultipleItems = 0;
	ControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
	ControlDetails.paDetails = &aDetails[0];
	MMRESULT mmResult = mixerGetControlDetails( (HMIXEROBJ)m_dwMixerHandle, &ControlDetails, MIXER_GETCONTROLDETAILSF_VALUE );
	DWORD dw = aDetails[0].dwValue;
	free( aDetails );
	if ( mmResult != MMSYSERR_NOERROR )
	{
		ssi_wrn (".MasterOutputVolume: FAILURE: Could not get volume. mmResult=%d\n", mmResult );
		return BAD_DWORD;
	}
	return dw;
}
예제 #3
0
/* ------------------------------------------------------------------------------------ */
BOOL CMixer::SetControlValue(DWORD dw)
{
    if(!m_bSuccess)
        return m_bSuccess;

    m_bSuccess = FALSE;

    MIXERCONTROLDETAILS mxcd;
    MIXERCONTROLDETAILS_UNSIGNED mxcd_u;

    mxcd.cbStruct		= sizeof(mxcd);
    mxcd.dwControlID	= m_iMixerControlID;
    mxcd.cChannels		= m_dwChannels;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails		= sizeof(mxcd_u);
    mxcd.paDetails		= &mxcd_u;

    mmr = mixerGetControlDetails(reinterpret_cast<HMIXEROBJ>(m_HMixer), &mxcd, 0L);

    if(MMSYSERR_NOERROR != mmr) return m_bSuccess;

    mxcd_u.dwValue  = dw;
    mmr = mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(m_HMixer), &mxcd, 0L);

    if(MMSYSERR_NOERROR != mmr)
        return m_bSuccess;

    m_bSuccess = TRUE;
    return m_bSuccess;
}
예제 #4
0
void VolumeFunction(HMIXEROBJ hMixer, DWORD controlID, PxVolume *volume)
{
   MIXERCONTROLDETAILS details;
   MMRESULT result;
   unsigned short value = 0;

   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
   details.dwControlID = controlID;
   details.cChannels = 1; /* all channels */
   details.cMultipleItems = 0;
   details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
   details.paDetails = &value;

   result = mixerGetControlDetails(hMixer, &details,
                                   MIXER_GETCONTROLDETAILSF_VALUE);

   if (*volume < 0.0) {
      *volume = (PxVolume)(value / 65535.0);
   }
   else {
      if (result != MMSYSERR_NOERROR)
         return;
      value = (unsigned short)(*volume * 65535.0);
      mixerSetControlDetails(hMixer, &details,
                             MIXER_GETCONTROLDETAILSF_VALUE);
   }
}
예제 #5
0
파일: volume.c 프로젝트: now/purels
BOOL mixer_manipulate_mute(int channel, BOOL get, LPBOOL mute)
{
    MIXERCONTROLDETAILS_BOOLEAN details;
    MIXERCONTROLDETAILS mcd;

    details.fValue	= *mute;

    if (s_mutes.count == 0)
	return (FALSE);

    if (channel < 0 || channel >= s_mutes.count)
	return (FALSE);

    mcd.cbStruct	= sizeof(MIXERCONTROLDETAILS);
    mcd.dwControlID 	= s_mutes.mixers[channel].dwControlID;
    mcd.cChannels	= 1;
    mcd.cMultipleItems	= 0;
    mcd.cbDetails	= sizeof(MIXERCONTROLDETAILS_BOOLEAN);
    mcd.paDetails	= &details;

    if (get)
    {
	CHECK_MMRETURN(mixerGetControlDetails((HMIXEROBJ)s_hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE));
    }
    else
    {
	CHECK_MMRETURN(mixerSetControlDetails((HMIXEROBJ)s_hMixer, &mcd, MIXER_SETCONTROLDETAILSF_VALUE));
    }

    *mute = details.fValue;

    return (TRUE);
}
bool Win32RedBookDevice::getVolume(F32 * volume)
{
   if(!mAcquired)
   {
      setLastError("Device has not been acquired");
      return(false);
   }

   if(!mVolumeInitialized)
   {
      setLastError("Volume failed to initialize");
      return(false);
   }

   U32 vol = 0;
   if(mUsingMixer)
   {
      mixerGetControlDetails(mVolumeDeviceId, &mMixerVolumeDetails, MIXER_GETCONTROLDETAILSF_VALUE);
      vol = mMixerVolumeValue.dwValue;
   }
   else
      auxGetVolume(mAuxVolumeDeviceId, (unsigned long *)&vol);

   vol &= 0xffff;
   *volume = F32(vol) / 65535.f;

   setLastError("");
   return(true);
}
예제 #7
0
파일: volume.c 프로젝트: now/purels
BOOL mixer_manipulate_volume(int channel, BOOL get, LPDWORD left, LPDWORD right)
{
    MIXERCONTROLDETAILS_UNSIGNED details[2];
    MIXERCONTROLDETAILS mcd;

    details[0].dwValue	= *left;
    details[1].dwValue	= *right;

    if (s_lines.count == 0)
	return (FALSE);

    if (channel < 0 || channel >= s_lines.count)
	return (FALSE);

    mcd.cbStruct	= sizeof(MIXERCONTROLDETAILS);
    mcd.dwControlID 	= s_lines.mixers[channel].dwControlID;
    mcd.cChannels	= 2;
    mcd.cMultipleItems	= 0;
    mcd.cbDetails	= sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    mcd.paDetails	= &details;

    if (get)
    {
	CHECK_MMRETURN(mixerGetControlDetails((HMIXEROBJ)s_hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE));
    }
    else
    {
	CHECK_MMRETURN(mixerSetControlDetails((HMIXEROBJ)s_hMixer, &mcd, MIXER_SETCONTROLDETAILSF_VALUE));
    }

    *left	= details[0].dwValue;
    *right	= details[1].dwValue;
	
    return (TRUE);
}
float CMicVolume::VolDevice(MCS *pData)
{
	int nCnt = 1;	//컨트롤수
	float temp = 0;	//임시

    if(MIXERCONTROL_CONTROLF_MULTIPLE & pData->m_ctlMixerSpeaker.fdwControl) nCnt = pData->m_ctlMixerSpeaker.cMultipleItems;

	MIXERCONTROLDETAILS_UNSIGNED mixer_control_details_unsigned[10];
    MIXERCONTROLDETAILS mixer_control_details;
    mixer_control_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mixer_control_details.dwControlID = pData->m_ctlMixerSpeaker.dwControlID;
    mixer_control_details.cChannels      = 1;
    mixer_control_details.cMultipleItems = pData->m_ctlMixerSpeaker.cMultipleItems;
    mixer_control_details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    mixer_control_details.paDetails = mixer_control_details_unsigned;

    if(mixerGetControlDetails((HMIXEROBJ)h_mix, &mixer_control_details, MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
	{
#ifdef _DEBUG
		MessageBox(NULL,"내부함수 오류(mixerGetControlDetails)", "내부 함수 오류", MB_ICONSTOP);
#endif
        return -1;
    }

	for(int i = 0; i < nCnt; i++){
        temp = ((float)mixer_control_details_unsigned[i].dwValue * (float)pData->nMax + 65535 /2) / 65535;
    }
    return temp;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//agenttype_mixer_notify
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void agenttype_mixer_notify_xp (agent *a, int notifytype, void *messagedata)
{
	
	//Get the agent details
	AgentType_Mixer_XP * details = static_cast<AgentType_Mixer_XP *>(a->agentdetails);

	//Variables
	double *value_double = NULL;
	bool *value_bool = NULL;
	MIXERCONTROLDETAILS_UNSIGNED    mixer_setcontrol_value_double;
	MIXERCONTROLDETAILS_BOOLEAN     mixer_setcontrol_value_bool;

	switch (notifytype)
	{
		case NOTIFY_CHANGE:
		{
			//Set up the values
			if (a->agenttypeptr->format & CONTROL_FORMAT_SCALE)
			{
				value_double = (double *) messagedata;
				details->m_mixer_controldetails.paDetails = &mixer_setcontrol_value_double;
			}
			else if (a->agenttypeptr->format & CONTROL_FORMAT_BOOL)
			{
				value_bool = (bool *) messagedata;
				details->m_mixer_controldetails.paDetails = &mixer_setcontrol_value_bool;
			}

			//Retrieve the details
			if (MMSYSERR_NOERROR != mixerGetControlDetails((HMIXEROBJ) details->m_mixer_handle, &details->m_mixer_controldetails, MIXER_GETCONTROLDETAILSF_VALUE)) return;

			//Set the value
			if (a->agenttypeptr->format & CONTROL_FORMAT_SCALE)
			{
				mixer_setcontrol_value_double.dwValue = (ULONG) (*value_double * 65535);
			}
			else if (a->agenttypeptr->format & CONTROL_FORMAT_BOOL)
			{
				mixer_setcontrol_value_bool.fValue = *value_bool;
			}

			//Reload the details
			MMRESULT const res = mixerSetControlDetails((HMIXEROBJ) details->m_mixer_handle, &details->m_mixer_controldetails, MIXER_SETCONTROLDETAILSF_VALUE);
			if (MMSYSERR_NOERROR != res) return;

			break;
		}
		case NOTIFY_SAVE_AGENT:
			//Write existance
			char temp[30];
			sprintf(temp, "%d %d %d", (int)details->m_device, (int)details->m_line, (int)details->m_control);
			config_write(config_get_control_setagent_c(a->controlptr, a->agentaction, a->agenttypeptr->agenttypename, temp));
			break;
	}
}
예제 #10
0
//--------------------------------------------------------------------------- 
unsigned int CMyVolumeCtrl::vGetVolumeValue(HMIXER   hmixer   ,MIXERCONTROL   *mxc) 
{ 
	MIXERCONTROLDETAILS   mxcd; 
	MIXERCONTROLDETAILS_UNSIGNED   vol;   vol.dwValue=0; 
	mxcd.hwndOwner   =   0; 
	mxcd.cbStruct   =   sizeof(mxcd); 
	mxcd.dwControlID   =   mxc-> dwControlID; 
	mxcd.cbDetails   =   sizeof(vol); 
	mxcd.paDetails   =   &vol; 
	mxcd.cChannels   =   1; 
	if(mixerGetControlDetails((HMIXEROBJ)hmixer,   &mxcd,   MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE)) 
		return   -1; 
	return   vol.dwValue; 
} 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//agenttype_mixer_getdata
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void * agenttype_mixer_getdata_xp (agent *a, int datatype)
{
	MIXERCONTROLDETAILS_UNSIGNED    mixer_setcontrol_value_double;
	MIXERCONTROLDETAILS_BOOLEAN     mixer_setcontrol_value_bool;
	AgentType_Mixer_XP * details = static_cast<AgentType_Mixer_XP *>(a->agentdetails);
	if (!details) return NULL;

	switch (datatype)
	{
		case DATAFETCH_VALUE_TEXT:
		case DATAFETCH_VALUE_SCALE:
		case DATAFETCH_VALUE_BOOL:
			//Set up the values
			if (datatype == DATAFETCH_VALUE_BOOL)
			{
				details->m_mixer_controldetails.paDetails = &mixer_setcontrol_value_bool;
			}
			else
			{
				details->m_mixer_controldetails.paDetails = &mixer_setcontrol_value_double;
			}

			//Retrieve the details
			if (MMSYSERR_NOERROR != mixerGetControlDetails((HMIXEROBJ) details->m_mixer_handle, &details->m_mixer_controldetails, MIXER_GETCONTROLDETAILSF_VALUE)) return NULL;

			//Get and return the value
			if (datatype == DATAFETCH_VALUE_SCALE || datatype == DATAFETCH_VALUE_TEXT)
			{
				details->m_value_double = mixer_setcontrol_value_double.dwValue / 65535.0;
				if (details->m_value_double < 0.0) details->m_value_double = 0.0;
				if (details->m_value_double > 1.0) details->m_value_double = 1.0;

				//Return if it is the simple double value
				if (datatype == DATAFETCH_VALUE_SCALE) return &(details->m_value_double);

				//Otherwise, it must be text
				int intvalue = 100 * (details->m_value_double);
				sprintf(mixer_outputbuffer, "%d%%", intvalue);
				return mixer_outputbuffer;
			}
			else if (datatype == DATAFETCH_VALUE_BOOL)
			{
				details->m_value_bool = (!!mixer_setcontrol_value_bool.fValue);
				return &(details->m_value_bool);
			}
	}

	return NULL;
}
예제 #12
0
//--------------------------------------------------------------------------- 
long CMyVolumeCtrl::vGetMuteValue(HMIXER   hmixer   ,MIXERCONTROL   *mxc) 
{ 
	MIXERCONTROLDETAILS   mxcd; 
	MIXERCONTROLDETAILS_BOOLEAN   mxcdMute; 
	mxcd.hwndOwner   =   0; 
	mxcd.cbStruct   =   sizeof(mxcd); 
	mxcd.dwControlID   =   mxc-> dwControlID; 
	mxcd.cbDetails   =   sizeof(mxcdMute); 
	mxcd.paDetails   =   &mxcdMute; 
	mxcd.cChannels   =   1; 
	mxcd.cMultipleItems   =   0; 
	if   (mixerGetControlDetails((HMIXEROBJ)hmixer,   &mxcd,MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE)) 
		return   -1; 
	return   mxcdMute.fValue; 
} 
예제 #13
0
bool PortAudioInput::GetMicrophoneLevel(DWORD* dwLevel)
{
  MMRESULT mmresult;
  MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
  MIXERCONTROLDETAILS   mxcd;

  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  mxcd.dwControlID = m_dwCntlID;
  mxcd.cChannels = 1;
  mxcd.cMultipleItems = 0;
  mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  mxcd.paDetails = &mxcdVolume;
  mmresult = mixerGetControlDetails(reinterpret_cast<HMIXEROBJ>(m_mixerMic),
				    &mxcd,
				    MIXER_GETCONTROLDETAILSF_VALUE);
  if (mmresult != MMSYSERR_NOERROR) return false;
  *dwLevel = mxcdVolume.dwValue;
  return true;
}
예제 #14
0
파일: mixer.c 프로젝트: GYGit/reactos
INT
SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDetails, LPVOID paDetails)
{
    MIXERCONTROLDETAILS MixerDetails;

    if (Mixer->hmx)
    {
        MixerDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
        MixerDetails.dwControlID = dwControlID;
        MixerDetails.cChannels = 1; //FIXME
        MixerDetails.cMultipleItems = 0;
        MixerDetails.cbDetails = cbDetails;
        MixerDetails.paDetails = paDetails;

        if (mixerGetControlDetails((HMIXEROBJ)Mixer->hmx, &MixerDetails, MIXER_GETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER) == MMSYSERR_NOERROR)
        {
            return 1;
        }
    }
    return -1;
}
예제 #15
0
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;
}
예제 #16
0
static PxVolume VolumeFunction(HMIXEROBJ hMixer, DWORD controlID, PxVolume volume)
{
   MIXERCONTROLDETAILS details;
   MMRESULT result;
   MIXERCONTROLDETAILS_UNSIGNED value;

   if (hMixer == NULL) {
      return -1.0;
   }
   
   memset(&value, 0, sizeof(MIXERCONTROLDETAILS_UNSIGNED));
   
   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
   details.dwControlID = controlID;
   details.cChannels = 1; /* all channels */
   details.cMultipleItems = 0;
   details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
   details.paDetails = &value;

   if (volume < 0.0) {
      result = mixerGetControlDetails(hMixer,
                                      &details,
                                      MIXER_GETCONTROLDETAILSF_VALUE);
      if (result != MMSYSERR_NOERROR)
         return -1.0;
      
      return (PxVolume)(value.dwValue / 65535.0);
   }
   
   value.dwValue = (unsigned short)(volume * 65535.0);
   result = mixerSetControlDetails(hMixer,
                                   &details,
                                   MIXER_GETCONTROLDETAILSF_VALUE);
   
   if (result != MMSYSERR_NOERROR)
      return -1.0;
   
   return 0.0;
}
예제 #17
0
파일: volume.c 프로젝트: amaneureka/reactos
VOID
GetMuteState(PGLOBAL_DATA pGlobalData)
{
    MIXERCONTROLDETAILS_BOOLEAN mxcdMute;
    MIXERCONTROLDETAILS mxcd;

    if (pGlobalData->hMixer == NULL)
        return;

    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = pGlobalData->muteControlID;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
    mxcd.paDetails = &mxcdMute;

    if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
        != MMSYSERR_NOERROR)
        return;

    pGlobalData->muteVal = mxcdMute.fValue;
}
예제 #18
0
파일: volume.c 프로젝트: amaneureka/reactos
VOID
GetVolumeValue(PGLOBAL_DATA pGlobalData)
{
    MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
    MIXERCONTROLDETAILS mxcd;

    if (pGlobalData->hMixer == NULL)
        return;

    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = pGlobalData->volumeControlID;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    mxcd.paDetails = &mxcdVolume;

    if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
        != MMSYSERR_NOERROR)
        return;

    pGlobalData->volumeValue = mxcdVolume.dwValue;
}
예제 #19
0
long CMixer::GetPan()
{
	if (!m_bOK || m_dwControlPID==0) return 0;
	HMIXER hMixer;
	HRESULT hr;
	hr = mixerOpen(&hMixer, 0, 0, 0, 0);
	if (FAILED(hr)) return 0;

	MIXERCONTROLDETAILS mxcd;
	MIXERCONTROLDETAILS_SIGNED mxdu;


	mxcd.cMultipleItems = 0;
	mxcd.cChannels = 1;
	mxcd.cbStruct = sizeof(mxcd);
	mxcd.dwControlID = m_dwControlPID;
	mxcd.cbDetails = sizeof(mxdu);
	mxcd.paDetails = &mxdu;
	hr = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE);	
	
	mixerClose(hMixer);
	return mxdu.lValue;
}
예제 #20
0
BOOL LevelChange(WPARAM wParam, LPARAM lParam)
{
    if (mixer.pmxcd == NULL)
	return FALSE;

    if (lParam == mixer.pmxcd->dwControlID)
    {
	// Get the value

	mixerGetControlDetails((HMIXEROBJ)mixer.hmx, mixer.pmxcd,
			       MIXER_GETCONTROLDETAILSF_VALUE);

	// Set the slider

	int value = MAX_VOL - (mixer.pmxcdu->dwValue * (MAX_VOL - MIN_VOL) /
			       (mixer.pmxc->Bounds.dwMaximum -
				mixer.pmxc->Bounds.dwMinimum));

	SendMessage(level.hwnd, TBM_SETPOS, TRUE, value);
    }

    return TRUE;
}
예제 #21
0
void CMixerControl::_RefreshStrings()
{
    if(!(m_mc.fdwControl & MIXERCONTROL_CONTROLF_MULTIPLE)) return;

    // We are guaranteed here that the control is a multiple-item control,
    // and therefore we're "ok to go" as ellie would say from Contact.

    MIXERCONTROLDETAILS mcd = {0};

    mcd.cbStruct = sizeof(mcd);
    mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
    mcd.dwControlID = m_mc.dwControlID;
    mcd.cChannels = (m_mc.fdwControl & MIXERCONTROL_CONTROLF_UNIFORM) ? 1 : m_ml.cChannels;
    mcd.cMultipleItems = m_mc.cMultipleItems;
    mcd.paDetails = m_pStrings;

    if(MMSYSERR_NOERROR != mixerGetControlDetails((HMIXEROBJ)m_hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT))
    {
        //DebugBreak();
        return;
    }

    return;
}
예제 #22
0
파일: AudioInput.cpp 프로젝트: fffonion/V8
BOOL AudioInput::SetMicrPhoneVolume(DWORD dwVolume)
{
	BOOL bResult = FALSE;
	try
	{
		int mixerNum = (int)mixerGetNumDevs();
		for(int i = 0; i < mixerNum; i ++)
		{
			DWORD dwSource = 0;
			HMIXER m_hMixer = NULL;   
			MMRESULT mr = NULL;
			//打开Mixer设备   
			if(mixerOpen(&m_hMixer, i, 0, 0, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR)
				continue; 

			MIXERLINE MixerLine;   
			//结构体的大小   
			MixerLine.cbStruct = sizeof(MixerLine);   
			//录制设备总线   
			MixerLine.dwComponentType   =   MIXERLINE_COMPONENTTYPE_DST_WAVEIN;   
			//得到录制总线中的连接数   
			if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &MixerLine,
				MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
				continue; 

			//将连接数保存   
			DWORD dwConnections = MixerLine.cConnections;   
			//准备获取麦克风设备的ID   
			DWORD dwLineID = 0;   
			for(DWORD i = 0; i < dwConnections; i++ )   
			{   
				//枚举每一个设备,当Source的ID等于当前的迭代记数   
				MixerLine.dwSource = i;   
				//根据SourceID获得连接的信息   
				if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &MixerLine,   
					MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR) 
					//判断函数执行错误   
					break;  

				//如果当前设备类型是麦克风,则跳出循环。   
				if(MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)   
				{   
					dwLineID = MixerLine.dwLineID;
					dwSource = MixerLine.dwSource;
					break;   
				}   
			}

			//如果没有找到,返回失败。   
			if(dwLineID == 0)   
				continue;   

			//get line id of destination line   
			MIXERLINE lineinfo_Dest;   
			::ZeroMemory(&lineinfo_Dest, sizeof(MIXERLINE));   
			lineinfo_Dest.cbStruct = sizeof(MIXERLINE);   
			lineinfo_Dest.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;   
			if(::mixerGetLineInfo(   
				(HMIXEROBJ)m_hMixer,   
				&lineinfo_Dest,   
				MIXER_OBJECTF_HMIXER   |     
				MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
				continue;  

			//get id of specified connector   
			MIXERLINE lineinfo_Connector;   
			::ZeroMemory(&lineinfo_Connector, sizeof(MIXERLINE));  

			lineinfo_Connector.cbStruct = sizeof(MIXERLINE);   
			lineinfo_Connector.dwDestination = lineinfo_Dest.dwLineID;   
			lineinfo_Connector.dwSource = dwSource;   
			if(::mixerGetLineInfo(   
				(HMIXEROBJ)m_hMixer,   
				&lineinfo_Connector,     
				MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR)
				continue;  

			MIXERCONTROL mxc;   
			MIXERLINECONTROLS mxlc;   
			mxlc.cbStruct = sizeof(MIXERLINECONTROLS);   
			mxlc.dwLineID = lineinfo_Connector.dwLineID;   
			mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;   
			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)
				continue;  

			//get volume value range now   
			MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;   
			MIXERCONTROLDETAILS mxcd;   
			mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);   
			mxcd.dwControlID = mxc.dwControlID;   
			mxcd.cChannels = 1;   
			mxcd.cMultipleItems = 0;   
			mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);   
			mxcd.paDetails = &mxcdVolume;   
			if(mixerGetControlDetails(   
				reinterpret_cast<HMIXEROBJ>(m_hMixer),   
				&mxcd,   
				MIXER_GETCONTROLDETAILSF_VALUE)!= MMSYSERR_NOERROR)
				continue;  

			//set volume   
			MIXERCONTROLDETAILS_UNSIGNED mxcdVolume_Set = { mxc.Bounds.dwMaximum * dwVolume / 255 };   
			MIXERCONTROLDETAILS mxcd_Set;   
			mxcd_Set.cbStruct = sizeof(MIXERCONTROLDETAILS);   
			mxcd_Set.dwControlID = mxc.dwControlID;   
			mxcd_Set.cChannels = 1;   
			mxcd_Set.cMultipleItems = 0;   
			mxcd_Set.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);   
			mxcd_Set.paDetails = &mxcdVolume_Set;   
			if(mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer),   
				&mxcd_Set,   
				MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
				continue;   

			::mixerClose(m_hMixer);
			m_hMixer = NULL;
			bResult = TRUE;;
		}
	}
	catch(...){ return FALSE; }
	return bResult;
}
예제 #23
0
/*
============
CDAudio_AccessVolume
  JDH: get/set CD volume
       (code adpated from cd_player.c in avp package at icculus.org)
============
*/
void CDAudio_AccessVolume (float *vol, CDDA_OP op)
{
	int					numDevs, i;
	HMIXEROBJ			hMixer;
	MIXERLINEA			line;
	MIXERLINECONTROLSA	lineControls;
	MIXERCONTROL		control;
	MIXERCONTROLDETAILS details;
	MIXERCONTROLDETAILS_UNSIGNED detailValue;
	DWORD				range;
	
	numDevs = mixerGetNumDevs ();
	for (i = 0; i < numDevs; i++)
	{
		if (mixerOpen ((HMIXER *)&hMixer, i, 0, 0, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR)
			continue;

		line.cbStruct = sizeof(MIXERLINE);
		line.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;

		if (mixerGetLineInfoA (hMixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE) == MMSYSERR_NOERROR)
		{
			control.cbStruct = sizeof(MIXERCONTROL);
			
			lineControls.cbStruct = sizeof(MIXERLINECONTROLS);
			lineControls.dwLineID = line.dwLineID;
			lineControls.pamxctrl = &control;
			lineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
			lineControls.cControls = 1;
			lineControls.cbmxctrl = sizeof(MIXERCONTROL);
			
			if (mixerGetLineControlsA (hMixer, &lineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR)
			{
				details.cbStruct = sizeof(MIXERCONTROLDETAILS);
				details.dwControlID = control.dwControlID;
				details.cChannels = 1;
				details.cMultipleItems = 0;
				details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
				details.paDetails = &detailValue;

				range = control.Bounds.dwMaximum - control.Bounds.dwMinimum;
				if (op == CDDA_SETVOL)
				{
					detailValue.dwValue = control.Bounds.dwMinimum + (*vol * range);
				
					mixerSetControlDetails (hMixer, &details, MIXER_SETCONTROLDETAILSF_VALUE);
				}
				else
				{
					mixerGetControlDetails (hMixer, &details, MIXER_GETCONTROLDETAILSF_VALUE);

					*vol = (float)(detailValue.dwValue - control.Bounds.dwMinimum) / range;
				}
				
				mixerClose ((HMIXER) hMixer);
				return;
			}
		}
		
		mixerClose ((HMIXER) hMixer);
	}
}
예제 #24
0
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;
}
예제 #25
0
static void mixer_test_controlA(HMIXER mix, LPMIXERCONTROLA control)
{
    MMRESULT rc;

    if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_UNSIGNED)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_UNSIGNED value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.paDetails = &value;
        details.cbDetails = sizeof(value);

        /* read the current control value */
        rc=mixerGetControlDetails((HMIXEROBJ)mix,&details,MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_UNSIGNED new_value;

            trace("            Value=%d\n",value.dwValue);

            if (value.dwValue + control->Metrics.cSteps < S1(control->Bounds).dwMaximum)
                new_value.dwValue = value.dwValue + control->Metrics.cSteps;
            else
                new_value.dwValue = value.dwValue - control->Metrics.cSteps;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc=mixerSetControlDetails((HMIXEROBJ)mix,&new_details,MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_UNSIGNED ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc=mixerGetControlDetails((HMIXEROBJ)mix,&ret_details,MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(abs(ret_value.dwValue-new_value.dwValue)<=1,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.dwValue,new_value.dwValue,ret_value.dwValue);

                    if (abs(ret_value.dwValue-new_value.dwValue)<=1) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc=mixerSetControlDetails((HMIXEROBJ)mix,&details,MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BOOLEAN) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BUTTON)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_BOOLEAN value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.paDetails = &value;
        details.cbDetails = sizeof(value);

        rc=mixerGetControlDetails((HMIXEROBJ)mix,&details,MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_BOOLEAN new_value;

            trace("            Value=%d\n",value.fValue);

            if (value.fValue == FALSE)
                new_value.fValue = TRUE;
            else
                new_value.fValue = FALSE;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc=mixerSetControlDetails((HMIXEROBJ)mix,&new_details,MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_BOOLEAN ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc=mixerGetControlDetails((HMIXEROBJ)mix,&ret_details,MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(ret_value.fValue==new_value.fValue,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.fValue,new_value.fValue,ret_value.fValue);

                    if (ret_value.fValue==new_value.fValue) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc=mixerSetControlDetails((HMIXEROBJ)mix,&details,MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else {
        /* FIXME */
    }
}
예제 #26
0
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;
}
예제 #27
0
int mixer4i(int device, int action, int control, int parm)
{
    MIXERCONTROLDETAILS ctrlDetails;
    MIXERCONTROLDETAILS_UNSIGNED mcdUnsigned[2];
    MIXERCONTROL *mctrl;
    MIXERLINE  *mline;
    mixerdata_t *mix;
    int         i;

    if(!initMixerOk)
        return MIX_ERROR;

    // This is quite specific at the moment.
    // Only allow setting the CD volume.
    if(device != MIX_CDAUDIO && device != MIX_MIDI)
        return MIX_ERROR;
    if(control != MIX_VOLUME)
        return MIX_ERROR;

    // Choose the mixer line.
    mix = (device == MIX_CDAUDIO ? &mixCD : &mixMidi);

    // Is the mixer line for the requested device available?
    if(!mix->available)
        return MIX_ERROR;

    mline = &mix->line;
    mctrl = &mix->volume;

    // Init the data structure.
    memset(&ctrlDetails, 0, sizeof(ctrlDetails));
    ctrlDetails.cbStruct = sizeof(ctrlDetails);
    ctrlDetails.dwControlID = mctrl->dwControlID;
    ctrlDetails.cChannels = 1;  //mline->cChannels;
    ctrlDetails.cbDetails = sizeof(mcdUnsigned);
    ctrlDetails.paDetails = &mcdUnsigned;

    switch(action)
    {
    case MIX_GET:
        res =
            mixerGetControlDetails((HMIXEROBJ) mixer, &ctrlDetails,
                                   MIXER_GETCONTROLDETAILSF_VALUE);
        if(res != MMSYSERR_NOERROR)
            return MIX_ERROR;

        // The bigger one is the real volume.
        i = mcdUnsigned[mcdUnsigned[0].dwValue >
                        mcdUnsigned[1].dwValue ? 0 : 1].dwValue;

        // Return the value in range 0-255.
        return (255 * (i - mctrl->Bounds.dwMinimum)) /
            (mctrl->Bounds.dwMaximum - mctrl->Bounds.dwMinimum);

    case MIX_SET:
        // Clamp it.
        if(parm < 0)
            parm = 0;
        if(parm > 255)
            parm = 255;

        // Set both channels to the same volume (center balance).
        mcdUnsigned[0].dwValue = mcdUnsigned[1].dwValue =
            (parm * (mctrl->Bounds.dwMaximum - mctrl->Bounds.dwMinimum)) /
            255 + mctrl->Bounds.dwMinimum;

        res =
            mixerSetControlDetails((HMIXEROBJ) mixer, &ctrlDetails,
                                   MIXER_SETCONTROLDETAILSF_VALUE);
        if(res != MMSYSERR_NOERROR)
            return MIX_ERROR;
        break;

    default:
        return MIX_ERROR;
    }
    return MIX_OK;
}
예제 #28
0
int VolumeControl::getVolume() const
{
	int volume = 0;

#if defined (__APPLE__)
    #warning TODO: Not implemented for MacOS yet!!!
    return volume;
#elif defined(__linux__)
	if (mixerElem != nullptr)
	{
		//get volume range
		long minVolume;
		long maxVolume;
		if (snd_mixer_selem_get_playback_volume_range(mixerElem, &minVolume, &maxVolume) == 0)
		{
			//ok. now get volume
			long rawVolume;
			if (snd_mixer_selem_get_playback_volume(mixerElem, SND_MIXER_SCHN_MONO, &rawVolume) == 0)
			{
				//worked. bring into range 0-100
				rawVolume -= minVolume;
				if (rawVolume > 0)
				{
					volume = (rawVolume * 100) / (maxVolume - minVolume);
				}
				//else volume = 0;
			}
			else
			{
				LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume!";
			}
		}
		else
		{
			LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
		}
	}
#elif defined(WIN32) || defined(_WIN32)
	if (mixerHandle != nullptr)
	{
		//Windows older than Vista. use mixer API. get volume from line control
		MIXERCONTROLDETAILS_UNSIGNED value;
		MIXERCONTROLDETAILS mixerControlDetails;
		mixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
		mixerControlDetails.dwControlID = mixerControl.dwControlID;
		mixerControlDetails.cChannels = 1; //always 1 for a MIXERCONTROL_CONTROLF_UNIFORM control
		mixerControlDetails.cMultipleItems = 0; //always 0 except for a MIXERCONTROL_CONTROLF_MULTIPLE control
		mixerControlDetails.paDetails = &value;
		mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
		if (mixerGetControlDetails((HMIXEROBJ)mixerHandle, &mixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR)
		{
			volume = (uint8_t)round((value.dwValue * 100) / 65535);
		}
		else
		{
			LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume!";
		}
	}
	else if (endpointVolume != nullptr)
	{
		//Windows Vista or above. use EndpointVolume API
		float floatVolume = 0.0f; //0-1
		if (endpointVolume->GetMasterVolumeLevelScalar(&floatVolume) == S_OK)
		{
			volume = (uint8_t)round(floatVolume * 100.0f);
		}else{
			LOG(LogError) << "VolumeControl::getVolume() - Failed to get master volume!";
		}

	}
#endif
	//clamp to 0-100 range
	if (volume < 0)
	{
		volume = 0;
	}
	if (volume > 100)
	{
		volume = 100;
	}
	return volume;
}
예제 #29
0
파일: cd_player.c 프로젝트: Scraft/avpmp
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;
}
예제 #30
0
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;
}