7

ブログ投稿「NAudioでの正弦波の再生」のように、 NAudioを使用して特定の周波数の正弦波を再生しています。サウンドをxミリ秒再生してから停止したいだけです。

thread.sleepを試しましたが、すぐに音が止まります。タイマーを試しましたが、WaveOutが破棄されると、クロススレッド例外が発生します。

このコードを試しましたが、ビープ音を鳴らすとプログラムがフリーズします。

public class Beep
{
    public Beep(int freq, int ms)
    {
        SineWaveProvider32 sineWaveProvider = new SineWaveProvider32();
        sineWaveProvider.Amplitude = 0.25f;
        sineWaveProvider.Frequency = freq;

        NAudio.Wave.WaveOut waveOut = new NAudio.Wave.WaveOut(WaveCallbackInfo.FunctionCallback());
        waveOut.Init(sineWaveProvider);
        waveOut.Play();
        Thread.Sleep(ms);
        waveOut.Stop();
        waveOut.Dispose();
    }
}

public class SineWaveProvider32 : NAudio.Wave.WaveProvider32
{
    int sample;

    public SineWaveProvider32()
    {
        Frequency = 1000;
        Amplitude = 0.25f; // Let's not hurt our ears
    }

    public float Frequency { get; set; }
    public float Amplitude { get; set; }

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

2 に答える 2

4

SineWaveProvider32 クラスは、オーディオを無期限に提供する必要はありません。ビープ音の最大持続時間を 1 秒 (たとえば) にしたい場合、モノ 44.1 kHz の場合、44,100 サンプルを提供する必要があります。提供するデータがなくなると、Read メソッドは 0 を返す必要があります。

GUI スレッドがブロックされないようにするには、Thread.Sleep、waveOut.Stop、および Dispose を取り除き、単純にオーディオの再生を開始する必要があります (関数よりもウィンドウ コールバックの方が信頼できる場合があります)。

次に、オーディオの再生が終了したら、WaveOut オブジェクトを閉じてクリーンアップできます。

于 2011-04-14T06:19:28.687 に答える
0

変数を別のスレッドに渡す方法については、C# で変数を新しいスレッドに渡すというブログ投稿を参照してください。

あなたがやりたいことは、サウンドを再生するスレッドを作成し、タイマーを作成し、スレッドを開始するようなものだと思います。タイマーが切れたら、スレッドを強制終了し、スレッドが閉じると、すべてのクリーンアップを実行します。

于 2011-03-30T11:42:39.140 に答える