{"id":110,"date":"2019-10-01T16:20:34","date_gmt":"2019-10-01T16:20:34","guid":{"rendered":"https:\/\/synthnotes.ucsd.edu\/wp7\/?p=110"},"modified":"2019-10-01T23:31:50","modified_gmt":"2019-10-01T23:31:50","slug":"table-lookup-oscillator","status":"publish","type":"post","link":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/2019\/10\/01\/table-lookup-oscillator\/","title":{"rendered":"Table Lookup Oscillator"},"content":{"rendered":"<h1>Table Lookup Oscillators<\/h1>\n<p>Often it is much more efficient to create a waveform using a lookup table as opposed to calculating the output directly. This is most often the case with the most acoustically simple waveform, the sine wave. One can calculate a sine wave from a phasor by multiplying the phasor by 2\u03c0, the number of radians in a circle, such that the phasor now extends from 0 to 2\u03c0. That value is then used in a sine operation such that the final equation looks like this:<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\">f(x) = sin(\\phi2\\pi)<\/span>\n<p>or:<\/p>\n<pre>sin(phasor(f)*2.0*PI);<\/pre>\n<p>where `PI` is the value of \u03c0 and `f` is the frequency in Hz of the waveform. This, however, means that the sine of the phasor is calculated for every sample. On the other hand, if we populate a table with a single cycle of a precomputed sine wave, all that needs to be done is to index into the table at the rate of the frequency of the sine wave desired.<\/p>\n<pre>static double 2PI = 3.14159 * 2.0; \/\/ two pi\nint tablesize = 1024; \/\/ size of the table\ndouble *sinetable = malloc(tablesize); \/\/ allocate a table\n\n\/\/ fill the table\nfor(int i = 0; i &lt; tablesize; i++)\n    sinetable[i] = sin((2PI*i)\/tablesize);<\/pre>\n<p>Using a tablesize of 1024, the table looks like this:<\/p>\n<p><a href=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-163\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table.png\" alt=\"\" width=\"1312\" height=\"387\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table.png 1312w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table-300x88.png 300w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table-768x227.png 768w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table-1024x302.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_table-624x184.png 624w\" sizes=\"auto, (max-width: 1312px) 100vw, 1312px\" \/><\/a><\/p>\n<p>To index into this table, we need to use integers. If we take a phasor at some desired frequency, we can take the output and multiply it by the <em>size of the table minus one<\/em>\u00a0(since in most languages we start counting from 0) and cut off the fractional part to obtain an index:<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\">i = \\lfloor \\phi * s \\rfloor<\/span>\n<p>where <em>s<\/em> is the size of the table and <em>phi<\/em> is the value of the phasor from 0 to 1. In code:<\/p>\n<pre>index = int(phasor(f)*tablesize);<\/pre>\n<p>This method of simply removing the fractional part of the phase is called <em>phase truncation<\/em>. We can then use this output to index into the table and get the correct value for the sine wave. Below are the first 512 samples of a 100Hz phasor indexing into a wavetable of size 1024 at an 8kHz samplerate:<\/p>\n<p><a href=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-165\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp.png\" alt=\"\" width=\"1312\" height=\"387\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp.png 1312w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp-300x88.png 300w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp-768x227.png 768w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp-1024x302.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/sine_100hz512samp-624x184.png 624w\" sizes=\"auto, (max-width: 1312px) 100vw, 1312px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table Lookup Oscillators Often it is much more efficient to create a waveform using a lookup table as opposed to calculating the output directly. This is most often the case with the most acoustically simple waveform, the sine wave. One can calculate a sine wave from a phasor by multiplying the phasor by 2\u03c0, the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-110","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/comments?post=110"}],"version-history":[{"count":4,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/110\/revisions"}],"predecessor-version":[{"id":478,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/110\/revisions\/478"}],"wp:attachment":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/media?parent=110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/categories?post=110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/tags?post=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}