2011-03-30 19 views
6

Estoy usando NAudio para reproducir una onda senoidal de una frecuencia determinada como en la publicación del blog Playback of Sine Wave in NAudio. Solo quiero reproducir el sonido() durante x milisegundos y luego detenerlo.NAudio tocando una onda sinusoidal durante x milisegundos usando C#

Probé un thread.sleep, pero el sonido se detiene enseguida. Probé un temporizador, pero cuando se elimina el WaveOut, hay una excepción entre hilos.

He intentado este código, pero cuando llamo a un bip, el programa se congela.

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 - eso es lo que hace el método de lectura - se llama cuando la tarjeta de sonido necesita más datos –

Respuesta

4

La clase SineWaveProvider32 no necesita proporcionar audio de forma indefinida. Si desea que el pitido tenga una duración máxima de un segundo (por ejemplo), entonces para mono 44.1   kHz, debe proporcionar 44,100 muestras. El método Read debería devolver 0 cuando no tiene más datos para suministrar.

Para que el hilo de tu GUI no se bloquee, debes deshacerte de Thread.Sleep, waveOut.Stop y Dispose, y simplemente comenzar a reproducir el audio (es posible que los callbacks sean más confiables que la función).

Luego, cuando el audio haya terminado de reproducirse, puede cerrar y limpiar el objeto WaveOut.

0

Mira la entrada de blog Pass Variables to a New Thread in C# sobre cómo pasar variables a otro hilo.

Creo que lo que quieres hacer es algo así como crear un hilo que reproduzca tu sonido, crear un temporizador y comenzar el hilo. Cuando el temporizador expira, mata el hilo, y cuando el hilo se cierra, haz toda la limpieza.

Cuestiones relacionadas