My first post here; I think this is the right group to ask this question; if not, or if there are other relevant groups, please feel free to direct me to them.
Background: I have a C++ WinXP speech recognition application that takes spoken input from a mike. It must interact with different people at different times, and these people's voices may have very different levels of amplitude. One person's speech might cause clipping, for example, while another's may be perfectly normal, or even too soft. It is thus not possible to select a fixed recording volume that is suitable for all.
My query: How can my application change the machine's recording volume at will? For example, I'd like the app to be able to turn the volume down if it detects clipping. I know there is a setWaveOutVolume API, but I have also learned from various searches that there is no corresponding setWaveInVolume API. There *must* be a solution somehow. I'd prefer to have it be a simple one, if possible. ;)
Just to make matters worse, we also use an Andrea USB SoundPod adapter, as well as direct connection the standard mike jack. Is there a solution that would work for both? (probably this is a dumb question)
> My first post here; I think this is the right group to ask this > question; if not, or if there are other relevant groups, please feel > free to direct me to them.
> Background: I have a C++ WinXP speech recognition application that > takes spoken input from a mike. It must interact with different people > at different times, and these people's voices may have very different > levels of amplitude. One person's speech might cause clipping, for > example, while another's may be perfectly normal, or even too soft. It > is thus not possible to select a fixed recording volume that is suitable > for all.
> My query: How can my application change the machine's recording volume > at will? For example, I'd like the app to be able to turn the volume > down if it detects clipping. I know there is a setWaveOutVolume API, > but I have also learned from various searches that there is no > corresponding setWaveInVolume API. There *must* be a solution somehow. > I'd prefer to have it be a simple one, if possible. ;)
> Just to make matters worse, we also use an Andrea USB SoundPod adapter, > as well as direct connection the standard mike jack. Is there a > solution that would work for both? (probably this is a dumb question)
I think the only way is to get involved with windows Mixer API. I found this a seriously brain-tiring activity <g>.
My first step was (and possibly yours would be) to get a document entitled "Mixing it up with the Mixer" by Steven Roman. This _was_ with MSDN (Microsoft Developers Network) but I think that later MSDN issues have omitted it.
Then having understood mixers, you would search for a source mixer- line of type SRC_MICROPHONE and then look for a control of type VOLUME on that line.
I have an MSWord copy of "Mixing it up with the Mixer" and also a small app which enumerates all mixer lines and displays their controls. I'll send you a copy if you email me. However while the app would tell you what is there, the source is in Delphi, but might be helpful to you.
>On Jan 29, 3:38=EF=BF=BDam, Dave Stallard <stall...@nospam.net> wrote: >> My first post here; I think this is the right group to ask this >> question; if not, or if there are other relevant groups, please feel >> free to direct me to them.
>> Background: =A0I have a C++ WinXP speech recognition application that >> takes spoken input from a mike. =A0 It must interact with different people >> at different =A0times, and these people's voices may have very different >> levels of amplitude. =A0One person's speech might cause clipping, for >> example, while another's may be perfectly normal, or even too soft. =A0It >> is thus not possible to select a fixed recording volume that is suitable >> for all.
>> My query: How can my application change the machine's recording volume >> at will? =A0For example, I'd like the app to be able to turn the volume >> down if it detects clipping. =A0 I know there is a setWaveOutVolume API, >> but I have also learned from various searches that there is no >> corresponding setWaveInVolume API. =A0 There *must* be a solution somehow. >> =A0 =A0I'd prefer to have it be a simple one, if possible. =A0;)
>> Just to make matters worse, we also use an Andrea USB SoundPod adapter, >> as well as direct connection the standard mike jack. =A0 Is there a >> solution that would work for both? (probably this is a dumb question)
>I think the only way is to get involved with windows Mixer API. I=20 >found this a seriously brain-tiring activity <g>.
>My first step was (and possibly yours would be) to get a document=20 >entitled "Mixing it up with the Mixer" by Steven Roman. This _was_=20 >with MSDN (Microsoft Developers Network) but I think that later MSDN=20 >issues have omitted it.
>Then having understood mixers, you would search for a source mixer- >line of type SRC_MICROPHONE and then look for a control of type VOLUME=20 >on that line.
>I have an MSWord copy of "Mixing it up with the Mixer" and also a=20 >small app which enumerates all mixer lines and displays their=20 >controls. I'll send you a copy if you email me. However while the app=20 >would tell you what is there, the source is in Delphi, but might be=20 >helpful to you.
I'll second that suggestion to get "Mixing it up with the mixer". I also found it very useful to download Mixer Browser (you'll have to Google for it), which shows you all the controls and their line IDs, etc in a neat, logical window layout.
The only other way out of this would be to use a sleazy trick: Set the recording volume manually using the mixer sliders such that nobody ever goes into clipping. That will mean that many people will come through too soft, and you will need to boost their signals in software. That's a bad idea in general since it will also boost internal preamp noise, and may run into quantization problems if carried too far. But for many applications the acoustic background noise will be higher than the internal noise anyway, so this trick won't be a problem.
Consider that if you have a 16-bit system you can probably afford to have the normal "soft" voices 48 dB down, where they will be equivalent to an 8-bit system (which is usually OK for voice). You can then adjust the soft ones up (or the loud ones down) as needed for the final mix.
Of course, whichever approach you choose, you will need to be able to determine the peak and average levels of the voices in software, either to change the mixer or to scale the signals.
Best regards,
Bob Masta dqatechATdaqartaDOTcom
D A Q A R T A Data AcQuisition And Real-Time Analysis www.daqarta.com Scope, Spectrum, Spectrogram, Signal Generator Science with your sound card!
Reading what you described it all depends on how you design your application.
If you receive the audio streams independently and play them independently (and simultaneously) then the Mixer API will not work for you. Because though you can pass the waveout of which waveout created still the volume change will affect all the streams being played. I would probably choose this one - if you are having separate input streams from eachone then convert each stream to a PCM format. - Process the PCM stream to determine the maximum/minimum levels and adjust them accordingly. Now that each stream is OK play them separately and simultaneously or use some algorithm to mix them and play them.
Generally however if an input stream is too low or high then you'd better adjust the microphone level (wavein) of the producer. Then you can filter or do whatever processing needed.
To set the microphone volume use this
function SetMicrophoneVolume(ADeviceID: Integer; bValue: Word; AOpenFlag: Cardinal): Boolean; var hMix: HMIXER; mxlc: MIXERLINECONTROLS; mxcd: TMIXERCONTROLDETAILS; vol: TMIXERCONTROLDETAILS_UNSIGNED; mxc: MIXERCONTROL; mxl: TMixerLine; intRet: Integer; nMixerDevs: Integer; cConnections: DWord; j: DWORD; begin // Check if Mixer is available Result := True; nMixerDevs := mixerGetNumDevs(); if (nMixerDevs < 1) then begin Result := False; exit; end;
// open the mixer intRet := mixerOpen(@hMix, ADeviceID, 0, 0, AOpenFlag); if intRet = MMSYSERR_NOERROR then begin mxl.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_WAVEIN; mxl.cbStruct := SizeOf(mxl);
// get line info intRet := mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
if intRet = MMSYSERR_NOERROR then begin
cConnections := mxl.cConnections;
for j := 0 to cConnections - 1 do begin mxl.dwSource := j; mixerGetLineInfo(hMix, @mxl, MIXER_GETLINEINFOF_SOURCE); if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = mxl.dwComponentType) then break; end;
if intRet = MMSYSERR_NOERROR then begin ZeroMemory(@mxcd, SizeOf(mxcd)); mxcd.dwControlID := mxc.dwControlID; mxcd.cbStruct := SizeOf(mxcd); mxcd.cMultipleItems := 0; mxcd.cbDetails := SizeOf(Vol); mxcd.paDetails := @vol; mxcd.cChannels := 1;
vol.dwValue := bValue;
intRet := mixerSetControlDetails(hMix, @mxcd, MIXER_SETCONTROLDETAILSF_VALUE); if intRet <> MMSYSERR_NOERROR then Result := False; end else Result := False; end else Result := False; mixerClose(hMix); end; end;
Where if you have the wavein handle call the function thisway: SetMicrophoneVolume(waveinhadle, micvolume; MIXER_OBJECTF_HWAVEIN)
If you don't have the wavein handle you could call the function this way SetMicrophoneVolume(SoundDeviceHandle, micvolume; MIXER_OBJECTF_WAVEIN)
The function returns True if there is a Microphone level control else returns False
Hope this helps
"Dave Stallard" <stall...@nospam.net> wrote in message
> My first post here; I think this is the right group to ask this question; > if not, or if there are other relevant groups, please feel free to direct > me to them.
> Background: I have a C++ WinXP speech recognition application that takes > spoken input from a mike. It must interact with different people at > different times, and these people's voices may have very different levels > of amplitude. One person's speech might cause clipping, for example, > while another's may be perfectly normal, or even too soft. It is thus not > possible to select a fixed recording volume that is suitable for all.
> My query: How can my application change the machine's recording volume at > will? For example, I'd like the app to be able to turn the volume down if > it detects clipping. I know there is a setWaveOutVolume API, but I have > also learned from various searches that there is no corresponding > setWaveInVolume API. There *must* be a solution somehow. I'd prefer to > have it be a simple one, if possible. ;)
> Just to make matters worse, we also use an Andrea USB SoundPod adapter, as > well as direct connection the standard mike jack. Is there a solution > that would work for both? (probably this is a dumb question)