{"id":119,"date":"2019-10-01T17:35:22","date_gmt":"2019-10-01T17:35:22","guid":{"rendered":"https:\/\/synthnotes.ucsd.edu\/wp7\/?p=119"},"modified":"2020-10-14T17:22:33","modified_gmt":"2020-10-14T17:22:33","slug":"harmonic-oscillators-through-additive-synthesis","status":"publish","type":"post","link":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/2019\/10\/01\/harmonic-oscillators-through-additive-synthesis\/","title":{"rendered":"Harmonic Oscillators through Additive Synthesis"},"content":{"rendered":"<h1>Sinewave Addition in Tables<\/h1>\n<p>One can also add sine waves together (additive synthesis) to approximate the basic forms presented earlier in this section. Individual sine waves of appropriate frequencies and amplitudes (with matching phases) can be used or one can use a lookup method and fill the table with the sum of the waves. The latter method is shown here.<\/p>\n<h2>Sawtooth and Ramp<\/h2>\n<p>The sawtooth has perhaps the most simple formula: given a harmonic series of sine waves, multiply each by the reciprocal of their harmonic number and sum. For instance, the first harmonic is multiplied by 1\/1, the second harmonic, is multiplied by 1\/2, the third harmonic is multiplied by 1\/3, and so on. In other words:<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\">\u00a0x_{saw}(t) = \\sum_{i=1}^{k} \\frac{1}{k} sin(2\\pi fkt) <\/span>\n<p>where <em>k<\/em>\u00a0is the number of harmonics and <em>sin(2\u03c0fkt)<\/em>\u00a0is a sine wave.<\/p>\n<pre>float table[1024];\nint harmonics = 10; \/\/ 10 harmonics\nfloat amp = 1.0; \/\/ amplitude\nfloat max = 0; \/\/ for normalization\n\n\/\/ clear the table\nfor(i=0; i &lt; tableSize; i++) '\n   table[i] = 0.0;\n\n\/\/ fill the table\nfor(k=1; k &lt;= harmonics; k++) \n{\n    \/\/ for each harmonic, go through and add it to the table\n    for(i=0; i &lt; tableSize; i++) \n    {\n        float samp;\n        samp = (i*k)\/tableSize; \/\/ get the increment\n        samp = samp * 2PI; \/\/ scale the frequency\n        table[i] = table[i] + (sin(samp) * 1\/harmonic); \/\/ add it\n        if (table[i] &gt; max)\n            max = table[i]; \/\/ remember it if it's the largest value we've encountere\n    }\n}\n\n\/\/ normalize\nfor(i=0; i &lt; tableSize; i++)\n   table[i] = table[i]\/max; \/\/ scale<\/pre>\n<p>The following is an animation of the process. <em>N<\/em>\u00a0is the number of harmonics used to construct the wave. Notice that as <em>N<\/em>\u00a0increases, the result is increasingly sharp and similar to an algebraically constructed sawtooth.<\/p>\n<p><a href=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Synthesis_sawtooth.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-173\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Synthesis_sawtooth.gif\" alt=\"\" width=\"500\" height=\"250\" \/><\/a><\/p>\n<h4>Ramp<\/h4>\n<p>The ramp is created by simply inverting the phase of the sine wave used in the sawtooth:<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\">\u00a0x_{ramp}(t) = \\sum_{i=1}^{k} \\frac{-1}{k} sin(2\\pi fkt) <\/span>\n<h2>Square<\/h2>\n<p>The square wave is created in much the same way as the sawtooth but using only the odd-numbered harmonics:<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\"> x_{square}(t) = \\sum_{i=1}^{2k+1} \\frac{1}{k} sin(2\\pi fkt)<\/span>\n<pre>float table[1024];\nint harmonics = 10; \/\/ 10 harmonics\nfloat amp = 1.0; \/\/ amplitude\nfloat max = 0; \/\/ for normalization\n\nfor(i=0; i&lt;tableSize; i++)\n    table[i] = 0.0;\n\/\/ fill the table\nfor(k=1; k &lt;= harmonics; k++) \n{\n   \/\/ if the harmonic is odd, go through and add it to the table\n   if (k &amp; 1 == 1) \n   {\n      for(i=0; i &lt; tableSize; i++) \n      {\n          float samp;\n          samp = (i*k)\/tableSize; \/\/ get the increment\n          samp = samp * 2PI; \/\/ scale the frequency\n          table[i] = table[i] + (sin(samp) * 1\/harmonic); \/\/ add it\n          if (table[i] &gt; max)\n              max = table[i]; \/\/ remember it if it's the largest value we've encountered\n      }\n   }\n}\n\n\/\/ normalize\nfor(i=0; i &lt; tableSize; i++)\n    table[i] = table[i]\/max; \/\/ scale\n<\/pre>\n<p>Notice that in the same way as the sawtooth, when we increase the number of harmonics of the square wave we more closely resemble an algebraically constructed one.<\/p>\n<p><a href=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Fourier_series_for_square_wave.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-175\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Fourier_series_for_square_wave.gif\" alt=\"\" width=\"480\" height=\"360\" \/><\/a><\/p>\n<h2>Triangle<\/h2>\n<p>The triangle wave, like the square wave, uses only odd harmonics but the phase of every other harmonic is inverted (multiplied by -1 or phase change by \u03c0). The amplitude of the harmonics, however, is the reciprocal of the square of their mode number. This means that the first harmonic is multiplied by 1\/1&lt;sup&gt;2&lt;\/sup&gt;, the third harmonic is multiplied by 1\/3&lt;sup&gt;2&lt;\/sup&gt;, the fifth by 1\/5&lt;sup&gt;2&lt;\/sup&gt;, etc.<\/p>\n<span class=\"wp-katex-eq\" data-display=\"false\"> x_{triangle}(t) = \\sum_{i=1}^{k} (-1)^{i} n^{-2} (\\text{sin}[nt]) <\/span>\n<pre>float table[1024];\nint harmonics = 10; \/\/ 10 harmonics\nfloat amp = 1.0; \/\/ amplitude\nfloat max = 0; \/\/ for normalization\nboolean invertPhase = false; \/\/ boolean to invert the phase\n\nfor(i=0; i&lt;tableSize; i++)\n    table[i] = 0.0;\n\n\/\/fill the table \nfor(k=1; k &lt;= harmonics; k++) \n{ \n    \/\/ if the harmonic is odd, go through and add it to the table \n    if (k &amp; 1 == 1) \n    { \n        for(i=0; i &lt; tableSize; i++) \n        { \n            float samp; \n            samp = (i*k)\/tableSize; \/\/ get the increment \n            samp = samp * 2PI; \n            \/\/ scale the frequency \n            table[i] = table[i] + (sin(samp) * 1\/(harmonic**2)); \n            \/\/ add it \n            if (invertPhase) \n            { \n                table[i] = -1 * table[i]; \/\/ invert the phase \n                invertPhase = false; \/\/ don't invert next time \n            } \n            else \n                invertPhase = true; \/\/ invert the next time \n            if (table[i] &gt; max)\n                max = table[i]; \/\/ remember it if it's the largest value we've encountered for normalization \n         }\n     } \n}\n\n\/\/ normalize \nfor(i=0; i &lt; tableSize; i++)\n    table[i] = table[i]\/max; \/\/ scale<\/pre>\n<p>Notice that in the same way as the sawtooth, when we increase the number of harmonics of the triangle wave we more closely resemble an algebraically constructed one.<\/p>\n<p><a href=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Synthesis_triangle.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-176\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/10\/Synthesis_triangle.gif\" alt=\"\" width=\"500\" height=\"250\" \/><\/a><\/p>\n<h1>Addition using individual Sinewaves<\/h1>\n<p>In the same way we can populate a table to create a waveform, one can also generate and add the same sine tones individually and sum them in the output. The technique is to essentially calculate the relative amplitudes using the same formulas as before, put them in a table, and read from them during playback.<\/p>\n<pre>float frequency = 440; \/\/ fundamental in Hz\nint harms = 10; \/\/ number of harmonics<br \/>float phase;\nfloat harmonicAmp[harms+1]; \/\/ a table to keep the amplitudes in\n\n\/\/ define a function to calculate the amplitudes\ndouble sawtoothAmp(int harm) \n{<br \/>    return(1.0\/(double)harm);\n}\n\n\/\/ populate the table of amplitudes\nfor(i=1; i &lt;= harms; i++) {\n  harmonicAmp[i] = sawtoothAmp(i);\n}\n\n\/\/ calculate a block<br \/>for(sample = 0; sample &lt; samples; sample++)<br \/>{<br \/>    \/\/ the phase increment is linearly<br \/>    \/\/ related to sample rate<br \/>    phase += (frequency * 6.28318531)\/samplerate; <br \/>    sawtooth = 0.0;\n    for(harm = 1; harm &lt;= harms; harm++)<br \/>        sawtooth += sin(phase * harm) * harmonicAmp[harm];<br \/>    output[sample] = sawtooth;\n}<\/pre>\n<p>Using this technique, one could also address the amplitude of each harmonic individually <em>after<\/em>\u00a0the waveform has been created. This could allow one to blend waveforms in time.<\/p>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sinewave Addition in Tables One can also add sine waves together (additive synthesis) to approximate the basic forms presented earlier in this section. Individual sine waves of appropriate frequencies and amplitudes (with matching phases) can be used or one can use a lookup method and fill the table with the sum of the waves. 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-119","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\/119","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=119"}],"version-history":[{"count":5,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"predecessor-version":[{"id":602,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/119\/revisions\/602"}],"wp:attachment":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}