Here’s a
code sample I’ve been meaning to share on my blog for years.
NAudio already has a built-in SignalGenerator class which can generate sine waves as well as various other waveforms. But what if you want to implement “portamento” to glide smoothly between frequencies?
One simple way to do this is to make use of a “wavetable”. Basically we store one cycle of a sine wave in a memory buffer, and then to work out what the next sample to be played is, we move forward a certain number of slots in that buffer and read out the value. If we go past the end of the buffer we simply start again.
If we call the current position in the waveform the “phase” and the number of steps in the wavetable we must move forward the “phase step”, then when the target frequency is changed, instead of immediately recalculating a new “phase step”, we slowly change the current phase step until it reaches the desired phase step.
It’s quite a simple technique, and the great thing is that it works for any waveform, so you could quite easily do the same with square or sawtooth waveforms.
Here’s a really basic implementation of this, which allows you to customise the portamento time. I meant for this setting to be in seconds, but I think I’ve got it slightly wrong as when you set it to 1.0 it seems to take longer than a second to reach the target frequency.
Please note, my wavetable code is extremely rudimentary. If you want to go into the science behind doing this properly, make sure to check out Nigel Redmon’s
excellent wavetable series at Ear Level Engineering. This involves creating multiple wavetables to cover different frequency ranges and using linear interpolation (I just truncate the phase to the nearest array entry).
Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.