PRB: No Signal is Recorded When Using MCI or waveInxxx APIsLast reviewed: November 22, 1996Article ID: Q159753 |
The information in this article applies to:
SYMPTOMSThere is no signal recorded using MCI (Media Control Interface) or waveInXXX APIs to record through the microphone.
CAUSEThere are three possible causes:
RESOLUTIONYou 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 INFORMATIONTwo 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 * sizeofMIXERCONTROL); 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 * sizeofMIXERCONTROLDETAILS_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 * sizeofMIXERCONTROLDETAILS_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: kbmm kbprb
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |