PRB: No Signal is Recorded When Using MCI or waveInxxx APIs

ID: Q159753

4.00    | 4.00
WINDOWS | WINDOWS NT
 kbprb

The information in this article applies to:

SYMPTOMS

There is no signal recorded using MCI (Media Control Interface) or waveInXXX APIs to record through the microphone.

CAUSE

There are three possible causes:

1. The microphone line is muted.

2. The volume of the microphone line is turned to the minimum.

3. The microphone line is not selected into the wave input destination.

RESOLUTION

You need to make sure that none of the above conditions exist in your applications. The audio mixer API set provides a means by which each condition can be checked and set accordingly.

MORE INFORMATION

Two input lines are involved when recording from the microphone: the physical source line (microphone) and the logical source line (wave in). This recording architecture can be separated into two distinct components where the signals from the microphone source line feed into the wave in destination line. Multiple controls influence these lines.

The first condition is cleared through a mute control. The second condition through a volume control. To clear the third one, use a LIST control associated with the wave input line. The following Visual C++ sample code consists of three functions for clearing these conditions, respectively. Although this sample is written in Visual C++, you can move the in-line declarations up front and modify the Visual C++ style initialization to make it a C sample:

void UnMute()
{
   // Open the mixer device
   HMIXER hmx;
   mixerOpen(&hmx, 0, 0, 0, 0);

   // Get the line info for the wave in destination line
   MIXERLINE mxl;
  mxl.cbStruct = sizeof(mxl);
  mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);

   // Now find the microphone source line connected to this wave in
   // destination
   DWORD cConnections = mxl.cConnections;
   for(DWORD j=0; j<cConnections; j++){
      mxl.dwSource = j;
      mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_SOURCE);
      if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == mxl.dwComponentType)
         break;
   }
   // Find a mute control, if any, of the microphone line
   LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(sizeof MIXERCONTROL);
   MIXERLINECONTROLS mxlctrl = {sizeof mxlctrl, mxl.dwLineID,
      MIXERCONTROL_CONTROLTYPE_MUTE, 1, sizeof MIXERCONTROL, pmxctrl};
   if(!mixerGetLineControls((HMIXEROBJ) hmx, &mxlctrl,
MIXER_GETLINECONTROLSF_ONEBYTYPE)){
      // Found, so proceed
      DWORD cChannels = mxl.cChannels;
      if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
         cChannels = 1;

      LPMIXERCONTROLDETAILS_BOOLEAN pbool =
         (LPMIXERCONTROLDETAILS_BOOLEAN) malloc(cChannels * sizeof
MIXERCONTROLDETAILS_BOOLEAN);
      MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), pmxctrl->dwControlID,
cChannels, (HWND)0,
         sizeof MIXERCONTROLDETAILS_BOOLEAN, (LPVOID) pbool};
      mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
      // Unmute the microphone line (for both channels)
      pbool[0].fValue = pbool[cChannels - 1].fValue = 0;
      mixerSetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);

    free(pmxctrl);
    free(pbool);
   }
  else
    free(pmxctrl);

   mixerClose(hmx);
}

void SetVolume()
{
   // Open the mixer device
   HMIXER hmx;
   mixerOpen(&hmx, 0, 0, 0, 0);

   // Get the line info for the wave in destination line
   MIXERLINE mxl;
    mxl.cbStruct = sizeof(mxl);
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
    mixerGetLineInfo((HMIXEROBJ)hmx, &mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE);

   // Now find the microphone source line connected to this wave in
   // destination
   DWORD cConnections = mxl.cConnections;
   for(DWORD j=0; j<cConnections; j++){
      mxl.dwSource = j;
      mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_SOURCE);
      if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == mxl.dwComponentType)
         break;
   }
   // Find a volume control, if any, of the microphone line
   LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(sizeof MIXERCONTROL);
   MIXERLINECONTROLS mxlctrl = {sizeof mxlctrl, mxl.dwLineID,
      MIXERCONTROL_CONTROLTYPE_VOLUME, 1, sizeof MIXERCONTROL, pmxctrl};
   if(!mixerGetLineControls((HMIXEROBJ) hmx, &mxlctrl,
MIXER_GETLINECONTROLSF_ONEBYTYPE)){
      // Found!
      DWORD cChannels = mxl.cChannels;
      if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
         cChannels = 1;

      LPMIXERCONTROLDETAILS_UNSIGNED pUnsigned =
(LPMIXERCONTROLDETAILS_UNSIGNED)
         malloc(cChannels * sizeof MIXERCONTROLDETAILS_UNSIGNED);
      MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), pmxctrl->dwControlID,
