首先,请注意我知道有一些问题已经发布;但他们 似乎没有充分解决问题。我有一个C#应用程序,所有的pInvoke挂钩都与waveXXX API对话,我能够捕获和回放 音频与此。我也可以使用该API调整扬声器(WaveOut)音量 问题在于,无论出于何种原因,该API都不允许我调整麦克风 (WaveIn)音量。所以,我设法找到了一些我也提到过的调音台代码 通过pInvoke访问并允许我调整麦克风音量,但仅限于我的W7 PC。我开始使用的混音器代码来自这里: http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/05dc2d35-1d45-4837-8e16-562ee919da85 它的工作原理,但写的是调整扬声器音量。我添加了SetMicVolume方法 这里显示...
public static void SetMicVolume(int mxid, int percentage)
{
bool rc;
int mixer, vVolume;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN);
int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol);
if (rc == false)
{
mixerClose(mixer);
mixerOpen(out mixer, 0, 0, 0, 0);
rc = GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, type, out volCtrl, out currentVol);
if (rc == false)
throw new Exception("SetMicVolume/GetVolumeControl() failed");
}
vVolume = ((int)((float)(volCtrl.lMaximum - volCtrl.lMinimum) / 100.0F) * percentage);
rc = SetVolumeControl(mixer, volCtrl, vVolume);
if (rc == false)
throw new Exception("SetMicVolume/SetVolumeControl() failed");
mixerClose(mixer);
}
注意调用GetVolumeControl()的“第二次尝试”。这样做是因为在XP上,在第一次调用GetVolumeControl时(参考上面的站点获取该代码),调用mixerGetLineControlsA()失败,XP系统返回MIXERR_INVALCONTROL。然后,使用mixerOpen(输出混音器,0,0,0,0)的第二次尝试,代码不会返回故障但麦克风增益不受影响。请注意,正如我上面所说,这适用于W7(第二次尝试永远不会执行,因为它使用mixerOpen(输出混音器,mxid,0,0,MIXER_OBJECTF_WAVEIN)不会失败。)
我承认没有很好地掌握混音器API,所以这就是我现在正在研究的内容;但是,如果有人知道为什么这可以在W7上运行,而不是XP,我肯定希望听到它。同时,如果我在得到答复之前弄明白,我会发布自己的答案......
答案 0 :(得分:1)
前一段时间我正在尝试使用NAudio编写.NET Voice Recorder,并发现它非常难。您可能最终需要编写两个代码,一个用于XP,一个用于Vista / Win 7.我使用NAudio用于混合器互操作。
这就是我最终的结果(到处都不起作用)
private void TryGetVolumeControl()
{
int waveInDeviceNumber = waveIn.DeviceNumber;
if (Environment.OSVersion.Version.Major >= 6) // Vista and over
{
var mixerLine = new MixerLine((IntPtr)waveInDeviceNumber, 0, MixerFlags.WaveIn);
foreach (var control in mixerLine.Controls)
{
if (control.ControlType == MixerControlType.Volume)
{
volumeControl = control as UnsignedMixerControl;
MicrophoneLevel = desiredVolume;
break;
}
}
}
else
{
var mixer = new Mixer(waveInDeviceNumber);
foreach (var destination in mixer.Destinations)
{
if (destination.ComponentType == MixerLineComponentType.DestinationWaveIn)
{
foreach (var source in destination.Sources)
{
if (source.ComponentType == MixerLineComponentType.SourceMicrophone)
{
foreach (var control in source.Controls)
{
if (control.ControlType == MixerControlType.Volume)
{
volumeControl = control as UnsignedMixerControl;
MicrophoneLevel = desiredVolume;
break;
}
}
}
}
}
}
}
}
答案 1 :(得分:1)
以下代码现在似乎对我有效(已于2010年6月29日更新)。请注意,我的测试用例是我的两台PC,一台是W7,另一台是XP,所以它不是决定性的。我已经证实这不适用于所有机器,但是对于那些机器,它似乎很好。
public static bool setMicVolume(int mxid, int percentage)
{
if (mixerdisabled)
return(false);
bool rc;
int mixer, vVolume, ctrltype, comptype;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
int mr = mixerOpen(out mixer, mxid, 0, 0, MIXER_OBJECTF_WAVEIN);
if (mr != MMSYSERR_NOERROR)
{
Warning("mixerOpen() failed: " + mr.ToString());
mixerdisabled = true;
return(false);
}
ctrltype = MIXERCONTROL_CONTROLTYPE_VOLUME;
comptype = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
rc = GetVolumeControl(mixer, comptype, ctrltype, out volCtrl, out currentVol);
if (rc == false)
{
Warning("SetMicVolume/GetVolumeControl() failed");
mixerdisabled = true;
mixerClose(mixer);
return(false);
}
vVolume = ((int)((float)(volCtrl.lMaximum - volCtrl.lMinimum) / 100.0F) * percentage);
rc = SetVolumeControl(mixer, volCtrl, vVolume);
if (rc == false)
{
Warning("SetMicVolume/SetVolumeControl() failed");
mixerdisabled = true;
mixerClose(mixer);
return (false);
}
mixerClose(mixer);
return (true);
}
请注意,主要区别在于我使用的是“MIXERLINE_COMPONENTTYPE_DST_WAVEIN”的组件类型,而不是“MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE”。真的不明白这一点,所以如果有人想要解释(或者告诉我这一般不会起作用),我很欢迎回复!