{"id":465,"date":"2018-09-30T23:59:00","date_gmt":"2018-10-01T04:59:00","guid":{"rendered":"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/?p=465"},"modified":"2018-09-30T21:50:34","modified_gmt":"2018-10-01T02:50:34","slug":"dsp-without-the-formalism","status":"publish","type":"post","link":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/2018\/09\/30\/dsp-without-the-formalism\/","title":{"rendered":"DSP: Without the Formalism"},"content":{"rendered":"<p><!-- html --><\/p>\n<h3 class=\"sectionHead\"><span class=\"titlemark\">1\u00a0<\/span>Introduction<\/h3>\n<p><!--l. 16--><\/p>\n<p class=\"noindent\" style=\"text-indent: 0em\">Today, we\u2019re going to be taking a brief look at digital signal processing (DSP) without (too much of) the<br \/>\nformalism usually associated with the topic. Of course, to get a deep understanding of how this works<br \/>\nand what sort of things you can really do with DSP you\u2019ll probably have to learn the math at a<br \/>\ndeeper level eventually. There\u2019s still plenty you can do without that however, and by the time you\u2019ve<br \/>\nread this post, you should have the tools to build an extremely basic beat detector. All the code<br \/>\nhere will be presented in Python, using the <a href=\"http:\/\/www.numpy.org\/\"><span class=\"cmtt-12\" style=\"font-family: monospace\">Numpy<\/span><\/a>, <a href=\"https:\/\/scipython.com\/\"><span class=\"cmtt-12\" style=\"font-family: monospace\">SciPy<\/span><\/a> and <a href=\"https:\/\/matplotlib.org\/\"><span class=\"cmtt-12\" style=\"font-family: monospace\">matplotlib<\/span><\/a> libraries. If you don\u2019t<br \/>\nalready have those installed and want to follow along, make sure you grab them first. On many<br \/>\nsystems this is as easy as using <span class=\"cmtt-12\" style=\"font-family: monospace\">pip install numpy matplotlib <\/span>or installing a SciPy distribution like<br \/>\n<a href=\"https:\/\/www.anaconda.com\/download\/\"><span class=\"cmtt-12\" style=\"font-family: monospace\">Anaconda<\/span><\/a>. Before we dive directly into the code though, we do need to take a short trip through the<br \/>\nmath.<br \/>\n<!--l. 52--><\/p>\n<h3 class=\"sectionHead\"><span class=\"titlemark\">2 <\/span> <a id=\"x1-20002\"><\/a>The Math<\/h3>\n<p><!--l. 53--><\/p>\n<p class=\"noindent\" style=\"text-indent: 0em\">The beautiful (and in some ways terrible) thing about signal processing, is that we really only need one<br \/>\nmathematical tool: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fourier_transform\">the Fourier transform<\/a>. Strictly speaking, we will be working with the <span class=\"cmbx-12\" style=\"font-weight: bold\">discrete Fourier<\/span><br \/>\n<span class=\"cmbx-12\" style=\"font-weight: bold\">transform <\/span>(DFT) here. This is great because we really only need to understand one thing which is so commonly<br \/>\nused that it is already available in library form for almost any platform or programming language you could<br \/>\nimagine. Unfortunately, that means there is a lot to unpack here. We will really only be taking the 30,000 foot<br \/>\nview today.<br \/>\n<!--l. 69--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">At it\u2019s heart, the Forier transform converts between what we call the <span class=\"cmbx-12\" style=\"font-weight: bold\">time domain <\/span>and something<br \/>\ncalled the <span class=\"cmbx-12\" style=\"font-weight: bold\">frequency domain<\/span>. It turns out that any \u201csignal\u201d: your voice, Rebecca Black\u2019s Friday, a<br \/>\nfinger painting, or Picasso\u2019s Mona Lisa, can be represented as a sum of sin waves. This result is not<br \/>\nat all obvious, but I promised to skip the formalism so we\u2019ll just have to take it on faith for now.<br \/>\nWe can see this at work by playing with a few examples though. The most obvious is simply a sin<br \/>\nwave:<br \/>\n<!--l. 83--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin0.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-506 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin0.png\" alt=\"\" width=\"630\" height=\"436\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin0.png 630w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin0-300x208.png 300w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><br \/>\n<!--l. 85--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">We can see that the Forier transform is telling us exactly what we expect: all the frequency content of the<br \/>\nsignal is focused at a single point. What about something like a square wave?<br \/>\n<!--l. 91--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-507 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin1.png\" alt=\"\" width=\"630\" height=\"436\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin1.png 630w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin1-300x208.png 300w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><br \/>\n<!--l. 93--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">There are a couple interesting things to note here. First, there is clearly a pattern in the DFT. This pattern<br \/>\ncan be described quite elegantly mathematically, and I encourage anyone who is so inclined to read up on that<br \/>\n(and the Fourier transform itself). Second, note that the frequency axis ranges from 0Hz to 250Hz. This is because<br \/>\nthe discrete version of the Fourier transform can only give us information about the spectral content up to half of<br \/>\nthe sampling frequency (which is 500Hz here). If you\u2019re interested in why this is the case, check out <a href=\"https:\/\/en.wikipedia.org\/wiki\/Nyquist_rate\">the wikiepdia article on the<br \/>\nNyquist rate<\/a>. The final thing to note is that I have been plotting three lines on these plots: The<br \/>\nsignal itself on top, and then two components of the DFT. Those components have been labeled<br \/>\n<span class=\"cmtt-12\" style=\"font-family: monospace\">mag(dft(f)) <\/span>and <span class=\"cmtt-12\" style=\"font-family: monospace\">angle(dft(f))<\/span>. This is because the Fourier transform actually produces two pieces of<br \/>\ninformation about the sin waves that compose a signal: the <span class=\"cmbx-12\" style=\"font-weight: bold\">magnitude <\/span>(amount) of each sin wave, and<br \/>\nthe <span class=\"cmbx-12\" style=\"font-weight: bold\">phase <\/span>(offset in time) of that wave. By leveraging both of these components, you can build<br \/>\nmuch more sophisticated DSP systems chains than the ones we will be building today. Before we<br \/>\nwrap up this section, I\u2019d like to take a brief moment to go over the code I used to generate these<br \/>\nplots.<br \/>\n<!--l. 126--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">The first thing we need to do is import all of the tools we\u2019ll need:<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb1\" class=\"fancyvrb\"><a id=\"x1-2002r1\"><\/a><span id=\"textcolor1\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor2\"><span class=\"cmtt-12\" style=\"font-family: monospace\">numpy<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor3\"><span class=\"cmtt-12\" style=\"font-family: monospace\">as<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor4\"><span class=\"cmtt-12\" style=\"font-family: monospace\">np<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-2004r2\"><\/a><span id=\"textcolor5\"><span class=\"cmtt-12\" style=\"font-family: monospace\">from<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor6\"><span class=\"cmtt-12\" style=\"font-family: monospace\">numpy<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor7\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0fft<\/span><br class=\"fancyvrb\" \/><a id=\"x1-2006r3\"><\/a><span id=\"textcolor8\"><span class=\"cmtt-12\" style=\"font-family: monospace\">from<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor9\"><span class=\"cmtt-12\" style=\"font-family: monospace\">math<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor10\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0pi<\/span><br class=\"fancyvrb\" \/><a id=\"x1-2008r4\"><\/a><span id=\"textcolor11\"><span class=\"cmtt-12\" style=\"font-family: monospace\">from<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor12\"><span class=\"cmtt-12\" style=\"font-family: monospace\">matplotlib<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor13\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0pyplot<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor14\"><span class=\"cmtt-12\" style=\"font-family: monospace\">as<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0plt<\/span><\/div>\n<p><!--l. 130--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">The <span class=\"cmtt-12\" style=\"font-family: monospace\">fft <\/span>stands for \u201cFast Fourier Transform\u201d, and is essentially the DFT we have been discussing. We also<br \/>\nneed to generate our signals:<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb2\" class=\"fancyvrb\"><a id=\"x1-2010r47\"><\/a><span id=\"textcolor15\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Generate<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a01000<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0time<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0values,<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0evenly<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0spaced<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0from<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a00<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a04<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0seconds<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-2012r48\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">t<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor16\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor17\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">linspace(<\/span><span id=\"textcolor18\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor19\"><span class=\"cmtt-12\" style=\"font-family: monospace\">4<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor20\"><span class=\"cmtt-12\" style=\"font-family: monospace\">1000<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-2014r49\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">fx<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor21\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor22\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">sin(t<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor23\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor24\"><span class=\"cmtt-12\" style=\"font-family: monospace\">2<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor25\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0pi)<\/span><\/div>\n<p><!--l. 136--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Then we need to compute the different statistics we\u2019re interested in from the Fourier transform<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb3\" class=\"fancyvrb\"><a id=\"x1-2019r1\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">hx<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor26\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0fft<\/span><span id=\"textcolor27\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">rfft(fx)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-2021r2\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">hx_mag<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor28\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor29\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">abs(hx)<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor30\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor31\"><span class=\"cmtt-12\" style=\"font-family: monospace\">len<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(fx)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-2023r3\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">hx_dir<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor32\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor33\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">angle(hx,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0deg<\/span><span id=\"textcolor34\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span id=\"textcolor35\"><span class=\"cmtt-12\" style=\"font-family: monospace\">True<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><\/div>\n<p><!--l. 145--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">A few minor details:<\/p>\n<ol class=\"enumerate1\" style=\"list-style-type: decimal\">\n<li id=\"x1-2025x1\" class=\"enumerate\">We use <span class=\"cmtt-12\" style=\"font-family: monospace\">rfft <\/span>here because our signal only contains real values. If you don\u2019t know what that means,<br \/>\nno worries. Just know that it will save us some cleaning up of the output later.<\/li>\n<li id=\"x1-2027x2\" class=\"enumerate\">We compute the magnitude of the outputs using <span class=\"cmtt-12\" style=\"font-family: monospace\">np.abs<\/span>. This has to do with the fact that the output<br \/>\nof the Fourier transform is actually a bunch of complex numbers. We also divide by the length of the<br \/>\ninput signal for normalization purposes. Again, the details don\u2019t really matter too much here.<\/li>\n<li id=\"x1-2029x3\" class=\"enumerate\">Numpy has a convenient function for computing angles from complex numbers, so we just use that.<br \/>\nThe <span class=\"cmtt-12\" style=\"font-family: monospace\">deg=True <\/span>keyword argument simply tells NumPy to output the angles in degrees, for more<br \/>\nintuitive plotting.<\/li>\n<\/ol>\n<p><!--l. 162--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Now that we have something of a foundation, let\u2019s take a look at how we might go about using this tool to<br \/>\nanalyze some music<\/p>\n<p><!--l. 165--><\/p>\n<h3 class=\"sectionHead\"><span class=\"titlemark\">3 <\/span> <a id=\"x1-30003\"><\/a>Musical Analysis<\/h3>\n<p><!--l. 166--><\/p>\n<p class=\"noindent\" style=\"text-indent: 0em\">To start with, we load some music into our program. I\u2019ll be working with <a href=\"https:\/\/www.youtube.com\/watch?v=Hwl8d5Fp-Jk\">Rogers &amp; Dean &#8211; No Doubt (Rival x<br \/>\nCadmium Remix)<\/a> which is an electronic piece, released for non-commercial use by NoCopyrightSounds. I have<br \/>\nchosen this piece because it has a number of distinctive features in the soundscape, and a strong baseline which<br \/>\nshould help our beat detector. First, we should load up all the data we\u2019re going to need, and clean it up a<br \/>\nlittle<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb4\" class=\"fancyvrb\"><a id=\"x1-3002r1\"><\/a><span id=\"textcolor36\"><span class=\"cmtt-12\" style=\"font-family: monospace\">from<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor37\"><span class=\"cmtt-12\" style=\"font-family: monospace\">scipy.io<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor38\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0wavfile<\/span><br class=\"fancyvrb\" \/><a id=\"x1-3004r2\"><\/a><span id=\"textcolor39\"><span class=\"cmtt-12\" style=\"font-family: monospace\">import<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor40\"><span class=\"cmtt-12\" style=\"font-family: monospace\">numpy<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor41\"><span class=\"cmtt-12\" style=\"font-family: monospace\">as<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor42\"><span class=\"cmtt-12\" style=\"font-family: monospace\">np<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3006r3\"><\/a><br class=\"fancyvrb\" \/><a id=\"x1-3008r4\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">fs,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0signal<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor43\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0wavfile<\/span><span id=\"textcolor44\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">read(<\/span><span id=\"textcolor45\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8216;song.wav&#8217;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-3010r5\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">WINDOW_SIZE<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor46\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0fs<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor47\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor48\"><span class=\"cmtt-12\" style=\"font-family: monospace\">8<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3012r6\"><\/a><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3014r7\"><\/a><span id=\"textcolor49\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0colapse<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0all<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0the<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0channels<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3016r8\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">signal<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor50\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor51\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">mean(signal,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor52\"><span class=\"cmtt-12\" style=\"font-family: monospace\">1<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-3018r9\"><\/a><span id=\"textcolor53\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Normalize<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0[-1,<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a01]<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3020r10\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">signal<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor54\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0signal<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor55\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(np<\/span><span id=\"textcolor56\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">max(np<\/span><span id=\"textcolor57\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">abs(signal)))<\/span><\/div>\n<p><!--l. 179--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">The most obvious thing to do right now is to simply take the DFT of the whole piece.<br \/>\n<!--l. 182--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-508 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin2.png\" alt=\"\" width=\"647\" height=\"436\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin2.png 647w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin2-300x202.png 300w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/><\/a><br \/>\n<!--l. 184--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Unfortunately, that doesn\u2019t provide us with terribly useful information. We can see that the phase content<br \/>\nis all over the place, and the magnitude data is not terribly interesting: it mostly just looks like a<br \/>\ndecaying exponential function. Instead of taking the DFT of the whole song, it\u2019s much more common<br \/>\nto take the DFT of small sections of it at a time. Sometimes it\u2019s useful for the chunks to overlap, but we won\u2019t be doing that here just for<br \/>\nconciseness. We will divide the song up into 1\/8th &#8211; second<br \/>\nchunks using the following code:<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb5\" class=\"fancyvrb\"><a id=\"x1-3022r12\"><\/a><span id=\"textcolor58\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Make<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0sure<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0that<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0our<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0signal<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0is<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0of<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0appropriate<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0length<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0split<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0into<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0windows<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3024r13\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">signal<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor59\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor60\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">pad(signal,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0((<\/span><span id=\"textcolor61\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0WINDOW_SIZE<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor62\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(<\/span><span id=\"textcolor63\"><span class=\"cmtt-12\" style=\"font-family: monospace\">len<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(signal)<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor64\"><span class=\"cmtt-12\" style=\"font-family: monospace\">%<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0WINDOW_SIZE))),<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor65\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8216;constant&#8217;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-3026r14\"><\/a><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3028r15\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">windows<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor66\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor67\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">array(np<\/span><span id=\"textcolor68\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">split(signal,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor69\"><span class=\"cmtt-12\" style=\"font-family: monospace\">len<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(signal)<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor70\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0WINDOW_SIZE))<\/span><span id=\"textcolor71\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">transpose()<\/span><\/div>\n<p><!--l. 196--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">We can then take the DFT of each chunk:<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb6\" class=\"fancyvrb\"><a id=\"x1-3030r14\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">spectral_content<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor72\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0fft<\/span><span id=\"textcolor73\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">rfft(windows,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0axis<\/span><span id=\"textcolor74\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span id=\"textcolor75\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><\/div>\n<p><!--l. 200--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">and then plot all of these as a big image:<br \/>\n<!--l. 202--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/norm.freqs_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-504 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/norm.freqs_.png\" alt=\"\" width=\"688\" height=\"665\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/norm.freqs_.png 688w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/norm.freqs_-300x290.png 300w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><br \/>\n<!--l. 204--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Here we can see the hints of some interesting things going on along the bottom of the image. However, it<br \/>\ninitially appears as though most of the image is empty. To demonstrate that this is not the case, I<br \/>\nhave provided a plot with some of the horizontal and vertical lines extracted. The magnitude is<br \/>\nplotted in purple for all of charts, while the angle is in blue. The charts are arranged so that the<br \/>\nbottom-most line chart corresponds to the lowest line, and lines are parallel with the chart representing that<br \/>\nslice<br \/>\n<!--l. 217--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-510 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_.png\" alt=\"\" width=\"790\" height=\"790\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_.png 790w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_-150x150.png 150w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_-300x300.png 300w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_-768x768.png 768w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_-170x170.png 170w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.freqs_-68x68.png 68w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/a><br \/>\n<!--l. 219--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Note that as we go up through the frequency spectrum, the magnitudes decrease exponentially. This makes<br \/>\nsense given our source of data \u2013 music. While the precise sensitivity of the human ear to different frequencies is<br \/>\nnot precisely known (and may in fact depend on the overall spectral content of the signal, creating a highly<br \/>\ncomplex and nonlinear dynamic) we are fairly sure that it is at least roughly sensitive to the logarithm of the<br \/>\nincoming energy. We would like to make our magnitude values \u201cperceptually linear\u201d. That is, we would like to<br \/>\napply some function to the magnitudes at each frequency to make an increase in magnitude at any frequency to<br \/>\nresult in the same perceived increase in loudness to the sound at that frequency. To do that, we\u2019ll apply the<br \/>\ntransformation below<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb7\" class=\"fancyvrb\"><a id=\"x1-3032r35\"><\/a><span id=\"textcolor76\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Energy<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0scales<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0linearly<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0with<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0frequency<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3034r36\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">freq_scaling<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor77\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor78\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">linspace(<\/span><span id=\"textcolor79\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0fs<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor80\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor81\"><span class=\"cmtt-12\" style=\"font-family: monospace\">2<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0normed_spectral_content<\/span><span id=\"textcolor82\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">shape[<\/span><span id=\"textcolor83\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">])<\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3036r37\"><\/a><span id=\"textcolor84\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Magic<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0make<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0numpy<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0happy<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3038r38\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">freq_scaling<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor85\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0freq_scaling<\/span><span id=\"textcolor86\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">reshape((sample_size,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor87\"><span class=\"cmtt-12\" style=\"font-family: monospace\">1<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">))<\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3040r39\"><\/a><span id=\"textcolor88\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0&#8220;Perceptually<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0linear&#8221;<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0version:<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0log<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0of<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0the<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0incoming<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0energy<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3042r40\"><\/a><span id=\"textcolor89\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0We<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0also<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0add<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0a<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0tiny<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0offset,<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0just<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0avoid<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0dealing<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0with<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0entries<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-3044r41\"><\/a><span id=\"textcolor90\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0that<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0have<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0zero<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0energy<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-3046r42\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">pl<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor91\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor92\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">log(freq_scaling<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor93\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0normed_spectral_content<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor94\"><span class=\"cmtt-12\" style=\"font-family: monospace\">+<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor95\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0.0001<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><\/div>\n<p><!--l. 239--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">This gives us the graph below:<br \/>\n<!--l. 241--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-512 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.png\" alt=\"\" width=\"789\" height=\"790\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.png 789w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_-150x150.png 150w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_-300x300.png 300w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_-768x769.png 768w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_-170x170.png 170w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_-68x68.png 68w\" sizes=\"auto, (max-width: 789px) 100vw, 789px\" \/><\/a><br \/>\n<!--l. 243--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">Note that we dropped the colors for the supplementary charts. That&#8217;s because we discarded all the phase information when converting to perceptual linearity. However, we did gain quite a bit of dynamic range in the process. unfortunately, due to the length of the waterfall plot, we can\u2019t really see<br \/>\nthe fine detail we might be interested in. I\u2019m going to zoom in on just a handful of the samples near the beginning of the piece so we can get a<br \/>\nmore detailed picture. The vertical line is still in the same place, relatively speaking:<br \/>\n<!--l. 249--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-511 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused.png\" alt=\"\" width=\"790\" height=\"790\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused.png 790w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused-150x150.png 150w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused-300x300.png 300w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused-768x768.png 768w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused-170x170.png 170w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sliced.norm_.pl_.focused-68x68.png 68w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/a><br \/>\n<!--l. 251--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">And now at last, we can see the feature we\u2019re looking for: the beats (those vertical stripes of bright yellow).<br \/>\n<!--l. 253--><\/p>\n<h3 class=\"sectionHead\"><span class=\"titlemark\">4 <\/span> <a id=\"x1-40004\"><\/a>A Really Bad Beat Detector<\/h3>\n<p><!--l. 254--><\/p>\n<p class=\"noindent\" style=\"text-indent: 0em\">To finish out this post, we\u2019re going to build a really bad beat detector. Hopefully the techniques presented here<br \/>\nwill help you develop your own, less terrible, beat detector (or other music-reactive project). The first thing to note is that we<br \/>\nare going to be heavily summarizing the data; we must collapse the data from over 3000 measurements<br \/>\nper time slice to just one bit: is there or is there not a beat start here. To start, we will summarize the amount of \u201cloudness\u201d in the \u201clow\u201d,<br \/>\n\u201cmid\u201d, and \u201chigh\u201d bands. This will give us a number of time-domain signals which, when all of<br \/>\nthem cross a given threshold, indicate beats. Putting this all together, we get the following bit of<br \/>\npython:<br \/>\n<!--l. 1--><\/p>\n<div id=\"fancyvrb8\" class=\"fancyvrb\"><a id=\"x1-4002r17\"><\/a><span id=\"textcolor96\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Summarize<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0data<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4004r18\"><\/a><span id=\"textcolor97\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Our<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0buckets<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0will<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0be<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0roughly:<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4006r19\"><\/a><span id=\"textcolor98\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a00<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0&#8211;<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0100<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Hz<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4008r20\"><\/a><span id=\"textcolor99\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0101<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0&#8211;<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a02<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Khz<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4010r21\"><\/a><span id=\"textcolor100\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a02Khz<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0&#8211;<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a020Khz<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4012r22\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">div1<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor101\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor102\"><span class=\"cmtt-12\" style=\"font-family: monospace\">int<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(sample_size<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor103\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(<\/span><span id=\"textcolor104\"><span class=\"cmtt-12\" style=\"font-family: monospace\">100<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor105\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(fs<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor106\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor107\"><span class=\"cmtt-12\" style=\"font-family: monospace\">2<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)))<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4014r23\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">div2<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor108\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor109\"><span class=\"cmtt-12\" style=\"font-family: monospace\">int<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(sample_size<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor110\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(<\/span><span id=\"textcolor111\"><span class=\"cmtt-12\" style=\"font-family: monospace\">2000<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor112\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(fs<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor113\"><span class=\"cmtt-12\" style=\"font-family: monospace\">*<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor114\"><span class=\"cmtt-12\" style=\"font-family: monospace\">2<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)))<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4016r24\"><\/a><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4018r25\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">SEG_START<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor115\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor116\"><span class=\"cmtt-12\" style=\"font-family: monospace\">100<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4020r26\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">SEG_END<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor117\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor118\"><span class=\"cmtt-12\" style=\"font-family: monospace\">300<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4022r27\"><\/a><br class=\"fancyvrb\" \/><a id=\"x1-4024r28\"><\/a><span id=\"textcolor119\"><span class=\"cmtt-12\" style=\"font-family: monospace\">def<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor120\"><span class=\"cmtt-12\" style=\"font-family: monospace\">summarize<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">(start,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0stop):<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4026r29\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor121\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Select<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0the<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0right<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0part<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0of<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0the<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0array<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4028r30\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor122\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor123\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">sum(pl[start:stop,SEG_START:SEG_END],<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0axis<\/span><span id=\"textcolor124\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span id=\"textcolor125\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4030r31\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor126\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Compute<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0a<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0moving<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0average<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0(window<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0size<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0=<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a016)<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4032r32\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor127\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0to<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0smooth<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0out<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0measurements<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4034r33\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0MA_SIZE<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor128\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor129\"><span class=\"cmtt-12\" style=\"font-family: monospace\">3<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4036r34\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor130\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor131\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">cumsum(tr)<\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4038r35\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr[MA_SIZE:]<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor132\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr[MA_SIZE:]<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor133\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr[:<\/span><span id=\"textcolor134\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">MA_SIZE]<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4040r36\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor135\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr[MA_SIZE<\/span><span id=\"textcolor136\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span id=\"textcolor137\"><span class=\"cmtt-12\" style=\"font-family: monospace\">1<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">:]<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor138\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0MA_SIZE<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4042r37\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor139\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Normalize<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0the<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0moving<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0average<\/span><\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4044r38\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0mi<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor140\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor141\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">min(tr)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4046r39\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0ma<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor142\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0np<\/span><span id=\"textcolor143\"><span class=\"cmtt-12\" style=\"font-family: monospace\">.<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">max(tr)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4048r40\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor144\"><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">#<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0Normalize<\/span><span class=\"cmitt-10x-x-120\" style=\"font-family: monospace;font-style: italic\">\u00a0TR<\/span><\/span><br class=\"fancyvrb\" \/><a id=\"x1-4050r41\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor145\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(tr<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor146\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0mi)<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor147\"><span class=\"cmtt-12\" style=\"font-family: monospace\">\/<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0(ma<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor148\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0mi)<\/span><br \/>\n<br class=\"fancyvrb\" \/><a id=\"x1-4052r42\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor149\"><span class=\"cmtt-12\" style=\"font-family: monospace\">return<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0tr<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4054r43\"><\/a><br class=\"fancyvrb\" \/><a id=\"x1-4056r44\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">sum0<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor150\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0summarize(<\/span><span id=\"textcolor151\"><span class=\"cmtt-12\" style=\"font-family: monospace\">0<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0div1)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4058r45\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">sum1<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor152\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0summarize(div1,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0div2)<\/span><br class=\"fancyvrb\" \/><a id=\"x1-4060r46\"><\/a><span class=\"cmtt-12\" style=\"font-family: monospace\">sum2<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor153\"><span class=\"cmtt-12\" style=\"font-family: monospace\">=<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0summarize(div2,<\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">\u00a0<\/span><span id=\"textcolor154\"><span class=\"cmtt-12\" style=\"font-family: monospace\">&#8211;<\/span><\/span><span id=\"textcolor155\"><span class=\"cmtt-12\" style=\"font-family: monospace\">1<\/span><\/span><span class=\"cmtt-12\" style=\"font-family: monospace\">)<\/span><\/div>\n<p><!--l. 271--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">We can see how well this works by looking at the plot below:<br \/>\n<!--l. 273--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\"><a href=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/beats.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-503 size-full\" src=\"http:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/beats.png\" alt=\"\" width=\"688\" height=\"1296\" srcset=\"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/beats.png 688w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/beats-159x300.png 159w, https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/beats-544x1024.png 544w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><br \/>\n<!--l. 275--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">So we can see that a simple threshold approach might work, assuming we set enough thresholds with enough<br \/>\nbins. However, we then run the risk of over-tuning our algorithm on this specific song. If we look<br \/>\nback at the plot of just the raw time-domain signal, we can see that the overall magnitude of the<br \/>\npiece varies significantly. That variance is at the root of the problem here: the varying volume means we need<br \/>\nto also vary the threshold for what is considered a \u201cbeat\u201d. This can be accomplished using digital<br \/>\nimplementations of things like <a href=\"https:\/\/en.wikipedia.org\/wiki\/Envelope_detector\">envelope followers<\/a>. If you want more detail about that\u00a0 approach, check out <a href=\"https:\/\/www.clear.rice.edu\/elec301\/Projects01\/beat_sync\/beatalgo.html\">this beat detector from<br \/>\nRice University<\/a>.<\/p>\n<p><!--l. 289--><\/p>\n<h3 class=\"sectionHead\"><span class=\"titlemark\">5 <\/span> <a id=\"x1-50005\"><\/a>Conclusion<\/h3>\n<p><!--l. 290--><\/p>\n<p class=\"noindent\" style=\"text-indent: 0em\">This blog post is getting really long, so I\u2019m going to wrap it up here. Hopefully you have at least<br \/>\nglimpsed the power of the Fourier transform, and have some desire to learn more about it. There are<br \/>\nthousands of different filters and algorithms out there, but at the end of the day they all come down to<br \/>\nwhat we did here: munging about with the data in the frequency domain. Some algorithms, like<br \/>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Finite_impulse_response\">FIR filters<\/a> work only in the time domain, but hidden behind that facade is a frequency-domain<br \/>\ntransformation. Doing things in the time domain directly can be more efficient, but it\u2019s usually harder<br \/>\nto figure out what\u2019s going on and is a less general approach. With the Fourier transform, we can<br \/>\ndirectly inspect the frequency content of signals. While I didn\u2019t have a chance to talk about it today,<br \/>\nthe DFT is actually invertable: you can reconstruct the original signal from its DFT. Several data<br \/>\nstorage formats, including MP3 and JPEG, actually use a close cousin of the DFT (the discrete<br \/>\ncosine transform or DCT) to compress data. If you want to learn more, <a href=\"http:\/\/www.bores.com\/courses\/intro\/basics\/index.htm\">this online course<\/a> is a good<br \/>\nresource.<br \/>\n<!--l. 321--><\/p>\n<p class=\"indent\" style=\"text-indent: 1.5em\">All the code for this article is available <a href=\"https:\/\/github.com\/ccsf18-flow\/dsp-blog\">here, on github<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1\u00a0Introduction Today, we\u2019re going to be taking a brief look at digital signal processing (DSP) without (too much of) the formalism usually associated with the topic. Of course, to get a deep understanding of how this works and what sort of things you can really do with DSP you\u2019ll probably have to learn the math&#8230;<\/p>\n","protected":false},"author":206,"featured_media":508,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-465","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-uncategorized","post_format-post-format-image"],"jetpack_featured_media_url":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-content\/uploads\/sites\/89\/2018\/09\/sin2.png","_links":{"self":[{"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/posts\/465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/users\/206"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/comments?post=465"}],"version-history":[{"count":35,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/posts\/465\/revisions"}],"predecessor-version":[{"id":518,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/posts\/465\/revisions\/518"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/media\/508"}],"wp:attachment":[{"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/media?parent=465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/categories?post=465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.cs.vt.edu\/ccs2018f\/wp-json\/wp\/v2\/tags?post=465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}