7

まず、このようないくつかの質問がすでに投稿されていることを私は知っていることに注意してください。しかし、彼らは問題に適切に対処していないようです。私はC#アプリケーションを持っており、waveXXX APIと通信するためのすべてのpInvokeフックがあり、それを使用してオーディオのキャプチャと再生を行うことができます。そのAPIでスピーカー(WaveOut)の音量を調整することもできます。
問題は、何らかの理由で、そのAPIではマイク(WaveIn)の音量を調整できないことです。そのため、pInvokeを介してプルインしてアクセスし、マイクの音量を調整できるミキサーコードを見つけることができましたが、これはW7PCでのみ可能です。私が始めたミキサーコードはここから来ています: 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()を呼び出す「2回目の試行」に注意してください。これが行われるのは、XPでは、GetVolumeControlの最初の呼び出し(そのコードについては上記のサイトを参照)で、mixerGetLineControlsA()の呼び出しが失敗し、XPシステムがMIXERR_INVALCONTROLを返すためです。次に、mixerOpen(out Mixer、0、0、0、0)を使用したこの2回目の試行では、コードは失敗を返しませんが、マイクゲインは影響を受けません。上で述べたように、これはW7で機能することに注意してください(mixerOpen(out Mixer、mxid、0、0、MIXER_OBJECTF_WAVEIN)を使用して失敗しないため、2回目の試行は実行されません)。

私はミキサーAPIをよく理解していないことを認めているので、それが私が今調べていることです。ただし、これがW7で機能するが、XPでは機能しない理由がわかれば、ぜひ聞いてみたいと思います。そんな中、返事が来る前にわかったら、自分で答えを投稿します...

4

2 に答える 2

1

少し前にNAudioを使って.NETボイスレコーダーを書いていたときにこれを正確にやってみましたが、非常に難しいことがわかりました。XP用とVista/Win7用の2つのコードを書く必要があるでしょう。私はミキサーの相互運用に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;
                                }
                            }
                        }
                    }
                }
            }
        }

    }
于 2010-06-11T13:37:32.447 に答える
1

次のコードは今は問題なく動作しているようです( 2010年6月29日更新)。私のテストケースは2台のPCであり、1台はW7、もう1台は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_SRC_MICROPHONE」ではなく「MIXERLINE_COMPONENTTYPE_DST_WAVEIN」のコンポーネントタイプを使用していることです。これを本当に理解していないので、誰かが説明でチャイムを鳴らしたい場合(またはこれは一般的には機能しないと私に言いたい場合)、私は返信を歓迎します!

于 2010-06-11T17:04:09.607 に答える