{"id":279,"date":"2020-07-25T18:49:33","date_gmt":"2020-07-26T01:49:33","guid":{"rendered":"https:\/\/boom-tracker.com\/tracker\/?p=279"},"modified":"2020-07-25T18:49:34","modified_gmt":"2020-07-26T01:49:34","slug":"to-skew-or-not-to-skew","status":"publish","type":"post","link":"https:\/\/boom-tracker.com\/tracker\/blog\/to-skew-or-not-to-skew\/","title":{"rendered":"To skew or not to skew"},"content":{"rendered":"\n<p>After writing up my (computationally intensive) code to measure the skew between the signals from two microphones, I&#8217;ve made a discovery.  It <a rel=\"noreferrer noopener\" href=\"\/tracker\/blog\/the-good-the-bad-and-the-skewed\/\" target=\"_blank\">works great<\/a> for stuff with complex, low-frequency sounds like my chair creaking, but not so well in other cases.  For sustained, constant frequency sounds (like beeps) it gets confused about which of several possible alignments are &#8220;best&#8221;.  Take for example this short beep as heard by two adjacent microphones:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496.png\" alt=\"\" class=\"wp-image-281\" width=\"776\" height=\"582\" srcset=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496.png 640w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496-300x225.png 300w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496-250x188.png 250w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496-550x413.png 550w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496-240x180.png 240w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496-400x300.png 400w\" sizes=\"auto, (max-width: 776px) 100vw, 776px\" \/><\/figure>\n\n\n\n<p>My visual best fit says the green waveform needs to be shifted a few hundred microseconds to the right, and that these were almost in alignment already.  However, my algorithm shifted it ~13,000 microseconds to the left.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed.png\" alt=\"\" class=\"wp-image-282\" width=\"788\" height=\"591\" srcset=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed.png 640w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed-300x225.png 300w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed-250x188.png 250w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed-550x413.png 550w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed-240x180.png 240w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595619496_skewed-400x300.png 400w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><\/figure>\n\n\n\n<p>It <strong>did <\/strong>make the wave peaks line up, but since this is a more or less steady tone, that happens every couple of milliseconds.  I&#8217;m also sure it maximized my fit function, but to my eye the overall envelopes don&#8217;t match nearly as well.  I think there are two factors working against my algorithm here.  First, the waveforms weren&#8217;t complete&#8211;the beginning of the waveforms was cut off by different amounts in the different samples.  I&#8217;ve taken measures to reduce the likelihood of that happening, but I can&#8217;t eliminate it altogether. Second, this was a fairly steady tone&#8211;as I already mentioned, and there were lots of &#8220;pretty good&#8221; fits that it had to choose from.<\/p>\n\n\n\n<p>The other situation that it doesn&#8217;t handle well is more problematic.  It appears that for short, sharp sounds&#8211;like a clap, whip crack, fireworks or gunshots&#8211;there is too much high-frequency information that the two mics will sample differently, and since my sampling rate is about 20kHz, I really can only differentiate frequencies below about 10kHz (5kHz for a good fit).  See the <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Nyquist%E2%80%93Shannon_sampling_theorem\" target=\"_blank\">Nyquist-Shannon theorem<\/a> for a more complete discussion as to why.  So, when I have a signal with a lot of high-frequency information, I can&#8217;t really match it effectively.  Take this example of a clap when the mics where a few feet apart (1-2 meters):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844.png\" alt=\"\" class=\"wp-image-283\" width=\"798\" height=\"599\" srcset=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844.png 640w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844-300x225.png 300w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844-250x188.png 250w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844-550x413.png 550w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844-240x180.png 240w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844-400x300.png 400w\" sizes=\"auto, (max-width: 798px) 100vw, 798px\" \/><\/figure>\n\n\n\n<p>The apparent shift shouldn&#8217;t need to be large, but the algorithm doesn&#8217;t pay attention to that, and it came up with a fit that looked like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed.png\" alt=\"\" class=\"wp-image-284\" width=\"806\" height=\"605\" srcset=\"https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed.png 640w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed-300x225.png 300w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed-250x188.png 250w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed-550x413.png 550w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed-240x180.png 240w, https:\/\/boom-tracker.com\/tracker\/wp-content\/uploads\/2020\/07\/mic_001_004_1595620844_skewed-400x300.png 400w\" sizes=\"auto, (max-width: 806px) 100vw, 806px\" \/><\/figure>\n\n\n\n<p>This is a much worse fit according to my eye.  I think a better technique in this case it to line up the beginning of the loud sounds, but I need to come up with a way to identify those algorithmically.   I&#8217;ll probably use some heuristic like looking at the time of the first samples to fall significantly further from the mean than I&#8217;d been seeing previously, but that requires that I have a nice quiet section before the sound happens.  I&#8217;ve taken steps to try to make sure that I have that (by sending the prior buffer as well when I detect an anomaly), but it doesn&#8217;t always work out as you can see in the purple curve.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After writing up my (computationally intensive) code to measure the skew between the signals from two microphones, I&#8217;ve made a discovery. It works great for stuff with complex, low-frequency sounds like my chair creaking, but not so well in other cases. For sustained, constant frequency sounds (like beeps) it gets confused about which of several&hellip; <a class=\"more-link\" href=\"https:\/\/boom-tracker.com\/tracker\/blog\/to-skew-or-not-to-skew\/\">Continue reading <span class=\"screen-reader-text\">To skew or not to skew<\/span> <span class=\"meta-nav\" aria-hidden=\"true\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bgseo_title":"","bgseo_description":"","bgseo_robots_index":"index","bgseo_robots_follow":"follow","footnotes":""},"categories":[3,7,9,8],"tags":[],"class_list":["post-279","post","type-post","status-publish","format-standard","hentry","category-blog","category-design","category-experimentation","category-implementation"],"_links":{"self":[{"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/posts\/279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/comments?post=279"}],"version-history":[{"count":1,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/posts\/279\/revisions"}],"predecessor-version":[{"id":285,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/posts\/279\/revisions\/285"}],"wp:attachment":[{"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/media?parent=279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/categories?post=279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/boom-tracker.com\/tracker\/wp-json\/wp\/v2\/tags?post=279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}