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

Во-первых, обратите внимание, что я знаю, что существует несколько вопросов как это уже отправленное; однако они, кажется, не решают проблему соответственно. У меня есть приложение C# со всеми рычагами pInvoke, чтобы говорить с waveXXX API, и я могу сделать получение и воспроизвести аудио с этим. Я также могу скорректировать динамик (WaveOut) объем с тем API.
Проблема состоит в том, что по любой причине, что API не позволяет мне корректировать микрофон (WaveIn) объем. Так, мне удалось найти некоторый код микшера, который я также втянул и доступ через pInvoke, и это позволяет мне корректировать громкость микрофона, но только на моем ПК W7. Код микшера, с которого я запустил, появляется отсюда: 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, я буду уверенный любить слышать его. Между тем, если я пойму это, прежде чем я получу ответ, я отправлю свой собственный ответ...

7
задан Ed. 11 June 2010 в 13:11
поделиться

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'. Я не совсем понимаю это, так что если кто-то хочет вступить в разговор с объяснением (или сказать мне, что это не будет работать в общем случае), я буду рад ответам!

1
ответ дан 7 December 2019 в 18:40
поделиться

Я пытался сделать именно это некоторое время назад, когда писал .NET Voice Recorder с помощью 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;
                                }
                            }
                        }
                    }
                }
            }
        }

    }
1
ответ дан 7 December 2019 в 18:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: