2011-03-30 7 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 메서드가하는 일입니다. 사운드 카드에 더 많은 데이터가 필요할 때마다 호출됩니다. –

답변

4

SineWaveProvider32 클래스는 오디오를 무기한 제공 할 필요가 없습니다. 경고음의 최대 지속 시간을 1 초 (말)로하려면 모노 44.1   kHz의 경우 44,100 샘플을 제공해야합니다. Read 메서드는 더 이상 제공 할 데이터가 없으면 0을 반환해야합니다.

GUI 스레드를 차단하지 않으려면 Thread.Sleep, waveOut.Stop 및 Dispose를 제거하고 단순히 오디오 재생을 시작해야합니다 (함수보다 안정적인 윈도우 콜백을 찾을 수 있음).

그런 다음 오디오 재생이 끝나면 WaveOut 개체를 닫고 정리할 수 있습니다.

0

체크 아웃 블로그 게시물 다른 스레드에 변수를 전달하는 방법에 Pass Variables to a New Thread in C#합니다.

나는 사운드를 재생하고, 타이머를 만들고, 스레드를 시작하는 스레드를 만드는 것과 같다고 생각합니다. 타이머가 만료되면 스레드를 종료하고 스레드가 종료되면 모든 정리를 수행합니다.