1

http://mark-dot-net.blogspot.com/2009/10/playback-of-sine-wave-in-naudio.htmlから直接 SineWaveProvider32 コードで naudio を使用して、正弦波トーンを生成しています。SineWaveProvider32 クラスの関連コード:

public override int Read(float[] buffer, int offset, int sampleCount)
        {
            int sampleRate = WaveFormat.SampleRate;
            for (int n = 0; n < sampleCount; n++)
            {
                buffer[n + offset] =
                    (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
                sample++;
                if (sample >= sampleRate) sample = 0;
            }
            return sampleCount;
        }

毎秒クリック/ビートが発生していたので、変更しました

if (sample >= sampleRate) sample = 0;

if (sample >= (int)(sampleRate / Frequency)) sample = 0;

これにより、毎秒クリック数が修正されました(「サンプル」は、サンプルレートではなく、常にゼロクロッシングに関連していました)。

ただし、Amplitude 変数を設定するたびに、クリック感が得られます。buffer[] がゼロクロッシングのときだけ設定してみました。振幅の急激なジャンプが問題を引き起こしているのではないかと考えました。それは問題を解決しませんでした。振幅を 0.25 から 0.0 の間の値に設定しています

NAudio change volume in runtimeで提案されているように、レイテンシーとバッファー数を調整しようとしましたが、それも効果がありませんでした。

振幅を変更する私のコード:

public async void play(int durationMS, float amplitude = .25f)
        {
        PitchPlayer pPlayer = new PitchPlayer(this.frequency, amplitude);
            pPlayer.play();
            await Task.Delay(durationMS/2);
            pPlayer.provider.Amplitude = .15f;
            await Task.Delay(durationMS /2);
            pPlayer.stop();
    }
4

2 に答える 2

0

クリックは、波形の不連続によって発生します。このようなクラスでこれを修正するのは困難です。理想的には、音量をある値から別の値にゆっくりと上げていくことになるからです。これは、目標振幅を持つようにコードを変更することで実行できます。次に、現在の振幅が目標振幅と等しくない場合は、ループを通過するたびに計算される小さなデルタ量だけ目標振幅に向かって移動します。したがって、たとえば 10 ミリ秒の期間にわたって、古い振幅から新しい振幅に移動します。しかし、残念ながらこれは自分で書く必要があります。

振幅ではなく周波数が徐々に変化する同様の概念については、NAudio のポルタメントに関する私のブログ投稿をご覧ください。

于 2016-09-08T21:38:31.667 に答える