Naudio che suona un'onda sinusoidale per x millisecondi usando c #
-
14-11-2019 - |
Domanda
Sto usando naudio per riprodurre un sinewave di una determinata frequenza come nel post del blog Riproduzione dell'onda sinusoidale in Naudio .Voglio solo che il suono gioca () per x millisecondi e poi fermati.
Ho provato un thread.sleep, ma il suono si ferma subito.Ho provato un timer, ma quando il waveout è disposto c'è un'eccezione cross-thread.
Ho provato questo codice, ma quando chiamo BEEP, il programma si blocca.
.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;
}
}
Soluzione
La classe SINEWAVESPROVIDER32 non ha bisogno di fornire indefinitamente audio.Se vuoi che il bip abbia una durata massima di un secondo (ad esempio), quindi per Mono 44.1 KHz, è necessario fornire 44.100 campioni.Il metodo di lettura dovrebbe restituire 0 quando non ha più dati da fornire.
Per effettuare il blocco della tua filettatura GUI, è necessario liberarti di thread.Sleep, Waveout.Stop e smaltire, e semplicemente avviare la riproduzione dell'audio (è possibile trovare le callback delle finestre più affidabili della funzione).
Quindi, quando l'audio ha finito di riproduzione, è possibile chiudere e ripulire l'oggetto Waveout.
Altri suggerimenti
Dai un'occhiata al post del blog Passa le variabili a un nuovo filo in c # su come passare le variabili a un altro filo.