2011-03-30 41 views
6

我使用NAudio播放給定頻率的正弦波,如在博文中Playback of Sine Wave in NAudio。我只想讓聲音播放()x毫秒,然後停下來。NAudio使用C#播放正弦波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; 
     } 
    } 
+0

@Hans - 這就是Read方法的作用 - 只要聲卡需要更多數據就會調用它 – 2011-04-14 06:15:29

回答

4

SineWaveProvider32類不需要無限期地提供音頻。如果您希望蜂鳴聲的最長持續時間爲一秒(比如說),那麼對於單聲道44.1   kHz,您需要提供44,100個採樣。 Read方法在沒有更多數據要提供時應該返回0。

爲了讓您的GUI線程不被阻塞,您需要擺脫Thread.Sleep,waveOut.Stop和Dispose,並且只需開始播放音頻(您可能會發現窗口回調比函數更可靠)。

然後,當音頻播放完畢後,您可以關閉並清理WaveOut對象。

0

退房的博客文章Pass Variables to a New Thread in C#如何將變量傳遞到另一個線程。

我想你想要做的就像創建一個播放聲音的線程,創建一個計時器並啓動線程。當計時器到期時,殺死該線程,並在線程關閉時執行全部清理。