Here is my problem: I made a simple mixer class for my own purposes, here it goes:
struct Volume
{
DWORD left;
DWORD right;
};
CMixer::CMixer ()
{
m_hMixer = 0;
m_value = 0;
}
CMixer::~CMixer(void)
{
delete [] m_value;
if (m_hMixer)
mixerClose (m_hMixer);
}
bool CMixer::Init( UINT type /*= MAIN*/)
{
// get number of mixer devices on system
if (mixerGetNumDevs() == 0)
return false;
// open mixer device
if (mixerOpen (&m_hMixer, MIXER_OBJECTF_MIXER, 0, 0, MIXER_OBJECTF_HMIXER) != MMSYSERR_NOERROR)
return false;
// get mixer info (like driver version, name...)
//MIXERCAPS caps;
//mixerGetDevCaps( (UINT)m_hMixer, &caps, sizeof(MIXERCAPS));
// get line info (like Volume control and Recording control)
MIXERLINE line;
line.cbStruct = sizeof( MIXERLINE );
line.dwSource = 0;
line.dwDestination = 0; // usualy 0 = Volume Control, 1 = Recording control (from caps.cDestinations)
switch (type)
{
case MAIN:
mixerGetLineInfo ((HMIXEROBJ)m_hMixer, &line, MIXER_GETLINEINFOF_DESTINATION);
break;
case WAVE:
mixerGetLineInfo ((HMIXEROBJ)m_hMixer, &line, MIXER_GETLINEINFOF_SOURCE);
break;
}
// get specific control
MIXERCONTROL mixerControl;
MIXERLINECONTROLS mixerLineControl;
mixerLineControl.cbStruct = sizeof (MIXERLINECONTROLS);
mixerLineControl.dwLineID = line.dwLineID;
mixerLineControl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mixerLineControl.cControls = 1;
mixerLineControl.cbmxctrl = sizeof (MIXERCONTROL);
mixerLineControl.pamxctrl = &mixerControl;
if (mixerGetLineControls ((HMIXEROBJ)m_hMixer, &mixerLineControl, MIXER_GETLINECONTROLSF_ONEBYTYPE ) != MMSYSERR_NOERROR )
return false;
// prepare struct for getting and setting control value
m_mixerDetails.cbStruct = sizeof (MIXERCONTROLDETAILS);
m_mixerDetails.dwControlID = mixerControl.dwControlID;
m_mixerDetails.cMultipleItems = mixerControl.cMultipleItems;
m_mixerDetails.cChannels = line.cChannels;
m_mixerDetails.cbDetails = sizeof (MIXERCONTROLDETAILS_UNSIGNED);
BYTE* value = new BYTE [m_mixerDetails.cbDetails * m_mixerDetails.cChannels];
m_mixerDetails.paDetails = value;
m_value = (MIXERCONTROLDETAILS_UNSIGNED *)value;
return true;
}
bool CMixer::GetValue (Volume &volume)
{
if( mixerGetControlDetails ((HMIXEROBJ)m_hMixer, &m_mixerDetails, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
return false;
volume.left = m_value[LEFT].dwValue;
volume.right = m_value[RIGHT].dwValue;
return true;
}
bool CMixer::SetValue (const Volume &volume)
{
m_value[LEFT].dwValue = volume.left;
m_value[RIGHT].dwValue = volume.right;
//if (mixerSetControlDetails ((HMIXEROBJ)m_hMixer, &m_mixerDetails, MIXER_SETCONTROLDETAILSF_VALUE ) != MMSYSERR_NOERROR)
// return false;
if (mixerSetControlDetails ((HMIXEROBJ)m_hMixer, &m_mixerDetails, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE ) != MMSYSERR_NOERROR)
return false;
return true;
}
Somewhere in code I will initialize the mixer and get the volume and remember it as a member variable and also set the new volume like this:
Volume m_volumeMain, m_volumeWave;
m_mixerMain.GetValue (m_volumeMain);
Volume volumeMain = {0, m_volumeMain.right}; // setting left channel to zero, while keeping the right channel
m_mixerMain.SetValue (volumeMain);
// set the volume back
m_mixerMain.SetValue (m_volumeMain);
That was the code. Here is the problem. After repeating the last code for couple of times the right channel will became inactive meaning if I use the multimedia keys on my keyboard it will control only left channel. I can get everything to normal if I use main volume slider inside Windows Volume control. Can anyone figure out what could be the problem?