cChannels, (HWND)0,
         sizeof MIXERCONTROLDETAILS_UNSIGNED, (LPVOID) pUnsigned};
      mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);
      // Set the volume to the middle  (for both channels as needed)
      pUnsigned[0].dwValue = pUnsigned[cChannels - 1].dwValue =
         (pmxctrl->Bounds.dwMinimum+pmxctrl->Bounds.dwMaximum)/2;
      mixerSetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_SETCONTROLDETAILSF_VALUE);

    free(pmxctrl);
    free(pUnsigned);
   }
  else
    free(pmxctrl);
   mixerClose(hmx);
}
void SelectMic()
{
   // Open the mixer device
   HMIXER hmx;
   mixerOpen(&hmx, 0, 0, 0, 0);

   // Get the line info for the wave in destination line
   MIXERLINE mxl;
    mxl.cbStruct      = sizeof(mxl);
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
    mixerGetLineInfo((HMIXEROBJ)hmx, &mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE);

   // Find a LIST control, if any, for the wave in line
   LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(mxl.cControls * sizeof
MIXERCONTROL);
   MIXERLINECONTROLS mxlctrl = {sizeof mxlctrl, mxl.dwLineID, 0,
      mxl.cControls, sizeof MIXERCONTROL, pmxctrl};
   mixerGetLineControls((HMIXEROBJ) hmx, &mxlctrl,
MIXER_GETLINECONTROLSF_ALL);

   // Now walk through each control to find a type of LIST control. This
   // can be either Mux, Single-select, Mixer or Multiple-select.
   DWORD i;
   for(i=0; i < mxl.cControls; i++)
      if (MIXERCONTROL_CT_CLASS_LIST == (pmxctrl[i].dwControlType
&MIXERCONTROL_CT_CLASS_MASK))
         break;
   if (i < mxl.cControls) { // Found a LIST control
      // Check if the LIST control is a Mux or Single-select type
      BOOL bOneItemOnly = FALSE;
      switch (pmxctrl[i].dwControlType) {
         case MIXERCONTROL_CONTROLTYPE_MUX:
         case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
            bOneItemOnly = TRUE;
      }

      DWORD cChannels = mxl.cChannels, cMultipleItems = 0;
      if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl[i].fdwControl)
         cChannels = 1;
      if (MIXERCONTROL_CONTROLF_MULTIPLE & pmxctrl[i].fdwControl)
         cMultipleItems = pmxctrl[i].cMultipleItems;

      // Get the text description of each item
      LPMIXERCONTROLDETAILS_LISTTEXT plisttext =
(LPMIXERCONTROLDETAILS_LISTTEXT)
         malloc(cChannels * cMultipleItems * sizeof
MIXERCONTROLDETAILS_LISTTEXT);
      MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), pmxctrl[i].dwControlID,
cChannels,
         (HWND)cMultipleItems, sizeof MIXERCONTROLDETAILS_LISTTEXT,
(LPVOID) plisttext};
      mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_GETCONTROLDETAILSF_LISTTEXT);

      // Now get the value for each item
      LPMIXERCONTROLDETAILS_BOOLEAN plistbool =
(LPMIXERCONTROLDETAILS_BOOLEAN)
         malloc(cChannels * cMultipleItems * sizeof
MIXERCONTROLDETAILS_BOOLEAN);
      mxcd.cbDetails = sizeof MIXERCONTROLDETAILS_BOOLEAN;
      mxcd.paDetails = plistbool;
      mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);

      // Select the "Microphone" item
      for (DWORD j=0; j<cMultipleItems; j = j + cChannels)
         if (0 == strcmp(plisttext[j].szName, "Microphone"))
            // Select it for both left and right channels
            plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 1;
         else if (bOneItemOnly)
            // Mux or Single-select allows only one item to be selected
            // so clear other items as necessary
            plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 0;
      // Now actually set the new values in
      mixerSetControlDetails((HMIXEROBJ)hmx, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);

    free(pmxctrl);
    free(plisttext);
    free(plistbool);
   }
  else
    free(pmxctrl);
   mixerClose(hmx);
}

KBCategory: kbprb KBSubcategory: MMWave MMMixer Additional reference words: 4.00 kbdsd waveInOpen waveInAddBuffer new type waveaudio

Keywords          : kbmm MMMixer MMWave 
Version           : 4.00 | 4.00
Platform          : NT WINDOWS

Last Reviewed: May 13, 1998