{"id":515,"date":"2019-11-24T22:30:48","date_gmt":"2019-11-24T22:30:48","guid":{"rendered":"https:\/\/synthnotes.ucsd.edu\/wp7\/?p=515"},"modified":"2019-11-24T22:37:39","modified_gmt":"2019-11-24T22:37:39","slug":"single-sideband-am","status":"publish","type":"post","link":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/2019\/11\/24\/single-sideband-am\/","title":{"rendered":"Single Sideband AM"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Single sideband amplitude modulation shifts the frequency either upward or downward, but not both directions (as in AM). This technique is based on the trigonometric identity we used earlier. Shifting a cosine up simply takes half of a complex multiplication.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span class=\"wp-katex-eq\" data-display=\"false\">cos(\\alpha+\\beta)=cos(\\alpha)cos(\\beta)\u2212sin(\\alpha)sin(\\beta)<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Alpha<\/em> and <em>beta<\/em> represent the frequencies of the signal sources. Each of these frequencies requires a cosine and sine oscillator pair. By subtracting the sin() product from the cos() product, a frequency shifted (<em>alpha+beta) <\/em>oscillator is synthesized. If the products are summed, a downward (<em>alpha-beta<\/em>) oscillator is synthesized. As cosine and sine are separated by 90 degrees, it is simple enough to create a cosine\/sine pair from a sinusoidal oscillator &#8211; simply add 90 degrees to the phase of the oscillator to create the second of the pair.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, single sideband AM is more often used to frequency shift sampled signals. To do this, it is useful to consider the sample as a sum of multiple sinusoidal oscillators. To perform SSB AM, the original sample as well as a 90 degree phase shifted sample is needed. Phase shifting all of the sinusoidal components of a sample 90 degrees can be done with a type of allpass filter called a Hilbert transformer. If well designed, a Hilbert transformer will shift most frequencies 90 degrees, and will maintain this phase shift until close to  0Hz and the Nyquist frequency. Many implementations have two outputs which are 90 degrees apart, but not in phase with the original sample.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"259\" src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2-1024x259.jpg\" alt=\"\" class=\"wp-image-522\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2-1024x259.jpg 1024w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2-300x76.jpg 300w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2-768x194.jpg 768w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2-624x158.jpg 624w, https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb2.jpg 1830w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Frequency shifting with a hilbert transformer.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Calculating coefficients for a Hilbert transformer is beyond the scope of this class, but one could read articles by <a href=\"https:\/\/www.researchgate.net\/publication\/2600006_A_Hilbert-Transformer_Frequency_Shifter_for_Audio\">Scott Wardle<\/a> or<a href=\"https:\/\/www.cct.lsu.edu\/~eberdahl\/Papers\/Harris_Berdahl_Abel_IIRHilbertDesignTechnique.pdf\"> Dan Harris, Edgar Berdahl and Jonathan Abel<\/a> for more information in this area.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Implementation<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There are several open source Hilbert transformers in popular audio software. One is in Miller Puckette&#8217;s Pure Data, and is implemented as 2 pairs of biquad filters (a biquad filter was used in the earlier second order allpass filter example). It is based on a 4X synthesizer patch by Emmanuel Favreau. The other is in the Csound source code, designed by Sean Costello and based on data from Bernie Hutchins.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difference equations for the Favreau Hilbert transformer are:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span class=\"wp-katex-eq\" data-display=\"false\">\\scriptsize x1[n]=x3[n]=in\\\\x2[n]=y1[n]=0.94657x1[n]-1.94632x1[n-1]+x1[n-2]+1.94632y1[n-1]-0.94657y1[n-2]\\\\ outsin = y2[n] = 0.06338x2[n]-0.83774x2[n-1]+x2[n-2]+0.83774y2[n-1]-0.06338y2[n-2]\\\\x4[n]=y3[n]=-0.260502x3[n]+0.02569x3[n-1]+x3[n-2]-0.02569y3[n-1]+0.260502y3[n-2]\\\\ outcos = y4[n] = 0.870686x4[n]-1.8685x4[n-1]+x4[n-2]+01.8685y4[n-1]-0.870686y4[n-2]<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that this specifies two pairs of allpass filters in which each pair is in series. The C code follows directly from these equations.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ the samplerate in Hz\nfloat sampleRate = 44100;\n\/\/ initial phase\nfloat phase = 0.0;\nlong tableSize = 8192;\nlong tableMask = 8191;\nfloat sineTab[8192];\nfloat x1[3], x2[3], x3[3], x4[3];\nfloat y1[3], y2[3], y3[3], y4[3];\n\nvoid InitTables(void)\n{\n  \/\/ create sineTab from sin()\n  for(i = 0; i &lt; tableSize; i++)\n  {\n    sineTab[i] = sin((6.283185307179586 * i)\/tableSize);\n   }\n}\n\n\n\/\/ 4 biquad filters\nvoid Hilbert(float input, float *sinout, float *cosout)\n{\n  x1[0] = x3[0] = input;\n  x2[0] = y1[0] = 0.94657*x1[0] \u2212 1.94632*x1[1] + x1[2]\n    + 1.94632*y1[1] \u2212 0.94657*y1[2];\n  y1[2] = y1[1];\n  y1[1] = y1[0];\n  x1[2] = x1[1];\n  x1[1] = x1[0];\n  *sinout = y2[0] = 0.06338*x2[0] \u2212 0.83774x2[1] + x2[2] \n    + 0.83774*y2[1] \u2212 0.06338*y2[2];\n  y2[2] = y2[1];\n  y2[1] = y2[0];\n  x2[2] = x2[1];\n  x2[1] = x2[0];\n\n  x4[0] = y3[0] = -0.260502*x3[0] + 0.02569*x3[1] + x3[2] \n    - 0.02569*y3[1] + 0.260502*y3[2];\n  y3[2] = y3[1];\n  y3[1] = y3[0];\n  x3[2] = x3[1];\n  x3[1] = x3[0];\n  *cosout = y4[0] = 0.870686*x4[0] \u2212 1.8685*x4[1] + x4[2] \n    + 1.8685*y4[1] \u2212 0.870686y4[2];\n  y4[2] = y4[1];\n  y4[1] = y4[0];\n  x4[2] = x4[1];\n  x4[1] = x4[0];\n}\nvoid FreqShift(float *input, float *output, float frequency, float ratio, float ringGain, float sineGain, float squareGain, long samples)\n{\n    long sample;\n    float phaseInc;\n    float sinOsc, cosOsc, sinSamp, cosSamp;\n    \/\/ calculate for each sample in a block\n    for(sample = 0; sample &lt; samples; sample++)\n    {\n        \/\/ get the phase increment for this sample\n        phaseInc = frequency\/sampleRate;\n\n        \/\/ calculate the waveforms\n        sinOsc = sineTab[(long)(phase * tableSize)];\n        cosOsc = sineTab[((long)(phase+0.25 * tableSize))%tableMask];\n        Hilbert(*output+sample, &amp;sinSamp, &amp;cosSamp);\n\n        *(output+sample) = sinSamp * sinOsc - cosSamp * cosOsc; \n\n        \/\/ increment the phases\n        phase = phase + phaseInc;\n        if(phase >= 1.0)\n            phase = phase - 1.0;\n  }\n}<\/pre>\n\n\n\n<figure class=\"wp-block-audio\"><audio controls src=\"https:\/\/synthnotes.ucsd.edu\/wp7\/wp-content\/uploads\/2019\/11\/ssb.wav\"><\/audio><figcaption>&#8220;Walk This Way&#8221; break shifted from 1000Hz up to 200Hz down<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Single sideband amplitude modulation shifts the frequency either upward or downward, but not both directions (as in AM). This technique is based on the trigonometric identity we used earlier. Shifting a cosine up simply takes half of a complex multiplication. Alpha and beta represent the frequencies of the signal sources. Each of these frequencies requires [&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-515","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\/515","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=515"}],"version-history":[{"count":26,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/515\/revisions"}],"predecessor-version":[{"id":544,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/posts\/515\/revisions\/544"}],"wp:attachment":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/media?parent=515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/categories?post=515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp7\/index.php\/wp-json\/wp\/v2\/tags?post=515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}