3

NAudio を使用してピーク ボリューム メーターを作成しようとしています。私のコードはhttp://channel9.msdn.com/coding4fun/articles/NET-Voice-Recorderと非常によく似ていますが、私のコードとリンクされた Voice Recorder プロジェクトの両方に問題があります。

周波数と音量が一定のサウンドを再生する場合、音量メーターは最初は妥当なレベルで始まりますが、その後非常に小さな値に減衰します。NAudioDemo のピーク ボリューム メーターはこれを行わないため、なぜそうなるのかはわかりません。私のプログラムで NAudioDemo からコードを複製しようとしましたが、ピーク ボリューム メーター コードを含むコード ファイルを見つけることができませんでした。

誰かがピーク ボリューム メーターを作成するための代替ソリューションを案内してくれたり、私のソリューション (およびリンクで提供されているソリューション) の両方が機能しない理由を判断するのに役立ちますか?

public MainWindow()
    {
        int waveInDevices = WaveIn.DeviceCount;
        for (int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
        {
            WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
            Console.WriteLine("Device {0}: {1}, {2} channels",
                waveInDevice, deviceInfo.ProductName, deviceInfo.Channels);

            WaveIn waveIn = new WaveIn();
            waveIn.DeviceNumber = 0; //TODO: Let the user choose which device, this comes from the device numbers above
            waveIn.DataAvailable += waveIn_DataAvailable;
            int sampleRate = SAMPLE_RATE; // 8 kHz
            int channels = 1; // mono
            waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
            waveIn.StartRecording();
        }
    }

    void waveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        for (int index = 0; index < e.BytesRecorded; index += 2)
        {
            short sample = (short)((e.Buffer[index + 1] << 8) |
                                    e.Buffer[index + 0]);
            float sample32 = sample / 32768f;
            ProcessSample(sample32);
        }           

    }

    void ProcessSample(float sample1)
    {
        samplenumber += 1;

        if (sample1 > maxval)
        {
            maxval = sample1;
        }

        if (sample1 < minval)
        {
            minval = sample1;
        }


        //Run updateView every few loops

        if (samplenumber > (double)SAMPLE_RATE / DISPLAY_UPDATE_RATE)
        {
            samplenumber = 0;
            updateView(); //needs to be fast!
        }
    }

    void updateView()
    {
        Console.WriteLine(maxval);
        Console.WriteLine(minval);
        progressBar1.Value = (maxval - minval)*50;

        maxval = 0;
        minval = 0;
    }
4

3 に答える 3

6

その記事で起こっているのは、小さな間隔(たとえば、20ms)で最大のオーディオピークを見つけて、それをデシベルスケールでプロットしているということだけです。ピークを見つけるには、間隔内の各サンプルの値を調べて、最大値を選択します(これはSampleAggregatorクラスが行っていることです)。デシベルに変換するには、最大値の10を底とする対数を取り、10を掛けます。したがって、0dBが最も大きく、-96dBより下の値は事実上無音です。(実際、記事を振り返ると、デシベルスケールに変換することすら気にならなかったと思います。おそらくそうすべきだったでしょう)

于 2013-01-16T09:27:42.477 に答える
3

これは、出力デバイスからピークを取得するための私の小さな解決策でした。NAudio バージョン 1.7.0.15 を使用しています

 public partial class Form1 : Form
{


    public Form1()
    {
        InitializeComponent();

        MMDeviceEnumerator enumerator = new MMDeviceEnumerator();

        var devices = enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active);
        comboboxDevices.Items.AddRange(devices.ToArray());
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (comboboxDevices.SelectedItem != null)
        {
            var device = (MMDevice)comboboxDevices.SelectedItem;
            progressBar1.Value = (int)(Math.Round(device.AudioMeterInformation.MasterPeakValue * 100));
        }
    }
}
于 2014-06-05T07:00:56.327 に答える
0

MasterPeakValue を使用してレベルを取得しようとすると、単にメソッドを呼び出すよりも複雑に見え、単純さが損なわれます。

着信データを使用しない場合でも、記録するためにデバイスを開く必要があることに偶然気付きました。WaveIn を開始しているため、MasterPeakValue は 0 以外の値を返す必要があります。

テスト用の簡単な代替手段は、システムの録音デバイスのプロパティを開くことです (システムのボリューム アイコンを右クリックし、[録音デバイス] を選択します)。

(2 台の異なるコンピューターでテストされています。)

于 2016-04-12T11:05:33.460 に答える