biblioteca Uso NAudio para la salida de audio.
Tome notas proveedor de onda:
class NotesWaveProvider : WaveProvider32
{
public NotesWaveProvider(Queue<Note> notes)
{
this.Notes = notes;
}
public readonly Queue<Note> Notes;
int sample = 0;
Note NextNote()
{
for (; ;)
{
if (Notes.Count == 0)
return null;
var note = Notes.Peek();
if (sample < note.Duration.TotalSeconds * WaveFormat.SampleRate)
return note;
Notes.Dequeue();
sample = 0;
}
}
public override int Read(float[] buffer, int offset, int sampleCount)
{
int sampleRate = WaveFormat.SampleRate;
for (int n = 0; n < sampleCount; n++)
{
var note = NextNote();
if (note == null)
buffer[n + offset] = 0;
else
buffer[n + offset] = (float)(note.Amplitude * Math.Sin((2 * Math.PI * sample * note.Frequency)/sampleRate));
sample++;
}
return sampleCount;
}
}
class Note
{
public float Frequency;
public float Amplitude = 1.0f;
public TimeSpan Duration = TimeSpan.FromMilliseconds(50);
}
reproducción de inicio:
WaveOut waveOut;
this.Notes = new Queue<Note>(new[] { new Note { Frequency = 1000 }, new Note { Frequency = 1100 } });
var waveProvider = new NotesWaveProvider(Notes);
waveProvider.SetWaveFormat(16000, 1); // 16kHz mono
waveOut = new WaveOut();
waveOut.Init(waveProvider);
waveOut.Play();
añadir nuevas notas:
void Timer_Tick(...)
{
if (Notes.Count < 10)
Notes.Add(new Note{Frecuency = 900});
}
ps este código es la idea única. de verdad usando add mt-locking etc
Funciona muy bien para lanzar una secuencia de notas. , agregar más notas a la cola después de que la "melodía" inicial haya finalizado no funciona correctamente. Es de esperar que la nueva nota comience inmediatamente. Esto se puede lograr con el código anterior insertando un reinicio del contador de muestras en el enunciado if (Notes.Count == 0) return null; ... mi código es ahora: if (Notes.Count == 0) {sample = 0; return null;}. En este caso, la siguiente nota comenzará inmediatamente, también si se inicia unos segundos más tarde. Además, el para (;;) no es necesario en NextNote. – Goodies