views:

413

answers:

0

I'm trying to write an application that will get the mic volume of every sound card on a machine.

My current code looks like this:

for (unsigned int i = 0; i < waveInGetNumDevs(); ++i)
{
 HMIXER hmx;
 mixerOpen(&hmx, i, 0, 0, MIXER_OBJECTF_WAVEIN);
 if (hmx == 0)
 {
  printf("Unable to open device %d\n", i);
  continue;
 }


 MIXERLINE mxl;
 mxl.cbStruct = sizeof(mxl);
 if (mixerGetLineInfo((HMIXEROBJ)i, &mxl, MIXER_OBJECTF_WAVEIN) != MMSYSERR_NOERROR)
 {
  printf("Unable to get line info for device %d\n", i);
  continue;
 }
  long cConnections = mxl.cConnections;
  MIXERLINE mxl2;
  for (long j = -1; j < cConnections; j++)
  {
   mxl2 = mxl;
   if (j != -1)
   {
    mxl2.dwSource = j;
    mixerGetLineInfo((HMIXEROBJ)hmx, &mxl2, MIXER_GETLINEINFOF_SOURCE);

    if (mxl2.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) //is this a mic?
     continue;
   }

   if (mxl2.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) //is this a mic?
    continue;

   for (DWORD k = 0; k < mxl2.cControls; ++k)
   {
    MIXERCONTROL mxctrl;
    MIXERLINECONTROLS mxlctrl = {sizeof mxlctrl, mxl.dwLineID, k, 1, sizeof MIXERCONTROL, &mxctrl};
    MMRESULT res;

    if (res = mixerGetLineControls((HMIXEROBJ) hmx, &mxlctrl, MIXER_GETLINECONTROLSF_ONEBYID))
     continue;

    if (mxctrl.dwControlType != MIXERCONTROL_CONTROLTYPE_VOLUME)
     continue;

    MIXERCONTROLDETAILS_UNSIGNED volume;
    MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), mxctrl.dwControlID, 1, (HWND)0, sizeof MIXERCONTROLDETAILS_UNSIGNED, (LPVOID) &volume};
    mxcd.cMultipleItems = mxctrl.cMultipleItems;
    MMRESULT res = mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE);
    volume.dwValue -= mxctrl.Bounds.dwMinimum;
    vol = (int)((float)volume.dwValue/(mxctrl.Bounds.dwMaximum - mxctrl.Bounds.dwMinimum)*100);
  }
 }

 mixerClose(hmx);
}

This works fine for some cards, but for other cards it reads the output volume and not the mic volume! Where am I going wrong?