Whole day I was looking for some tutorial or piece of code, "just" to play simple sin wave for "infinity" time. I know it sounds a little crazy.
But I want to be able to change frequency of tone in time, for instance - increase it. Imagine that I want to play tone A, and increase it to C in "+5" frequency steps each 3ms (it's really just example), don't want to have free places, stop the tone.
Is it possible? Or can you help me?
Use NAudio library for audio output.
Make notes wave provider:
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);
}
start play:
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();
add new notes:
void Timer_Tick(...)
{
if (Notes.Count < 10)
Notes.Add(new Note{Frecuency = 900});
}
ps this code is idea only. for real using add mt-locking etc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With