{"id":100,"date":"2012-05-04T17:51:10","date_gmt":"2012-05-05T01:51:10","guid":{"rendered":"http:\/\/www.earlevel.com\/main\/?p=100"},"modified":"2019-11-18T23:46:16","modified_gmt":"2019-11-19T07:46:16","slug":"a-wavetable-oscillator-part-1","status":"publish","type":"post","link":"https:\/\/www.earlevel.com\/main\/2012\/05\/04\/a-wavetable-oscillator-part-1\/","title":{"rendered":"A wavetable oscillator\u2014Part 1"},"content":{"rendered":"<p>There are many ways to make an oscillator. Without looking for further motivation, I&#8217;ll propose a wavetable oscillator. Wavetables are a fairly obvious extension of the general playback of digital audio. Such oscillators are easy to understand, and their extreme flexible make them a very popular choice among synthesizer oscillators.<\/p>\n<h3>Making a tone from a wavetable<\/h3>\n<p>If we start with one cycle of a waveform, we can output the samples one after another, at the sample rate, and repeat the process after getting to the end of the table. Here&#8217;s a sine wave, the most &#8220;fundamental&#8221; (if boring) of all waveforms, at about 440 Hz (&#8220;concert A&#8221;); I say &#8220;about&#8221; because a single cycle at 44.1 k Hz would be 100.227 (44100 \/ 440) samples, so we round to a whole number to give us 100 samples (441 Hz):<\/p>\n<p>Sine wave, 441 Hz<br \/>\n<!--[if lt IE 9]><script>document.createElement('audio');<\/script><![endif]-->\n<audio class=\"wp-audio-shortcode\" id=\"audio-100-1\" preload=\"none\" style=\"width: 100%;\" controls=\"controls\"><source type=\"audio\/mpeg\" src=\"\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-cycle.mp3?_=1\" \/><a href=\"\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-cycle.mp3\">\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-cycle.mp3<\/a><\/audio><\/p>\n<p>OK, that gives us one tone at excellent quality. We could have a separate wavetable for each note that we want to play, but that wouldn&#8217;t let us vary the pitch by arbitrary amounts, such as for vibrato or frequency sweeps. Also, we&#8217;d continue to run into the problem of our table needing to be an integer length\u2014a problem that becomes extreme at high frequencies (due to shorter tables).<\/p>\n<h3>Arbitrary pitch from a wavetable<\/h3>\n<p>A first guess at a solution might be to mimic changing the playback rate on a tape recorder by varying the sample rate. This works quite well, and has the advantage that any errors in the waveform (due to a short wavetable or short sample size) remain harmonically related, so they&#8217;re heard as harmonic distortion instead of noise (hiss), and aliasing is not a threat because we&#8217;re raising the sample rate to play higher notes. This technique was used in some early digital synthesizers (such as the Fairlight CMI), but has a glaring weakness: we can&#8217;t multiplex this type of oscillator\u2014each independent voice requires its own variably-clocked DAC.<\/p>\n<p>However, we can do the equivalent shifting with DSP by using sample rate conversion techniques (sometimes called resampling). Because we can resample a wavetable at multiple rates with DSP, we can generate multiple tones digitally, before sending them to a common DAC.<\/p>\n<p>Basically, we simulate the different clocking rates by using a fixed clock and scanning through the wavetable at a different rate. (We&#8217;ll use the CD sample rate of 44.1 kHz for our tests\u2014higher rates are easier, since they give more audio headroom before aliasing, making 44.1 kHz a good test as we develop the algorithm.) So, instead of outputting the first sample, then the second\u2014stepping through the table with an increment of 1\u2014we can step through with a smaller increment for lower pitches and a larger increment for higher pitches.<\/p>\n<p>But we need to decide which sample to use for a fractional offset. The simplest choice is to truncate the fractional index by taking only the integer portion. This has been done in popular instruments of the past, especially early samplers. I&#8217;ll cut straight to a recommendation and suggest that we use linear interpolation\u2014it&#8217;s not much more computationally expensive, and gives us enough improvement in sound quality to be worth the effort. We&#8217;ll discuss linear interpolation more later.<\/p>\n<p>Here&#8217;s our sine wave at a different pitch, using a fractional increment and linear interpolation\u2014middle C (261.626 Hz):<\/p>\n<p>Sine wave, 261.626 Hz<br \/>\n<audio class=\"wp-audio-shortcode\" id=\"audio-100-2\" preload=\"none\" style=\"width: 100%;\" controls=\"controls\"><source type=\"audio\/mpeg\" src=\"\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-table-middle-C.mp3?_=2\" \/><a href=\"\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-table-middle-C.mp3\">\/main\/wp-content\/uploads\/2012\/05\/sine-100-sample-table-middle-C.mp3<\/a><\/audio><\/p>\n<p>That sounds promising\u2014and note that fractional increments let us get our target pitch exactly this time. To prove it works at any pitch we&#8217;re interested in, here&#8217;s the same technique used with an exponential sweep, changing the wavetable index increment at each cycle to cover a wide range:<\/p>\n<p>Sine sweep, 20-20,000 Hz<br \/>\n<audio class=\"wp-audio-shortcode\" id=\"audio-100-3\" preload=\"none\" style=\"width: 100%;\" controls=\"controls\"><source type=\"audio\/mpeg\" src=\"\/main\/wp-content\/uploads\/2012\/05\/sine-sweep-100-sample-table-20-20k.mp3?_=3\" \/><a href=\"\/main\/wp-content\/uploads\/2012\/05\/sine-sweep-100-sample-table-20-20k.mp3\">\/main\/wp-content\/uploads\/2012\/05\/sine-sweep-100-sample-table-20-20k.mp3<\/a><\/audio><\/p>\n<p>That sounds like we may have solved the problem of creating any pitch we want from a wavetable! But let&#8217;s test further&#8230;<\/p>\n<h3>A classic synthesizer waveform<\/h3>\n<p>Sine waves are boring. A staple for classic synthesizers is the sawtooth wave\u2014a harmonically rich waveform that&#8217;s excellent for subtractive synthesis. A single cycle of a sawtooth climbs in value from the lowest value to highest, then resetting instantly to the lowest. We can&#8217;t generate a perfect sawtooth in a wavetable (we can&#8217;t reset instantly, for instance\u2014we must wait till the next sample output), so the proper thing to do is to build a band-limited sawtooth from sine wave harmonics. A band-limited sawtooth wave is made up of a sine wave for the first harmonic, a sine at twice the frequency but half the amplitude for the second harmonic, a sine three times the frequency but a third of the amplitude, etc. Because our wavetable is 100 samples, we can fit a sawtooth of 49 harmonics.<\/p>\n<p>Here&#8217;s what a sawtooth of 441 Hz sounds like:<\/p>\n<p>Sawtooth wave, 441 Hz<br \/>\n<audio class=\"wp-audio-shortcode\" id=\"audio-100-4\" preload=\"none\" style=\"width: 100%;\" controls=\"controls\"><source type=\"audio\/mpeg\" src=\"\/main\/wp-content\/uploads\/2012\/05\/saw-100-sample-cycle.mp3?_=4\" \/><a href=\"\/main\/wp-content\/uploads\/2012\/05\/saw-100-sample-cycle.mp3\">\/main\/wp-content\/uploads\/2012\/05\/saw-100-sample-cycle.mp3<\/a><\/audio><\/p>\n<p>And here we sweep the range as before:<\/p>\n<p>Sawtooth sweep, 20-20,000 Hz<br \/>\n<audio class=\"wp-audio-shortcode\" id=\"audio-100-5\" preload=\"none\" style=\"width: 100%;\" controls=\"controls\"><source type=\"audio\/mpeg\" src=\"\/main\/wp-content\/uploads\/2012\/05\/saw-sweep-100-sample-table-20-20k.mp3?_=5\" \/><a href=\"\/main\/wp-content\/uploads\/2012\/05\/saw-sweep-100-sample-table-20-20k.mp3\">\/main\/wp-content\/uploads\/2012\/05\/saw-sweep-100-sample-table-20-20k.mp3<\/a><\/audio><\/p>\n<p>Yikes! At the higher pitches, the tone is too harmonic-rich, causing strong aliasing. Also, notice that at the lower pitches the sawtooth starts out sounding a bit dull, lacking the highest harmonics.<\/p>\n<p>Clearly, we do not have a suitable wavetable oscillator yet. We need the ability to scale the harmonic content to the pitch required\u2014starting with a wavetable tailored to the lowest pitch we want to produce, and reducing harmonic content as we move up in pitch before it has a chance to fold back as aliasing at half the sample rate.<\/p>\n<p><i>Next: working on a solution in <a href=\"\/main\/2012\/05\/08\/a-wavetable-oscillator\u2014part-2\/\">Part 2<\/a><\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are many ways to make an oscillator. Without looking for further motivation, I&#8217;ll propose a wavetable oscillator. Wavetables are a fairly obvious extension of the general playback of digital audio. Such oscillators are easy to understand, and their extreme &hellip; <a href=\"https:\/\/www.earlevel.com\/main\/2012\/05\/04\/a-wavetable-oscillator-part-1\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,20,6,24],"tags":[],"_links":{"self":[{"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/posts\/100"}],"collection":[{"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/comments?post=100"}],"version-history":[{"count":5,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/posts\/100\/revisions"}],"predecessor-version":[{"id":956,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/posts\/100\/revisions\/956"}],"wp:attachment":[{"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/media?parent=100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/categories?post=100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.earlevel.com\/main\/wp-json\/wp\/v2\/tags?post=100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}