Как настроить усиление микрофона от C # (необходимо работать на XP & W7)
-
26-09-2019 - |
Вопрос
Во-первых, обратите внимание, что я знаю, что есть такие вопросы, как это уже опубликовано; Однако они, кажется, не решают проблему адекватно. У меня есть приложение C #, со всеми крючками PinVoke, чтобы поговорить с API WAVEXXX, и я могу сделать захват и воспроизведение звука с этим. Я также могу настроить громкость динамика (Waxout) с помощью этого API.
Проблема в том, что по любой причине, что API не позволяет мне регулировать объем микрофона (волны). Итак, мне удалось найти какой-то код микшера, который я также вытащил и доступа через PinVoke, и это позволяет мне регулировать громкость микрофона, но только на моем ПК W7. Смеситель, который я начал с отсюда:http://social.msdn.microsoft.com/forums/en-us/isvvba/thrad/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 (Out Mixer, 0, 0, 0, 0) код не возвращает сбой, но усиление микрофона не зависит. Примечание, как я уже сказал выше, это работает на W7 (вторая попытка никогда не выполняется, потому что она не завершается использованием Mixeropen (Out Mixer, MXID, 0, 0, Mixer_objectf_wavein)).
Я признаюсь, что не иметь хорошего понимания на API микшера, так что это то, что я ищу сейчас; Однако, если у кого-то есть ключ, почему это будет работать на W7, но не XP, я бы хотел услышать это. Между тем, если я пойму это, прежде чем получить ответ, я опубликую свой ответ ...
Решение 2
Следующий код, кажется, работает хорошо для меня сейчас (Обновлено 6/29/2010.). Обратите внимание, что мои тестовые случаи - мои два компьютера, одна из которых является 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». Не очень понимаю это, поэтому, если кто-то хочет взломать с объяснением (или сказать мне, что это не будет работать в общем времени), я приветствую ответы!
Другие советы
Я пытался сделать именно это некоторое время назад, когда я писал .Net голосовой рекордер используя Naudio, и нашел его чрезвычайно сложным. Вам, вероятно, пришлось в конечном итоге написать два много кода, один для 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;
}
}
}
}
}
}
}
}