Как настроить усиление микрофона от C # (необходимо работать на XP & W7)

StackOverflow https://stackoverflow.com/questions/3022981

  •  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;
                                }
                            }
                        }
                    }
                }
            }
        }

    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top