tag:blogger.com,1999:blog-51655084236184181932024-03-15T09:06:45.887+01:00Signals ProcessedSporadic outbursts of things that have to do with research, electronics or coding that may or may not be DSP related.Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.comBlogger73125tag:blogger.com,1999:blog-5165508423618418193.post-86432906521829980512018-04-24T21:43:00.001+02:002018-04-24T21:43:21.672+02:00The disappearance and reappearance of the DEMAND corpus <div class="separator" style="clear: both; text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja9QhQK1nId82Io9MsrVLEg81PDA8UDVfrGT6BVIS_VNHQAv3G8uOPbslaWiwDKbNVHptqBrk_yVMhxP9urbqM3E3Wo2UP-ax2rHyt5dN1PlR1jPQ70z6zxoKJ2lsH9HPRGlnwjH1-S8Gh/s1600/Screen+Shot+2018-04-24+at+21.08.12.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="191" data-original-width="439" height="139" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja9QhQK1nId82Io9MsrVLEg81PDA8UDVfrGT6BVIS_VNHQAv3G8uOPbslaWiwDKbNVHptqBrk_yVMhxP9urbqM3E3Wo2UP-ax2rHyt5dN1PlR1jPQ70z6zxoKJ2lsH9HPRGlnwjH1-S8Gh/s320/Screen+Shot+2018-04-24+at+21.08.12.png" width="320" /></a></div>
<div style="text-align: justify;">
The <a href="https://zenodo.org/record/1227121">DEMAND</a> ("Diverse Environments Multichannel Acoustic Noise Database") Corpus is one of my most successful creations - at the time I'm writing this post, <a href="https://scholar.google.de/scholar?oi=bibs&hl=en&cites=2954818737208640925,9701276805695528209">Google Scholar claims there are 43 citations</a> of the main article describing it. (And I blogged about it <a href="http://signalsprocessed.blogspot.de/2012/03/building-microphone-array.html">here</a>, <a href="http://signalsprocessed.blogspot.de/2012/10/demand-diverse-environments.html">here</a>, <a href="http://signalsprocessed.blogspot.de/2013/03/updates-to-demand-project.html">here</a> and <a href="http://signalsprocessed.blogspot.de/2014/05/spatial-properties-of-demand.html">here</a>) So it was a bit of a nasty surprise when <a href="http://my.ece.queensu.ca/people/W-Y-G-Chan/index.html">Professor Chan</a> (of Queens University in Kingston, Ontario; a good friend of my Ph.D. supervisor) dropped me a note telling me the database had disappeared off the internet.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To my dismay, I did not have a copy of the data on my own harddrives either, except for the files sampled at 16 kHz; luckily after some frantic emailing, I was told by my former colleagues Remy and Nancy that <a href="https://www.inria.fr/en/centre/rennes">INRIA</a> still has backups of the original files and <a href="https://members.loria.fr/EVincent/">Emmanuel</a> has a backup of the website along with the HTML and descriptive PDF. Note to self: KEEP WELL ORGANIZED BACKUPS!</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkwTvnrhE1XDHbb-vTqz2XJv-8xjpSCxFBWqK3E_wkOPYWc_rlbXS0Vyt1xzzeXm7DQEJRf-l6ZQVMCCiIyhYBcmR2AiVrDcpqCKQKresSRyNEeS5gQlgQizV3l23JC7PxHevgR6y3i26N/s1600/Screen+Shot+2018-04-24+at+21.27.20.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="218" data-original-width="468" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkwTvnrhE1XDHbb-vTqz2XJv-8xjpSCxFBWqK3E_wkOPYWc_rlbXS0Vyt1xzzeXm7DQEJRf-l6ZQVMCCiIyhYBcmR2AiVrDcpqCKQKresSRyNEeS5gQlgQizV3l23JC7PxHevgR6y3i26N/s320/Screen+Shot+2018-04-24+at+21.27.20.png" width="320" /></a></div>
<div style="text-align: justify;">
There was still the problem of finding a new home to host the data, and Emmanuel suggested <a href="https://zenodo.org/">Zenodo</a>, a platform funded by CERN and the EU for open-access data: DEMAND fits the bill pretty well. As a bonus, the dataset now has a "proper" DOI: <a href="https://doi.org/10.5281/zenodo.1227121"><img alt="DOI" src="https://zenodo.org/badge/DOI/10.5281/zenodo.1227121.svg" /></a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I hope the new home of DEMAND is more permanent than the old one; ot certainly looks good. I'll be putting my HRTF database (<a href="http://signalsprocessed.blogspot.de/2014/07/my-workspace-for-next-month-or-two.html">blog post</a>, <a href="https://jthiem.bitbucket.io/research.html#MMHR-HRTF">brief preliminary conference paper</a>) on there too once the main journal article describing it is vetted - actually the data is already there, it just needs to be released.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Enjoy the data! (And let's hope the new location will pop up at the top of Google when using the search terms "DEMAND noise", as the old one did!)</div>
<div style="text-align: justify;">
</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-82439696182029199152018-01-03T04:30:00.001+01:002018-01-03T04:34:47.810+01:00A trip to the library...<div style="text-align: justify;">
When I <a href="https://signalsprocessed.blogspot.ca/2016/08/audio-resampling-in-python.html">started</a> thinking about resampling and the <a href="https://nbviewer.jupyter.org/urls/jthiem.bitbucket.io/project-files/SRCII.ipynb">filters used in resampling</a> I leaned heavily on the book by <a href="https://books.google.ca/books?id=pAsfAQAAIAAJ">P. P. Vaidyanathanm, "Multirate Systems And Filter Banks"</a>, the "brown book" that every signal processing practitioner should have on his or her shelf (or on a shelf of a nearby colleague)!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Like many articles discussing this topic (e.g. the documentation of <a href="https://de.mathworks.com/help/signal/ref/kaiser.html">this MATLAB function</a>), the key paper always referenced is <b>Kaiser, James F.</b> “Nonrecursive Digital Filter Design Using the I0-Sinh Window Function.” <i>Proceedings of the 1974 IEEE International Symposium on Circuits and Systems</i>. April, 1974, pp. 20–23. Being curious about how the equations given in Vaidyanathanm were derived, I wanted to see the original paper - but unfortunately, the earliest proceedings of ISCAS that can be found in IEEE Xplore are from 1988 - 14 years after the one I'm after.</div>
<div style="text-align: justify;">
<br /></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo0rigBT83NmbfsPlYxnrrSZ5FbruzB050tIe8SsSUqCv5Q-or7pbBV-Cp6TqJ6FTDdw5UxVlJmqSEnX5AXrReO96pqD51ckKs6NOY6cskVuxMHyhVXqT53frcdql2jB2oYUV86Uby3Vw6/s1600/20180102_144414.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: justify;"><img border="0" data-original-height="509" data-original-width="1000" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo0rigBT83NmbfsPlYxnrrSZ5FbruzB050tIe8SsSUqCv5Q-or7pbBV-Cp6TqJ6FTDdw5UxVlJmqSEnX5AXrReO96pqD51ckKs6NOY6cskVuxMHyhVXqT53frcdql2jB2oYUV86Uby3Vw6/s320/20180102_144414.jpg" width="320" /></a><br />
<div style="text-align: justify;">
Luckily, I happen to be on Christmas vacation at my inlaws, which live in Kitchener, which is right next door to Waterloo - home to one of the best engineering universities of the world. Unsurprisingly, they have a well-stocked library, which includes the above conference proceeding booklet and, braving the cold, I now have a copy for my own archives.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I could only copy it by taking snaps using my cellphone - the copiers need a special card to use, and the scanners need a UWaterloo login, but for reading the content, that is sufficient with today's smartphones. It's only for personal use, and I do hope that the IEEE will eventually get around to scanning in the older papers!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Papers from that era have a certain charm. Typewriter written equations. FORTRAN code. I believe the below should be FORTRAN66 (due to the IF statement; I don't think FORTRAN IV had that, and FORTRAN77 obviously didn't exist yet). Without looking it up, do you know how that IF statement works? (Explanation at end)</div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUUCEEkz9Bh1jayAruxXAnimy6QpO3nkhKIlYgsLWHSf3xMQG8K3mm0mDkLICD0BUKIbdt3-qkxVi8Tf0vf2m35N094wnh3s9BLP0YEFmYxtT2Ps5NPCIg316ILNReWRPtjOq3L4W_yPhi/s1600/20180102_144414+%25281%2529.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="696" data-original-width="800" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUUCEEkz9Bh1jayAruxXAnimy6QpO3nkhKIlYgsLWHSf3xMQG8K3mm0mDkLICD0BUKIbdt3-qkxVi8Tf0vf2m35N094wnh3s9BLP0YEFmYxtT2Ps5NPCIg316ILNReWRPtjOq3L4W_yPhi/s320/20180102_144414+%25281%2529.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
As for what I learned from the paper (on first quick read): those formulas relating N and beta to the Stopband attenuation and transition band width were fitted to empirical data. I expected as much - but still I wanted to confirm that to myself. (If on a closer read I turn out to be wrong, I'll correct this post)</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
So there's one item off my list of things to to in 2018. Visit the UWaterloo Campus and its library. Good fun.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
-------</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
The FORTRAN IF statement: That is known as the "arithmetic IF" or "three-way IF" statement. The expression after the IF is evaluated, and if it is negative, the execution jumps to the first label ("2", exiting the subroutine). If the result is 0, we go to the second label ("1"), and if it is positive, to the third (also "1"). Here, each term of the power series expansion is calculated, and as soon as the new term is less than 2x10^-9 of the approximation, the code terminates. And IIRC, FORTRAN is call-by-reference.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-4524063975091673182017-11-01T16:56:00.002+01:002017-11-01T20:14:54.622+01:00Halloween Raspberry Pi project<div style="text-align: right;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI1CB4Ntr8VqeLplc-odly-KSyvC4_wOd_znHX0B7Y4LmREkX_zoFDhGH9A2gf7lteQK7M5dAau-9_v1GBoadqc4xhFxkv0ok9Q9gAIDuHP-2lPoAOhEV_0Pv9pLsA3HdszhrUA5d7LLHb/s1600/20171031_141933.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI1CB4Ntr8VqeLplc-odly-KSyvC4_wOd_znHX0B7Y4LmREkX_zoFDhGH9A2gf7lteQK7M5dAau-9_v1GBoadqc4xhFxkv0ok9Q9gAIDuHP-2lPoAOhEV_0Pv9pLsA3HdszhrUA5d7LLHb/s320/20171031_141933.jpg" width="135" /></a></div>
Halloween is a great time to do projects if you have kids. There is a lot of fun to be had building animated things for displays or costumes. In our case, Madeline and I collaborated on a great costume for our son, who wanted to go as a Robot. She found some shiny material and sewed it up, and I build an animated control panel.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkEU09JMzjH85deEt13ZAAQlWUikTiBDAVihrIx4nPh8oQjfWdi8PsVmNSLXOQW-xbQRAQNM_Qxc_oFyb9TxiyhoPBZhVZm_PbxDfzzTpkvWEj_59KCe4ffNEjpv3WIU4_NsP6Hx4P1qeA/s1600/20171030_234300_Richtone%2528HDR%2529.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkEU09JMzjH85deEt13ZAAQlWUikTiBDAVihrIx4nPh8oQjfWdi8PsVmNSLXOQW-xbQRAQNM_Qxc_oFyb9TxiyhoPBZhVZm_PbxDfzzTpkvWEj_59KCe4ffNEjpv3WIU4_NsP6Hx4P1qeA/s320/20171030_234300_Richtone%2528HDR%2529.jpg" width="320" /></a>The Rπ0 controls a IIC-connected OLED display (128x32) and 9 LEDs via the GPIOs. I could theoretically have used an Arduino - but the OLED display is 3.3V only, and I only have 5V Arduinos (I know I can just underclock them, but not during development). Thickness was also a factor - the Rπ0 is VERY flat.<br />
<br />
The panel is built mostly of Moosgummi (craft foam rubber), and I mounted my Raspberry Pi 0 into it. The Rπ0 and all the other stuff is mounted in a sandwich of Moosgummi sheets with strips of Moosgummi around the edge. Power and development (eg. changing the scrolling message or the blink pattern) is done trough a gap, through which a (short) USB cable is fed. The LEDs are connected trough 150 Ohm resistors directly to the GPIOs.<br />
<br />
<div style="text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJE2tjkqjhMaka2SuqPUfaQOVNIe5SuLawq7PmVxBEoMUVTfJzjz_912-_561G6cAoKMTD28U48QXenKcjJuPColehLZM9nkHqESMo4u_st217FZqPJ1P6Nt4rHcgHxsFwPY0BRpAvH5tR/s1600/20171030_145017.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJE2tjkqjhMaka2SuqPUfaQOVNIe5SuLawq7PmVxBEoMUVTfJzjz_912-_561G6cAoKMTD28U48QXenKcjJuPColehLZM9nkHqESMo4u_st217FZqPJ1P6Nt4rHcgHxsFwPY0BRpAvH5tR/s320/20171030_145017.jpg" width="320" /></a></div>
The SD card has <a href="https://www.raspberrypi.org/downloads/raspbian/">Raspbian Stretch Lite</a> on it, to which I added the <a href="https://github.com/adafruit/Adafruit_Python_SSD1306">Adafruit SSD1306 Python library</a>. The Python script (<a href="https://gist.github.com/jthiem/e07ae8ed92d5b8e4397908eb62f1a472">placed in a Gist here</a>) running the display and the LEDs sits in the (FAT-formatted) boot partition, and is called from rc.local. Once that was all in place, I used the <a href="https://learn.adafruit.com/read-only-raspberry-pi/">Read-Only Raspbian script</a> to make the system read-only; this way I can just pull the power once the trick-or-treating is done. The script on the boot partition can still be edited at will by remounting /boot read-write (or pulling the SD card and editing it on a different computer!) The Rπ0 acts as a <a href="http://blog.gbaman.info/?p=699">USB Ethernet gadget</a>, and I can just ssh into it.<br />
<br />
Life lesson learned: Mounting blinking LEDs on your kids makes them very easy to find at night! Note to self: next time, add lights to the back (of the kids) as well.Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-76101768431781586772017-05-07T10:51:00.000+02:002017-05-07T10:57:22.572+02:00NNResample package on PyPI<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAZ0TgVTStwIIameLSwz2-bmDCYURgkMksjPCHhbjwqPwp4oeu3Iq5kiKIJ7J7zUcoeRI6IRlO3Pw75XfWBbnXM3I1frRwwWBeCJGlPz-Ges4a0wJVtHtRBoMo17APd1ZMr4TuOMyC5nq5/s1600/sample.svg.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: justify;"><img border="0" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAZ0TgVTStwIIameLSwz2-bmDCYURgkMksjPCHhbjwqPwp4oeu3Iq5kiKIJ7J7zUcoeRI6IRlO3Pw75XfWBbnXM3I1frRwwWBeCJGlPz-Ges4a0wJVtHtRBoMo17APd1ZMr4TuOMyC5nq5/s320/sample.svg.png" width="320" /></a></div>
<div style="text-align: justify;">
<a href="http://signalsprocessed.blogspot.de/2017/05/resampling-in-python-electric-bugaloo.html">In the previous post</a>, I described my filter generation method for scipy.signal.resample_poly, where the filter is designed such that the first null if the filter is on <a href="https://en.wikipedia.org/wiki/Nyquist_rate">Nyquist</a>. For easier inclusion into my own projects, I made it into a package as a self-standing function, and then decided to make that my first submission to <a href="https://pypi.python.org/pypi">PyPI</a>. The package depends only on numpy and scipy>=0.18.0.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, if you want to use my resampler, you can now simply do `pip install nnresample`. To report bugs, the link to the repository is <a href="https://github.com/jthiem/nnresample">https://github.com/jthiem/nnresample</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I've included one "special feature": since it takes a little time to generate the filter (to search for the null and regenerate the filter afterwards) the generated filter is cached in a global for re-use.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As for the name, since I'm calling it "Null-on-Nyquist Resampler", the obvious name should be non-resample, but I think that could be confusing...</div>
<div style="text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-77258391141944774662017-05-03T00:59:00.000+02:002017-05-03T09:00:24.462+02:00Resampling in Python: Electric Bugaloo<a href="http://signalsprocessed.blogspot.de/2016/08/audio-resampling-in-python.html">In a previous post,</a> I looked at some sample rate conversion methods for Python, at least for audio data. I did some more digging into it, and thanks to a note by Prof. Christian Muenker from the Munich University of Applied Sciences I was made aware of <span style="font-family: "courier new" , "courier" , monospace;">scipy.signal.resample_poly </span>(new in scipy since 0.18.0). This lead me down a bit of a rabbit-hole and I ended up with a Jupyter Notebook which I'm not going to copy-paste here since there is quite a bit of code and some LaTeX in there. <a href="https://nbviewer.jupyter.org/urls/jthiem.bitbucket.io/project-files/SRCII.ipynb">Here is the link to it instead.</a><br />
<br />
For the impatient, here are the interesting bits:<br />
<br />
<pre><a href="https://www.blogger.com/blogger.g?blogID=5165508423618418193" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a>def resample_poly_filter(up, down, beta=5.0, L=16001):
# *** this block STOLEN FROM scipy.signal.resample_poly ***
# Determine our up and down factors
# Use a rational approximation to save computation time on really long
# signals
g_ = gcd(up, down)
up //= g_
down //= g_
max_rate = max(up, down)
sfact = np.sqrt(1+(beta/np.pi)**2)
# generate first filter attempt: with 6dB attenuation at f_c.
filt = firwin(L, 1/max_rate, window=('kaiser', beta))
N_FFT = 2**19
NBINS = N_FFT/2+1
paddedfilt = np.zeros(N_FFT)
paddedfilt[:L] = filt
ffilt = np.fft.rfft(paddedfilt)
# now find the minimum between f_c and f_c+sqrt(1+(beta/pi)^2)/L
bot = int(np.floor(NBINS/max_rate))
top = int(np.ceil(NBINS*(1/max_rate + 2*sfact/L)))
firstnull = (np.argmin(np.abs(ffilt[bot:top])) + bot)/NBINS
# generate the proper shifted filter
filt2 = firwin(L, -firstnull+2/max_rate, window=('kaiser', beta))
return filt2
plt.figure(figsize=(15,3))
wfilt = resample_poly_filter(P, Q, L=2**16+1)
plt.specgram(scipy_signal.resample_poly(sig, P, Q, window=wfilt)*30, scale='dB', Fs=P, NFFT=256)
plt.colorbar()
plt.axis((0,2,0,Q/2))
</pre>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Recycling my test sweep from the previous post, I get:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR13pQBr8ppsbL09uAxhSucJ173vzb4deGJ7rYSnhyB83WJl1leBfV9HmPmEWI5UE1cPVpUyo2IWwx8MCAikcfWuNuGXQ6Xl1sGyperPwz9TwDgA6TZDiF2i51UynpN3ohhaKFsuigDduC/s1600/sweep-own.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR13pQBr8ppsbL09uAxhSucJ173vzb4deGJ7rYSnhyB83WJl1leBfV9HmPmEWI5UE1cPVpUyo2IWwx8MCAikcfWuNuGXQ6Xl1sGyperPwz9TwDgA6TZDiF2i51UynpN3ohhaKFsuigDduC/s400/sweep-own.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sweep resampled using my own filter</td><td class="tr-caption" style="text-align: center;"></td></tr>
</tbody></table>
But really, <a href="https://nbviewer.jupyter.org/urls/jthiem.bitbucket.io/project-files/SRCII.ipynb">please read the Notebook.</a> Comments are welcome!Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-19099627229778280632017-03-20T16:50:00.003+01:002017-03-20T22:23:22.570+01:00Publication update<div style="text-align: justify;">
This blog has been basically been inactive since last October since being a PostDoc means that there are a whole bunch other things that I am busy with. And of course, it <b>was</b> winter - that means statistically, there is always someone in the family who is sick (kids bring home every germ that is going around...).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://upload.wikimedia.org/wikipedia/commons/0/0c/Kiel_Hafen_vom_CAP_Januar_2012.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="127" src="https://upload.wikimedia.org/wikipedia/commons/0/0c/Kiel_Hafen_vom_CAP_Januar_2012.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">View of Kiel. Source: Johannes Barre 2006, on Wikipedia</td></tr>
</tbody></table>
But it is spring now! And I have just returned from <a href="http://www.daga2017.de/">DAGA 2017</a> in <a href="https://en.wikipedia.org/wiki/Kiel">Kiel</a> (where we found a <a href="http://www.banmaai.de/">very nice Thai restaurant</a>) so time to update some of my work!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First off, <a href="https://www.ims.uni-hannover.de/mitarbeiter-as.html">my colleagues in Hannover</a> published <b>"Customized high performance low power processor for binaural speaker localization"</b> at ICECS 2016 in Monte Carlo, Monaco (<a href="http://ieeexplore.ieee.org/document/7841215/">paper on IEEE Xplore</a>), there was the <a href="http://hearing4all.eu/DE/Medien/Veranstaltungen/Intern.php">Winter plenary of Hearing4all</a>, and at DAGA 2017, I presented <b>"Pitch features for low-complexity online speaker tracking"</b>, and Sarina (Ph.D. student I'm co-supervising) presented <b>"A distance measure to combine monaural and binaural auditory cues for sound source segregation"</b>, both of which can be found <a href="https://jthiem.bitbucket.io/research.html">on my homepage</a>. In the pipeline is now <b>"Real-time Implementation of a GMM-based Binaural Localization Algorithm on a VLIW-SIMD Processor"</b> by Christopher, which has been accepted and will be presented at <a href="http://www.icme2017.org/">ICME 2017</a> in Hong Kong in July, and I submitted a paper (<b>"Segregation and Linking of Speech Glimpses in Multisource Scenarios on a Hearing Aid"</b>) to EUSIPCO 2017; that one is still in review.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I was also teaching a class in the past semester ("5.04.4223 <b>Introduction into Music Information Retrieval</b>") which, because it's a brand new class took a crazy amount of work to prepare for - but I think the students really enjoyed it, and I saw some very good code being written for the final project.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now back to real work (writing more papers, that is)! (Well, there's one or two topics I'll put on the blog in the next little while, too. Later.)</div>
<div style="text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-43363189182545553252017-03-17T10:58:00.001+01:002017-03-17T10:58:30.153+01:00What happened to my homepage? Or: why you should read emails from your hosting provider carefully...Having had about a million things on my plate recently (WHEN was the last time I blogged anything?), I tend to prioritize emails - and I did kinda ignore an email sent out by <a href="https://www.atlassian.com/">Atlassian</a> in January. It meant to inform me that the personal homepages on <a href="https://bitbucket.org/">BitBucket</a> were moving from bitbucket.org to bitbucket.io (and switching to https in the process); a redirect from Jan 23rd on, then the old link would be dead after March 1st.<br />
<div>
<br /></div>
<div>
I noticed this of course only when I suddenly couldn't access my homepage. D'Oh!</div>
<div>
<br /></div>
<div>
I have now gone though most of the blog postings here to fix all the links. If you find any that I missed (or other dead links) please let me know in the comments! Thanks!</div>
<div>
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-36095093062221000182016-10-23T21:20:00.000+02:002016-10-23T21:20:42.769+02:00A (very) short trip to Korea<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-eIJM7HzcgjQ/V_332kQw_9I/AAAAAAAAJs4/nBMk_dxgDAskSDX1hydVKGYfprfKDproACPcB/s1600/PANO_20161012_174232.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="96" src="https://2.bp.blogspot.com/-eIJM7HzcgjQ/V_332kQw_9I/AAAAAAAAJs4/nBMk_dxgDAskSDX1hydVKGYfprfKDproACPcB/s400/PANO_20161012_174232.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Panorama view from my room at the Nest Hotel in Incheon. The Incheon Airport is visible on the right.</td></tr>
</tbody></table>
<div style="text-align: justify;">
Earlier this month, I was in Incheon, South Korea, to present a talk at the Symposium for "<a href="http://home.kias.re.kr/MKG/h/spmlspr/?pageNo=2506" target="_blank">Statistical physics, machine learning, and its application to speech and pattern recognition</a>", organized by Prof. Kang-Hun Ahn as part of the <a href="http://www.kias.re.kr/" target="_blank">Korea Institute for Advanced Study (KIAS)</a>. I was specifically invited to give a talk there (along with Jörg Lücke and Steven van de Par). One does not refuse such an invitation, esp. as a post-doc trying to make an academic career happen.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As a conference, the event was very good, in both of scientific content and forging connections that hopefully can continue in the future. Many interesting discussions happened outside the sessions, too.</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVBskDRx2dPMzs4x9yU3QnHJ05qR3BGczxcyaY8_wy5x_pcEHS5xHqrEhbQyECN-dcO4g_BjlBwr6yQK-vJ3HMmzHU2YYpzUC0v_lChtrzUsQuxYZ7fWTw1l4XPPlFLRWdKJSgJ7ZMIt5Z/s1600/IMG_20161014_180755.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVBskDRx2dPMzs4x9yU3QnHJ05qR3BGczxcyaY8_wy5x_pcEHS5xHqrEhbQyECN-dcO4g_BjlBwr6yQK-vJ3HMmzHU2YYpzUC0v_lChtrzUsQuxYZ7fWTw1l4XPPlFLRWdKJSgJ7ZMIt5Z/s320/IMG_20161014_180755.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: justify;">The location of the Symposium banquet. It was excellent. Don't ask me for the name though; but I can give the coordinates: 37°25'53.1"N 126°25'27.0"E</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
The trip was bizarre for me for one reason, though. It's the first time I traveled that far just to present at a conference. Unfortunately, this symposium was scheduled not long after I had returned from Italy (where I was at <a href="http://mlsp2016.conwiz.dk/home.htm" target="_blank">MLSP 2016,</a> coupled with a 1 week vacation), and the week before classes start here at the University of Oldenburg; so I had no time to do any sightseeing in Korea. I literally arrived the day before the first day of the symposium, and left the morning after the last day. Total time in Korea: about 66 hours. Total time flying there and back: 30 hours. We (myself, Jörg, and Steven) never went further than about 5 km from the Airport.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I certainly hope to go to Korea again, but then stay a little longer! There is so much to see, and I have friends in Japan I'd like to visit, too. (I've been to Jeju before, so I know Korea can be very beautiful. Next time I'd like to bring the wife and kids along!)</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-35057525235300535642016-09-14T10:25:00.000+02:002017-03-17T10:45:45.569+01:00MLSP2016 paper: Speaker Tracking for Hearing Aids<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: justify;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-8MEk_eyCS-g/V9j2yebIP1I/AAAAAAAAJHk/I-kuO9olLugN9VbgCtugC7WrERCG0jtzACPcB/s1600/mlsp2016poster.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://3.bp.blogspot.com/-8MEk_eyCS-g/V9j2yebIP1I/AAAAAAAAJHk/I-kuO9olLugN9VbgCtugC7WrERCG0jtzACPcB/s200/mlsp2016poster.jpg" width="150" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MLSP 2016 poster, the print version<br />
can be found <a href="http://jthiem.bitbucket.io/MyPapers/MLSP2016-poster.pdf" target="_blank">here</a>.</td></tr>
</tbody></table>
<div style="text-align: justify;">
Yesterday, I presented my poster at the 2016 IEEE International Workshop on Machine Learning for Signal processing. I think it was received pretty well, there were several people that talked to me, and we had very good discussions. The biggest problem (and typical for all poster sessions) was that there were other good posters being presented, and I couldn't really spend time talking to the other authors at that session. However, over the next few days I'll have a chance to chat with them, so it's all good.</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy3ZemNSRNLOdUmwWaOqjj5yDvepukvvIuq6s7fthQQ60xnx4TCDd40e4F4QeXhezlp-udp0uRh2vDaZ3sSjT0QMXSsz_5zpLQBM3N3aZRkSRAYMeHMqoEXn4thaBj5ZvK1Yg20H6xoyMg/s1600/mlsp2016view.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy3ZemNSRNLOdUmwWaOqjj5yDvepukvvIuq6s7fthQQ60xnx4TCDd40e4F4QeXhezlp-udp0uRh2vDaZ3sSjT0QMXSsz_5zpLQBM3N3aZRkSRAYMeHMqoEXn4thaBj5ZvK1Yg20H6xoyMg/s200/mlsp2016view.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The beach of the conference venue,<br />
with view towards Salerno.</td></tr>
</tbody></table>
<div style="text-align: justify;">
My own paper I'm presenting is entitled "Speaker Tracking for Hearing Aids", and it basically a method to link speech utterances spoken at different times by the same speaker, a classic problem also found in speaker diarization (but I don't need to do segmentation). My method however is optimized for low computational complexity (for hearing aids), yet reaches comparable performance to typical far more complex methods. You can find the abstract, paper, and poster (seen in the pic) <a href="http://jthiem.bitbucket.io/" target="_blank">on my homepage.</a></div>
<div style="text-align: justify;">
Overall, I like these small, highly focused conferences - and being in a nice sunny environment is not to be sneezed at either.</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-5702984441143798112016-08-31T15:53:00.000+02:002016-08-31T15:56:31.475+02:00A library of Gammatone Filterbanks in Python<div style="text-align: justify;">
I have already programmed gammatone filterbanks several times in MATLAB, but in for some recent work I needed a specific one (the One-Zero Gammatone filterbank) <a href="http://ieeexplore.ieee.org/document/4267201/" target="_blank">[Katsiamis, 2006]</a> in Python.</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-left: 0px; margin-right: 0px; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaQRbWa2PiuzeIJFjC5VAx0e5n6aWW7NegMpx2CKvLsWa9-IX0LRJoO5ybRqHn9l8o_deEUq3pvB-QZz8cvVVAiiCEMlW8JSn1hyphenhyphenSsyoAwfXXKv8eqw27VKilEsqHD0Biuzu3CZBPRU6Vk/s1600/GT_time.svg.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaQRbWa2PiuzeIJFjC5VAx0e5n6aWW7NegMpx2CKvLsWa9-IX0LRJoO5ybRqHn9l8o_deEUq3pvB-QZz8cvVVAiiCEMlW8JSn1hyphenhyphenSsyoAwfXXKv8eqw27VKilEsqHD0Biuzu3CZBPRU6Vk/s320/GT_time.svg.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Gammatone impulse responses, in time domain</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In addition, I wanted my "old" FIR GTFB (from my <a href="http://signalsprocessed.blogspot.ca/2011/11/matlab-code-for-my-thesis.html" target="_blank">Ph.D. Thesis</a>) to be in there as well as the GTFB of a former colleague here in Oldenburg <a href="http://ieeexplore.ieee.org/document/7156101/" target="_blank">[Chen, 2015]</a>. So I packed them all up in a library - I also wanted to learn how to make a PyPI compatible Python library.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b>This is a work in progress. </b>The gammatone filterbanks mentioned are there, but momentarily I don't have time to polish the code; furthermore, I'd like to eventually add the Slaney GTFB and the Hohmann GTFB - not to mention the structure needs more cleanup. Consider this v0.01, for educational purposes. <a href="https://github.com/jthiem/gtfblib" target="_blank">You can find it on github.</a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-53787158799123629302016-08-11T10:31:00.000+02:002017-05-08T13:39:56.589+02:00Audio Resampling in Python<div style="background-color: white; box-sizing: border-box; color: black; font-family: "helvetica neue", helvetica, arial, sans-serif; font-size: 14px; font-style: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">
<div style="font-weight: normal;">
(Note: this post was written as a Jupyter Notebook which can be found with the Python code at <a href="https://nbviewer.jupyter.org/gist/jthiem/0bb8b2296c8dbd0b83bfab8270a8eb24">https://nbviewer.jupyter.org/gist/jthiem/0bb8b2296c8dbd0b83bfab8270a8eb24</a>.) </div>
<div style="font-weight: normal;">
<br /></div>
<b>UPDATE: </b>You can resample with nothing but scipy and one extra function now.<strike> <a href="http://signalsprocessed.blogspot.de/2017/05/resampling-in-python-electric-bugaloo.html">See this new post.</a></strike><br />
<a href="http://signalsprocessed.blogspot.de/2017/05/nnresample-package-on-pypi.html">I now have written a package that you can install using pip.</a></div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
One of the most basic tasks in audio processing anyone would need to do is resampling audio files; seems like the data you want to process is<span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">never</i><span class="Apple-converted-space"> </span>sampled in the rate you want. 44.1k? 16k? 8k? Those are the common ones; there are some really odd ones out there.</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Resampling is actually quite hard to get right. You need to properly choose your antialias filters, and write a interpolation/decimation procedure that won't introduce too much noise. There have been books written on this topic. For the most part, there is no single univeral way to to this right, since context matters.</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
For a more detailed discussion on sample rate conversion see the aptly named "Digital Audio Resampling Homepage" [<a href="https://ccrma.stanford.edu/~jos/resample/" style="background-color: transparent; box-sizing: border-box; color: #337ab7; text-decoration: underline;" target="_blank">https://ccrma.stanford.edu/~jos/resample/</a>]. Then look at [<a href="http://src.infinitewave.ca/" style="background-color: transparent; box-sizing: border-box; color: #337ab7; text-decoration: underline;" target="_blank">http://src.infinitewave.ca/</a>] for a super informative comparison of a ton of resampling implementations.<span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">No seriously, go there.</i><span class="Apple-converted-space"> </span>(It inspired me to compare the methods below using a sine sweep.)</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
MATLAB has the built-in<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resample</code><span class="Apple-converted-space"> </span>function. Everyone uses it. It works, but also sucks in many aspects - a much better function is in the DSP toolbox, but as near as I can tell, noone uses it (even when copious other parts of the DSP toolbox are being used!)</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
But I'm not talking about MATLAB, I'm talking about Python here, and it doesn't have a default resampling method - except if you're doing any kind of numerical computing, you'll be using<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">numpy</code><span class="Apple-converted-space"> </span>and probably<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scipy</code><span class="Apple-converted-space"> </span>--- and the latter<span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">has</i><span class="Apple-converted-space"> </span>a built-in resample function.</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
To get ahead of myself a bit,<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scipy.signal.resample</code><span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">sucks</i><span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">for audio resampling</i>. That becomes apparent quite quickly - it works in frequency domain, by basically truncation or zero-padding the signal in the frequency domain. This is quite ugly in time domain (especially since it assumes the signal to be<span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">circular</i>).</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
There are two alternatives I want to point at that are "turn-key", that is, you just have to specify your resampling ratio, and the library does the rest. I know of a few others, but at the time of writing this they didn't seem as easy to use (eg. just doing the interpolation/decimation, but not calculating a filter.) If there are other notable libraries I should know of, please mention it in the comments of the blog version of this notebook [<a href="https://signalsprocessed.blogspot.de/" style="background-color: transparent; box-sizing: border-box; color: #337ab7; text-decoration: underline;" target="_blank">https://signalsprocessed.blogspot.de</a>].</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
The first alternative is<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scikit.resample</code>. Using it has two problems: it relies on an external (C-language) library called "Secret Rabbit Code" (SRC as in "sample rate conversion", geddit?) aka libsamplerate [<a href="http://www.mega-nerd.com/SRC/">http://www.mega-nerd.com/SRC/</a>]. Not a problem in itself, but you need to install it and this step is not automated in pip and friends (as far as I know at time of writing). (Problem for me was that I needed to run it on a platform where I couldn't do this easily.) Problem 2: scikit.resample 0.3.3 is Python 2 only, and the Python 3 version is unofficial (0.4.0-dev, I used [<a href="https://github.com/gregorias/samplerate" style="background-color: transparent; box-sizing: border-box; color: #337ab7; text-decoration: underline;" target="_blank">https://github.com/gregorias/samplerate</a>]).</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
The other one is<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code>, which can be found in PyPI or [<a href="https://github.com/bmcfee/resampy" style="background-color: transparent; box-sizing: border-box; color: #337ab7; text-decoration: underline;" target="_blank">https://github.com/bmcfee/resampy</a>]. It is easy to install and works with Python 3 (<code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">librosa</code><span class="Apple-converted-space"> </span>now uses it as preferred resampler over libsamplerate)</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
TL;DR: if you can install external libs, use scikit.resample (0.4.0-dev).<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code><span class="Apple-converted-space"> </span>is faster, but not as good, but entirely reasonable. (If MATLAB<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resample</code><span class="Apple-converted-space"> </span>is good enough for you,<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code><span class="Apple-converted-space"> </span>will serve you just fine and is easier to install)</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Now for a comparison with pretty pictures.</div>
<h2 id="Downsampling-a-sweep" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 21.994px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; letter-spacing: normal; line-height: 1; margin: 0.636em 0px 0px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Downsampling a sweep</h2>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
A common task is to convert between the CD sampling rate of 44.1 kHz, and the multiples of 8kHz that originated from the telekon industry. In particular, 48kHz. (Supposedly the rate of 44.1k was chosen in part<span class="Apple-converted-space"> </span><i style="box-sizing: border-box; font-style: italic;">because</i><span class="Apple-converted-space"> </span>is was difficult to convert to 48 kHz; but it is also connected to NTSC timing). So let's have a sweep sampled at 48 kHz. (See the Jupyter Notebook for the Python code)</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9B6CDEw876-TUe_eb8XrOpZiPhQQ9BZdSCPxzHDWLtW5UM0n8mRZDUTAFh60chEYU7jTRkeqIk5uNopo7Me4srV0HVD_RxBkRnnAu9sPIpDr7unWWcYT_DDLklmfm32tWjK9kemGwgO3j/s1600/sweep48k.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9B6CDEw876-TUe_eb8XrOpZiPhQQ9BZdSCPxzHDWLtW5UM0n8mRZDUTAFh60chEYU7jTRkeqIk5uNopo7Me4srV0HVD_RxBkRnnAu9sPIpDr7unWWcYT_DDLklmfm32tWjK9kemGwgO3j/s400/sweep48k.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sweep 100-23900 Hz, sampled at 48 kHz.</td></tr>
</tbody></table>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">Now convert it to 44.1 kHz using the different libraries, and plot the spectrograms.<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO8sau32MnsTO5Zub1ZaRqU-fo8j1I0CUu019z6IZXsalwMjUKC_zVxiyfxjmf-0RDiCWZa1MvR4BWgJYaCwxx7gV0-Tv6uW-LOIPZuD8fWfcS7clFbPGXkWDhD9ib07VHriizbzrlwvZK/s1600/sweep441src.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO8sau32MnsTO5Zub1ZaRqU-fo8j1I0CUu019z6IZXsalwMjUKC_zVxiyfxjmf-0RDiCWZa1MvR4BWgJYaCwxx7gV0-Tv6uW-LOIPZuD8fWfcS7clFbPGXkWDhD9ib07VHriizbzrlwvZK/s400/sweep441src.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Same sweep downsampled to 44.1 kHz using scikit.resample.</td></tr>
</tbody></table>
</span></div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><code style="-webkit-text-stroke-width: 0px; background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: 2; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">scikit.samplerate</code><span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="Apple-converted-space"> </span>(or<span class="Apple-converted-space"> </span></span><code style="-webkit-text-stroke-width: 0px; background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: 2; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">libsamplerate</code><span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span class="Apple-converted-space"> </span>AKA "Secret Rabbit Code") does it well. Almost no aliasing, yet close to Nyquist, and noise levels in line with the input. Note that once the sweep is above Nyquist, the output is basically nil.<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGkj2HurPnZ2fXof5o_XtHRUAFQiW8siXQbw5nlAZyHYIleGvT70s3AQdi1_wm2gt1oEvIaiHnOqjwJuOEKP8yXQmXXffrJljsAbDlElROnal7x5FCAcv9TBSU-vJyLrZvMh_lBHETj3s5/s1600/sweep441scipy.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGkj2HurPnZ2fXof5o_XtHRUAFQiW8siXQbw5nlAZyHYIleGvT70s3AQdi1_wm2gt1oEvIaiHnOqjwJuOEKP8yXQmXXffrJljsAbDlElROnal7x5FCAcv9TBSU-vJyLrZvMh_lBHETj3s5/s400/sweep441scipy.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The same sweep but now downsampled using scipy.signal.resample.</td></tr>
</tbody></table>
</span></span></div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">And this is<span class="Apple-converted-space"> </span></span><code style="-webkit-text-stroke-width: 0px; background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: 2; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px;">scipy.signal.resample</code><span style="background-color: white; color: black; display: inline; float: none; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">. Throughout the entire signal there is a high-frequency tone, and there is considerable energy even if the sweep is above Nyquist. This is a result of the frequency-domain processing operating on the entire signal at one. This is NOT suited to audio signals.</span></span></span></div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwvrtMZt1SEqyIjiZW9Cx5jAYGRjKJ8gFAKMgEutiKCo6663CbrVGFq7CEDNzP1fC74yAC6iPS8eBreIlEB9xIXPCHe0Okuw2Aqqmmx19BYOsNZBFCiSBCEiTgC-n3Xi09VeXSSqZpBJ1M/s1600/download.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwvrtMZt1SEqyIjiZW9Cx5jAYGRjKJ8gFAKMgEutiKCo6663CbrVGFq7CEDNzP1fC74yAC6iPS8eBreIlEB9xIXPCHe0Okuw2Aqqmmx19BYOsNZBFCiSBCEiTgC-n3Xi09VeXSSqZpBJ1M/s400/download.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The same sweep downsampled using resampy.</td></tr>
</tbody></table>
Finally,<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code>. There are some funny nonlinear effects, but at very low level - for audio applications generally nothing to worry about. Even the aliasing is below -60 dB. So, while not as good as<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scikit.resample</code><span class="Apple-converted-space"> </span>is is useable and certainly better than<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scipy.signal.resample</code>!</div>
<h2 id="Upsampling-an-impulse" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 21.994px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; letter-spacing: normal; line-height: 1; margin: 1.27em 0px 0px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Upsampling an impulse</h2>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
A way to examine the antialias filter is to upsample an impulse. Here, note a frustrating aspect of all these differing libraries: the interface is completely different beween all of them; and to boot,<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code><span class="Apple-converted-space"> </span>and<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">scikit.resample</code><span class="Apple-converted-space"> </span>give different length outputs for the same upsampling ratio. This means you can't just switch between them using a<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">from foo import resample</code><span class="Apple-converted-space"> </span>statement, you'll need a wrapper function if you want to switch freely amongst them (see<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">librosa</code><span class="Apple-converted-space"> </span>as an example).</div>
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">>>> us1 = sk_samplerate.resample(impulse, P/Q, 'sinc_best')</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">>>> us2 = scipy_signal.resample(impulse, int(len(impulse)*P/Q))</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">>>> us3 = resampy.resample(impulse, Q, P)</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">>>> print(us1.shape, us2.shape, us3.shape)</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">(1087,) (1088,) (1088,)
</span></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaToWLud0AJHPkav6J2Xav22PEhhcNmUeGzp2w4wJZ9NJ8pVX1R-VoTlP_Ql-sS1v9NqiuQQaIFJP2XcIvhscrozaCwvDB2LAjsGEscapqNu8nT4zNR1s4J70NRZZTupsUYkFtKPDnXXT7/s1600/impulse-filter.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaToWLud0AJHPkav6J2Xav22PEhhcNmUeGzp2w4wJZ9NJ8pVX1R-VoTlP_Ql-sS1v9NqiuQQaIFJP2XcIvhscrozaCwvDB2LAjsGEscapqNu8nT4zNR1s4J70NRZZTupsUYkFtKPDnXXT7/s640/impulse-filter.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Frequency response of an impulse upsampled from 44.1 kHz to 48 kHz</td></tr>
</tbody></table>
<pre style="background-color: white; border-radius: 0px; border: 0px none; box-sizing: border-box; color: black; display: block; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 17.0001px; margin: 0px; overflow: auto; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; vertical-align: baseline; white-space: pre-wrap; word-break: break-all; word-spacing: 0px; word-wrap: break-word;"><span style="font-size: small;"><span style="font-family: "courier new" , "courier" , monospace;"> </span></span></pre>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
'scikit.resample' certainly uses the best antialias filter, with a steep slope, allowing very little energy over Nyquist. 'resampy' is a more gentle filter (lower order, perhaps?) but decent. 'scipy.signal.resample'... well, anyways.</div>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
What do the impulse responses look like in time domain? </div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4S1YRdAZRDglQsHmUi3MPq8vtJiuweo5_L9CmcHZ30S8NdMaxnrxuhnuJCJoVeV17SRIb-NtKjf_8IYsGZNh1EqWuO3Gger4DWeSDm5lWqTtS9IqohpJD_EaOXmDvat1Dl06oSt2rF8cv/s1600/impulse-time.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4S1YRdAZRDglQsHmUi3MPq8vtJiuweo5_L9CmcHZ30S8NdMaxnrxuhnuJCJoVeV17SRIb-NtKjf_8IYsGZNh1EqWuO3Gger4DWeSDm5lWqTtS9IqohpJD_EaOXmDvat1Dl06oSt2rF8cv/s640/impulse-time.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Time-domain impulse upsampled from 44.1 kHz to 48 kHz</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghfQ0e-nRDWjHfFLdaQqCXmCsNaxA7itGta72xBlZJ1bDwUSHCxKc2qqkPNZew1bid3_U96lKYeMdb8s7q4aCJ7CtotsKDI4SjW7ulGcXF5O1W3PW9nZEi_Vojv7uRr1KAktyREK_hkUFG/s1600/impulse-time-dB.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghfQ0e-nRDWjHfFLdaQqCXmCsNaxA7itGta72xBlZJ1bDwUSHCxKc2qqkPNZew1bid3_U96lKYeMdb8s7q4aCJ7CtotsKDI4SjW7ulGcXF5O1W3PW9nZEi_Vojv7uRr1KAktyREK_hkUFG/s640/impulse-time-dB.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The same section of the impulse, but with samples converted into dB (10*log10 magnitude squared)</td></tr>
</tbody></table>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Unsurprisingly, 'resampy' is the most compact, which explains the gentler cut-off. 'scikit.resample' is wider, but acceptable. 'scipy.signal.resample' sticks out like a sore thumb.</div>
<h2 id="Speed-comparison" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 21.994px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; letter-spacing: normal; line-height: 1; margin: 1.27em 0px 0px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Speed comparison</h2>
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">>>> %timeit sk_samplerate.resample(sig, Q/P, 'sinc_best')</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">10 loops, best of 3: 98.1 ms per loop</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">>>> %timeit scipy_signal.resample(np.float64(sig), int(len(sig)*Q/P))</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">100 loops, best of 3: 4.52 ms per loop</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">>>> %timeit resampy.resample(np.float64(sig), P, Q) </span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">10 loops, best of 3: 40.7 ms per loop</span><br />
<br />
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
And here is a notable merit of 'scipy.signal.resample'. It is faster by an order of magnitude compared to the other methods. I suspect that if you make sure your signals are of length 2^N<span class="MathJax" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mn>2</mn><mi>N</mi></msup></math>" id="MathJax-Element-1-Frame" role="presentation" style="border: 0px; box-sizing: border-box; direction: ltr; display: inline-table; float: none; font-size: 14px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; max-height: none; max-width: none; min-height: 0px; min-width: 0px; padding: 0px; position: relative; text-align: left; text-indent: 0px; text-transform: none; white-space: nowrap; word-spacing: normal; word-wrap: normal;" tabindex="0"><nobr style="border: 0px; box-sizing: border-box; line-height: normal; margin: 0px; max-height: none; max-width: none; min-height: 0px; min-width: 0px; padding: 0px; text-decoration: none; transition: none; vertical-align: 0px; white-space: nowrap !important;"></nobr></span>, you'll get even faster results, since it'll switch to a FFT instead of a DFT. The other two are probably losing some speed in the passing of data from Python to C - but fundamentally, frequency domain techniques do tend to be fast. So keep that in mind you you need speed.</div>
<h2 id="Conclusion" style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 21.994px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; letter-spacing: normal; line-height: 1; margin: 1.27em 0px 0px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
Conclusion</h2>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
I'll just repeat the above TL;DR: use scikit.resample (0.4.0-dev) if you can install libsamplerate in a sane place. Else, use<span class="Apple-converted-space"> </span><code style="background-color: white; border-radius: 2px; border: 0px; box-sizing: border-box; color: black; font-family: monospace; font-size: 14px; padding: 0px; white-space: pre-wrap;">resampy</code>, which is faster, but not as good --- but entirely reasonable. Use 'scipy.signal.resample' only if you really need the speed, and be aware of its shortcomings (note the circular assumption!).</div>
<pre style="-webkit-text-stroke-width: 0px; background-color: white; border-radius: 0px; border: 0px; box-sizing: border-box; color: black; display: block; font-family: monospace; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 17.0001px; margin: 0px; orphans: 2; overflow: auto; padding: 0px; text-align: left; text-indent: 0px; text-transform: none; vertical-align: baseline; white-space: pre-wrap; widows: 2; word-break: break-all; word-spacing: 0px; word-wrap: break-word;"> </pre>
<div style="-webkit-text-stroke-width: 0px; background-color: white; box-sizing: border-box; color: black; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; margin: 1em 0px 0px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com4tag:blogger.com,1999:blog-5165508423618418193.post-23522256345442004652016-06-06T22:18:00.000+02:002016-06-08T11:26:19.654+02:00FFT-based Overlap-Add FIR filtering in Python<div style="text-align: right;">
<a href="https://upload.wikimedia.org/wikipedia/commons/7/77/Depiction_of_overlap-add_algorithm.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="103" src="https://upload.wikimedia.org/wikipedia/commons/7/77/Depiction_of_overlap-add_algorithm.png" width="200" /></a></div>
<a href="https://github.com/jthiem/overlapadd">Here is a small Python function I've written</a> (github), that might be useful if you're doing signal processing in Python. The function implements the classic FFT-based Overlap-Add filtering, potentially saving a heck of a lot of processing time (assuming your filter is of sufficiently high order: usually about 128 taps).<br />
<br />
For a thorough explanation of the algorithm, <a href="https://en.wikipedia.org/wiki/Overlap%E2%80%93add_method">see the Wikipedia article</a>.<br />
<br />
I wrote this code as part of a lager ongoing project (gammatone filtering) that I will release eventually. <strike>What I still have to add to this code is the ability to set and save state information (it's simply the part of the response cut off at the end of the function) and the ability to filter complex signals with complex filters (replacing rfft with fft).</strike> Changes made in the latest version.<br />
<br />Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-57230681481349331062016-05-18T15:57:00.001+02:002016-05-18T15:57:26.572+02:00A simple scikit-learn classifier based on Gaussian Mixture Models (GMM)<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj22JS7nrKC2OjQ9HC-jN_KM0OrmswohOhtCnwhEqAKVEEtXIKsn76mCGoLtlQaYrQAq3vHGAUEDJcgl6YXMZO5EjchZ37JlDVmA5yN7fjxoiv54dzZnPD8FUzAeomeP8HgU3e-fEu9pn3C/s1600/GMMcl-demo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj22JS7nrKC2OjQ9HC-jN_KM0OrmswohOhtCnwhEqAKVEEtXIKsn76mCGoLtlQaYrQAq3vHGAUEDJcgl6YXMZO5EjchZ37JlDVmA5yN7fjxoiv54dzZnPD8FUzAeomeP8HgU3e-fEu9pn3C/s400/GMMcl-demo.png" width="400" /></a></div>
When I started switching to Python for my work on CASA, it wasn't entirely clear to me how to use the sklearn GMM (<a href="http://scikit-learn.org/stable/modules/generated/sklearn.mixture.GMM.html"><span style="font-family: "Courier New",Courier,monospace;">sklearn.mixture.GMM</span></a>) for classification. Turned out a bit easier than expected (yay for scikit-learn!), but for others, here is my implementation of a class that behaves like the other classifiers (eg. <a href="http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html#sklearn.svm.SVR"><span style="font-family: "Courier New",Courier,monospace;">sklean.svm.SVC</span></a>). All you need to decide is how many Gaussians you want to model your data with, and off you go.<br />
<br />
<a href="https://github.com/jthiem/GMMcl">Link to Github repo.</a> A <a href="http://jupyter.org/">Jupyter</a> notebook shows a sample use.<br />
<br />
Why isn't something like this in sklearn yet? Well, turns out someone did propose it already (no surprise) in a much more general way: <a href="https://github.com/scikit-learn/scikit-learn/pull/2468">see this discussion on GitHub</a>. (I myself was pointed there when <a href="https://github.com/scikit-learn/scikit-learn/issues/5616">I asked about my own code</a>) My bit of code is far more primitive, but I hope easier to understand.<br />
<br />Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-3574967100727908582016-04-12T16:14:00.001+02:002017-03-17T10:42:34.696+01:00DAGA2016 article: Probabilistic 2D localization of sound sources using a multichannel bilateral hearing aidJust put my DAGA 2016 article online. <a href="http://jthiem.bitbucket.io/MyPapers/DAGA2016-paper.pdf">Link to paper.</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg51mTApk9bkAPx1-9hxu5mjaAXqXckNzp0wI1ev0XDiQl_NinUU_59fDGlwpFEcFgWT-Z6N5jbAn6xFTUozFQBYShliMNrRnGaH4gYxiZhxPSCLUCbHFMsr7F0uG1JgLnBWMvDsIXf8o5X/s1600/Screenshot_2016-04-12_16-13-10.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg51mTApk9bkAPx1-9hxu5mjaAXqXckNzp0wI1ev0XDiQl_NinUU_59fDGlwpFEcFgWT-Z6N5jbAn6xFTUozFQBYShliMNrRnGaH4gYxiZhxPSCLUCbHFMsr7F0uG1JgLnBWMvDsIXf8o5X/s320/Screenshot_2016-04-12_16-13-10.png" width="320" /></a></div>
<div style="text-align: justify;">
Abstract: In the context of localization for Computational Auditory Scene Analysis (CASA), probabilistic localisation is a technique where a probability that a sound source is present is computed for each possible direction. This approach has been shown to work well with binaural signals provided the location of the sources to be localized is in front of the user and approximately on the same plane as the ears. Modern hearing aids use multiple microphones to perform array processing, and in a bilateral configuration, the extra microphones can be used by localization algorithms to not only estimate the horizontal direction (azimuth), but vertical direction (elevation) as well, thereby also resolving the front-back confusion. In this work, we present three different approaches to use Gaussian Mixture Model classifiers to localize sounds relative to a multi- microphone bilateral hearing aid. One approach is to divide a unit sphere into a nonuniform grid and assign a class to each grid point; the other two approaches estimate elevation and azimuth separately, using either a vertical-polar coordinate system or an ear- polar coordinate system. The benefits and drawbacks in terms of performance, computational complexity and memory requirements are discussed for each of these approaches.</div>
<div style="text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-73202836219454129662016-02-08T11:39:00.000+01:002016-02-08T11:39:10.959+01:00GMM based localizer on custom ASIC model<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-left: 0px; margin-right: 0px; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioxWimMMIvHMDPIcYW_EiwV0ICTPVlw2uy0YssZevcp1Jv-CNs6jw2ta3GkUkgTidQQDzEjYDB9Em_t8-5SJxna38Av7cUgZRkVGs2VPopC9pOSoj7ZUCZ-w9yyERiCGqiTGcKW2DGkhdh/s1600/IMG_20160205_112243.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioxWimMMIvHMDPIcYW_EiwV0ICTPVlw2uy0YssZevcp1Jv-CNs6jw2ta3GkUkgTidQQDzEjYDB9Em_t8-5SJxna38Av7cUgZRkVGs2VPopC9pOSoj7ZUCZ-w9yyERiCGqiTGcKW2DGkhdh/s320/IMG_20160205_112243.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The model interface hardware with the FPGA in-circuit emulator.</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnbmy7UhkqAUcsawrkpNVD-mdt2m4g6hOfV0fGPlUqtNUeqlOD-MlnHAPcCTsViz2MS_S89smjWn_hSIYLkd4_kZG5Z6OcDCK7L9m4vjHkdOSz0QcT38h9Fcyx-cV5DP3pSU0WcmUsi0W/s1600/IMG_20160205_112312.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxnbmy7UhkqAUcsawrkpNVD-mdt2m4g6hOfV0fGPlUqtNUeqlOD-MlnHAPcCTsViz2MS_S89smjWn_hSIYLkd4_kZG5Z6OcDCK7L9m4vjHkdOSz0QcT38h9Fcyx-cV5DP3pSU0WcmUsi0W/s320/IMG_20160205_112312.jpg" width="254" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Lukas Gerlach (L) and Christopher Seifert (R) demoing their ASIC model setup, running realtime on a FPGA.</td><td class="tr-caption" style="text-align: center;"><br /></td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<div style="text-align: justify;">
It's always nice to see one's own research code running on real actual hardware with live data rather than just having a simulation in MATLAB. My colleagues over at the <a href="https://www.ims.uni-hannover.de/">Institut für Mikroelektronische Systeme (IMS)</a> of the <a href="https://www.uni-hannover.de/">Leibnitz Universität in Hannover</a> presented a demo of their hardware at the <a href="http://hearing4all.eu/DE/">Hearing4All</a> winter plenary held last week in Soltau. The code running on the hardware visible is a GMM based localizer originally written by Tobias May, but since heavily modified by myself. The next step is that we'll write up exactly what we did to make this all work and how well it does - so look out for an article on this in the near future! It's one of the advantages of being at an intengrated cluster; at
Hearing4All, pretty much everything related to hearing loss is being
investigated: from basic ear physiology, to audiology, models,
algorithms, clinical procedures, implants, and new ground-breaking
hardware.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-10403700311249376332016-02-02T23:11:00.000+01:002017-03-17T10:41:39.730+01:00The Selective Binaural Beamformer: It's out!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQYpqyhr5WLLyUbiD3rsBtbPxlbQhy9NvbbTKuWZp2f2WzSWBsM3EYOHVltusUavZsZQnUR7ujhSuyhJh-4BQq1QyfBrS6kGwXir9KwVuRh2TJyxLv-6YZ5X2gXB1XcPuAxKiE-07wj3Zi/s1600/Figure1.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQYpqyhr5WLLyUbiD3rsBtbPxlbQhy9NvbbTKuWZp2f2WzSWBsM3EYOHVltusUavZsZQnUR7ujhSuyhJh-4BQq1QyfBrS6kGwXir9KwVuRh2TJyxLv-6YZ5X2gXB1XcPuAxKiE-07wj3Zi/s320/Figure1.jpg" width="320" /></a></div>
<div style="text-align: justify;">
After six or so months of going through the peer review gauntlet, our paper on the Selective Binaural Beamformer (or simply SBB) is finally published. Thanks to all my coauthors (Menno, Daniel, Simon, and Steven) as well as the reviewers (especially reviewer #2, who gave very tough but important feedback) I think this became a very nice paper. Please go ahead and read it at <a href="http://www.asp.eurasipjournals.com/content/2016/1/12">http://www.asp.eurasipjournals.com/content/2016/1/12</a> (EURASIP Journal on Advances in Signal Processing, full title "Speech enhancement for multimicrophone binaural hearing aids aiming to preserve the spatial auditory scene"): it's open access, one can read it either at the above address or <a href="http://www.asp.eurasipjournals.com/content/pdf/s13634-016-0314-6.pdf">download a PDF</a> (see the right sidebar on the linked page). Being open access, it's free and CC-A 4.0 licensed. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSdzZ4rEar3-BLn6CbgNIJ1AJCjE1y4YqZsRfrhSKyrIcO_iu5FSX_gipEgpbgOLltbxw_5CQ1aMMqJ3stTpw3z_VO84Ehs_HNGkywfD-dEeVDU-dc8RW6RA9jNjFXD1dbOr6EHtD6SN9z/s1600/Figure2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSdzZ4rEar3-BLn6CbgNIJ1AJCjE1y4YqZsRfrhSKyrIcO_iu5FSX_gipEgpbgOLltbxw_5CQ1aMMqJ3stTpw3z_VO84Ehs_HNGkywfD-dEeVDU-dc8RW6RA9jNjFXD1dbOr6EHtD6SN9z/s200/Figure2.png" width="118" /></a></div>
<div style="text-align: justify;">
The basic idea behind the algorithm is this: Normally, if using a beamforming algorithm on a binaural hearing aid, the entire auditory image will collapse to the position of the beam direction, that is ALL sound will appear (to the hearing aid user) to originate from the same location. Various methods have been proposed to fix this - Simon Doclo in particular has done a lot of work on this topic (which is why it was so helpful to have him as coauthor). My approach to this problem was to take the signal in the STFT domain (ie, the signal is divided into discrete short time frames and narrow frequency bins) and in each "bin" (time-frequency unit) make a decision if the target signal is dominant, or if the background noise is dominant. In the first case, I use the beamformer output: the signal is enhanced, collapsed, but that's OK - it _should_ be coming from the target direction anyways. In the second case, I simply use the signal as it comes from the two microphones closest to the ear canal, without processing - hence there is (almost) no difference from the "real" signal reaching the ears. So, all the benefit of the beamformer without the nasty collapse of the auditory field!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
...Well, mostly. The tricky part is to make a good speech/noise decision (or actually a "target signal"/background noise decision). But there's a fancy SNR estimator in there, from Adam Kuklasinski (see ref. 19 - I met him in Lisbon where he presented it at EUSIPCO), and that works pretty well.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So if this is the kind of thing that seems interesting to you, read the paper - and I will post some of the sample files (that were used during subjective testing) soonish on my <a href="http://jthiem.bitbucket.io/research.html">personal homepage</a>.</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-71699595374665406102015-07-02T12:30:00.000+02:002015-07-02T12:30:15.258+02:00A bit of Python path hackeryLike many people, I have a directory in $HOME for useful python code I write.
Similar to MATLAB's <span style="font-family: "Courier New",Courier,monospace;">"Documents/MATLAB"</span> directory, I want those files to be
easily available if I'm hacking new stuff. The typical way of handling
this is to do:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">
import sys
sys.path.append('/path/to/my/dir')
</code>
</pre>
but that is a bit ugly, and has the problem that if I'm doing an
<a href="http://ipython.org/notebook.html">IPython Notebook</a>
(<a href="http://signalsprocessed.blogspot.de/2014/10/using-arm-chromebook-for-scientific-and.html">as I often do</a>),
this append function gets reevaluated if I reexecute the cell in which
I do all my imports (since as I'm edition the notebook and adding stuff,
I would do a lot). Besides I now have sys in my namespace.<br />
<br />
I could just dump it into <span style="font-family: "Courier New",Courier,monospace;">".local/lib/python3.4/site-packages" </span>
(too hidden, outside the tree that is synced between machines), or link
<span style="font-family: "Courier New",Courier,monospace;">"Documents/Python"</span> to that path, but then I don't want to have <span style="font-family: "Courier New",Courier,monospace;">pip</span> install
stuff there, and also, there might be times I <i>don't</i> want
<span style="font-family: "Courier New",Courier,monospace;">"Documents/Python"</span> to be in the path.<br />
<br />
So here's my solution. I place a file in <span style="font-family: "Courier New",Courier,monospace;">".local/lib/python3.4/site-packages"</span> and <span style="font-family: "Courier New",Courier,monospace;">".local/lib/python2.7/site-packages"</span>
with a name like <b><span style="font-family: "Courier New",Courier,monospace;">"LocalPath.py"</span></b>, and this file contains<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
import sys
myPythonDir = '/home/jthiem/Documents/Python'
if myPythonDir not in sys.path:
sys.path.append(myPythonDir);
</code>
</pre>
I can now do
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
import LocalPath</code>
</pre>
and have instant no-fuss access to my homebrew packages. Now isn't that nice.Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-62660491384233698682015-07-02T11:28:00.002+02:002015-07-02T11:52:33.792+02:00EUSIPCO 2015<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShNna_JT12h9FddkPnZgFMJ-_36AlYTg-m7Hp7w4bj6Dt92pmCg8Zpyb8_APcMDQ1dmYDQIqNCv-F4LEFKju41ol4Qp3mbwl6evKF9jTebYboFNEKOU3LG3AmmqZtlvzOXDqFojcIqZI_/s1600/Nice_france_mamac.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShNna_JT12h9FddkPnZgFMJ-_36AlYTg-m7Hp7w4bj6Dt92pmCg8Zpyb8_APcMDQ1dmYDQIqNCv-F4LEFKju41ol4Qp3mbwl6evKF9jTebYboFNEKOU3LG3AmmqZtlvzOXDqFojcIqZI_/s320/Nice_france_mamac.JPG" width="320" /></a></div>
It's becoming a habit: I'm going to <a href="http://www.eusipco2015.org/">EUSIPCO</a> again. They seem to have a preference for the sunnier parts of Europe (fine by me!) so this time I'm off to <a href="https://en.wikipedia.org/wiki/Nice">Nice, France</a>, where I will be presenting some of my current work on CASA for hearing devices. While what I'll be presenting is just a small part of the whole, it's an important initial result: evaluating the features I'm extracting from the hearing aid microphones to use for localization of sources. I'll be presenting my paper "Features for Speaker Localization in Multichannel Bilateral Hearing Aids" as part of the <a href="http://www.eusipco2015.org/content/special-sessions#SS0">Acoustic scene analysis using microphone array</a> special session, on Wednesday at 14:30. (A bit of a pity, I would have liked to attend the "Audio and speech source separation and enhancement" session as well)<br />
<br />
I'll be going straight to Nice after visiting the in-laws in Canada, so it'll be quite the trip. Hope to see you there!<br />
<br />Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-84221120424366675942014-11-28T15:40:00.001+01:002014-11-28T15:40:56.291+01:00The new and improved method of real-time MIDI control of MATLAB (or Python, or ... whatever!)In <a href="http://signalsprocessed.blogspot.de/2011/09/real-time-control-of-matlab-using-midi.html">an older post on my blog</a>, I had this method to get the state of a MIDI controller into MATLAB (though readable by pretty much anything that can read files). This method is quite clunky and when I wanted to do something similar again, I re-thought the problem and came up with a better method based on memory mapped files. You can find the
<a href="https://github.com/jthiem/midistatebroadcast">code on GitHub</a>.
<br />
<br />
Basically, I'm creating a file of fixed length (260 bytes, in /tmp), mmap() it and update the contents based on the MIDI stream I'm receiving. The first 128 bytes are for keys, where each byte is the last seen velocity (0 means "off"). The following 128 bytes are for the cc messages. Bytes 257 and 258 store the pitch bend, a 14-bit value with MSB in byte 257. Byte 259 is the last received program change value and 260 is the channel aftertouch.<br />
<br />
<b>MATLAB Access</b><br />
<br />
Accessing the values from MATLAB does not require any special functions, it can simply be done using<br />
<br />
<pre>mm = memmapfile('/tmp/midibroadcast');
</pre>
<br />
then the data can be obtained in real-time from mm.Data. As described above, mm.Data(1:128) are the last seen key down velocities (0 meaning key is not pressed) and mm.Data(129:256) are controllers 0..127. The pitch bend value can be obtained as mm.Data(257)*256+mm.Data(258) (<i>note this may be buggy; my cheap controller (KeyRig 25) does not let me set and hold precise pitch bends, so I can't test it properly</i>). mm.Data(259) is the program change and mm.Data(260) shows the current aftertouch amount.<br />
<br />
<b>Python Access</b><br />
<br />
From Python the values can be accessed as easily:<br />
<br />
<pre>import os
import mmap
mfd = os.open('/tmp/midibroadcast', os.O_RDONLY)
mfile = mmap.mmap(mfd, 0, prot=mmap.PROT_READ)
</pre>
<br />
Remembering that Python counts from 0, the controllers can be read in real-time as mfile[128] to mfile[255]: just subtract 1 from the descriptions above.<br />
<br />
Any language which can do memory-mapping should be able to do the same, but it should even be possible to read the current state just by re-reading the /tmp/midibroadcast file.<br />
<br />
Enjoy!<br />
<br />Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-50686274318588537792014-10-05T23:22:00.000+02:002014-10-05T23:23:13.790+02:00Using an ARM Chromebook for Scientific (and Academic) Computing<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOvAYPp8V7kP4S6tqHXVFhQ1sUzMS3GXV7-p3JK99HAJcztrsXCah28QlSWjhMPCYSjvV0fP7EAaIaNbdg9RCv5rFhNVpbeOq8QhpxyBKLpTz1YQAbNHK01vOJXz1I2eDFapVux4LXMkD6/s1600/IMG_20140930_154714.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOvAYPp8V7kP4S6tqHXVFhQ1sUzMS3GXV7-p3JK99HAJcztrsXCah28QlSWjhMPCYSjvV0fP7EAaIaNbdg9RCv5rFhNVpbeOq8QhpxyBKLpTz1YQAbNHK01vOJXz1I2eDFapVux4LXMkD6/s1600/IMG_20140930_154714.jpg" height="200" width="192" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Samsung ARM Chromebook</td></tr>
</tbody></table>
A couple of months ago, I decided to get myself a Chromebook. The Samsung ARM Chromebook is cheap (to the point of being almost disposable) and it's got an ARM CPU - and for performance at the least possible amount of juice it's hard to beat. I really like the fact that this thing emits no noise that I can detect even in a very quiet room.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But how useful is it, for someone in a standard engineering/academic setting? The answer is that it works well, for me at least - with some special considerations. Especially for the last few weeks, it has been my primary laptop, having been dragged to research cluster meetings and one conference. I will explain the details of a few typical things I do, such as (LaTeX) document editing, intensive numerical computation, etc. Read below the break for details. </div>
<div style="text-align: justify;">
</div>
<a name='more'></a>First off, the Chromebook is NOT - and probably will never be - my primary computer. This is a big part of how I'm doing my work with the Chromebook, that is, it is primarily a remote access device for my desktop at work, a nice 8-core i7 box with 16G of RAM. (If I do want to work offline, I have an SD card with <a href="http://archlinuxarm.org/platforms/armv7/samsung/samsung-chromebook">Arch Linux for ARM</a>, and a <a href="https://github.com/dnschneid/crouton">Crouton chroot</a> - but that's beyond the scope of this post).<br />
<div style="text-align: justify;">
<h3>
</h3>
<h3>
Remote Access</h3>
If you're old-school, the only thing you really need is a shell. For me, <a href="http://mosh.mit.edu/">mosh</a> is the best thing since sliced bread, and it's available as <a href="https://chrome.google.com/webstore/detail/mosh/ooiklbnjmhbcgemelgfhaeaocllobloj?hl=en">a Chrome extension</a>. It handles disconnects and network changes without sweat - very important so you can just close the lid and not worry about logging off. The alternative is ssh (available <a href="https://chrome.google.com/webstore/detail/secure-shell/pnhechapfaindjhompbnflcldabbghjo?hl=en">as a Chrome extension as well</a>, or using the developer console) with <a href="http://www.gnu.org/software/screen/">GNU Screen</a> or <a href="http://tmux.sourceforge.net/">tmux</a> on the other end. Not nearly as convenient though. mosh with tmux is where it's at.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If I do need graphics (say for running MATLAB on my desktop), I use VNC via ssh. I start ssh with a port redirect from localhost to the remote, tightvnc on my desktop and the RealVNC VNC viewer on the Chromebook. It does suffer from lag, and recently the tightvnc server has been giving me grief. I'm eagerly awaiting Chrome Remote Desktop to become usable on Linux (remoting a session or being a "pure" login session). I'm already using Chrome Remote Desktop to talk to Windows if I have to.<br />
<br />
<b>The real killer app is <a href="http://ipython.org/">iPython</a>.</b> To be exact, the <a href="http://ipython.org/notebook.html">iPython Notebook</a> server, running on my desktop computer. With nothing more than the Chrome browser running natively on the Chromebook, I can edit and run Python code (<a href="http://signalsprocessed.blogspot.de/2014/09/transplant-yet-another-bridge-between.html">and Matlab code!</a>) on my main box, so I don't need to worry about lugging big datasets around, backups (happen automatically), or my laptop falling under the bus or getting stolen. Besides, once you get used to the notebook workflow, it's a very efficient way of creating research code.<br />
<br />
<a href="http://www.latex-project.org/"><b>LaTeX</b></a>. Still the best way to create scientific documents where it is necessary to discuss math. On the one hand, it is easy enough to use the above-mentioned remote shell methods (again: yay mosh!) to login to the mothership and then use vim (or Emacs, pick your poison) to edit the source text. That works OK, but I'm not that stuck in the 90's that I <i>prefer</i> to work that way - I appreciate the ability to be able to hit "recompile" and see my changes instantly so at home I have <a href="http://pages.uoregon.edu/koch/texshop/">TeXShop</a>, and if I'm at my desk I have <a href="http://www.xm1math.net/texmaker/">Texmaker</a>. On the Chromebook? I have started using <a href="https://www.sharelatex.com/">ShareLaTeX</a>, which basically is Texmaker in the browser. It's been working fine for me, with some issues: I'd like to be able to sync with files on my desktop and it doesn't handle disconnections very well yet.<br />
<br />
<b>Cloud Storage and Editing</b>: The University of Oldenburg runs OwnCloud and Gitlab servers. I could actually edit my LaTeX source files via the Gitlab web interface - but then I'd have unverified source in the repo. I prefer sticking with vim.<br />
<br />
<b>The Google Apps. </b>Yes, I do use them. GMail and Google calendar extensively, Google Docs quite a bit. This all ties well together with my Android Phone (Galaxy S3, if you care - these things go cheap second hand these days). These things are what the Chromebooks are made for, unsurprisingly they work well - within their limits. I use Google Docs for notes and other things where high-quality typesetting is not needed.<br />
<br />
<b>The things that don't work. </b>There are a few things I can't (yet?) do well on the Chromebook. One of these is my work e-mail, sitting on an Exchange server. The webmail interface sucks. Hard. The University doesn't want me to forward my mail to Gmail (and I actually agree, wanting to keep my work and personal mail separate, also; privacy). There is no good IMAP mail reader as a Chrome extension so for now, I'm using <a href="http://www.mutt.org/">mutt</a> on my desktop computer (and did I mention mush yet???). I'm considering <a href="https://www.mailpile.is/">Mailpile</a>, which looks really cool, GMail-like, keeps all the mail on my desktop yet should let me read it from anywhere.<br />
<br />
<b>Privacy and security concerns. </b>This is where many people (including myself) have misgivings about the Chromebook. The Chromebook, unless repurposed by loading regular Linux on it, is chained to the Google ecosystem. If you don't want to interact with Google, do not get a Chromebook. That being said, I could actually create a "burner" Google account, and just use it to log into the Chromebook, then let everything just go through my desktop machine. I'm just not that paranoid, and tolerate Google analysing my data - within reason. Besides, this blog is hosted by Blogger (thus, Google) so the very act of reading this, you are using (and being analysed by) the Goog.<br />
<h3>
Conclusion</h3>
<div>
I like my Chromebook. But I'm not attached to it, and that's kinda the point. If a better one comes along (and I'm already considering the Tegra based ones as a soonish replacement), there will be absolutely no need to change any of my workflow.</div>
<div>
<b>What would be even better</b> would be a "Firefoxbook" - a browser-only laptop that would be - if one chose to work that way - be completely controlled not by Google's servers but your own. It shouldn't be too hard to roll one's own Linux (or *BSD) distro to do exactly that if one can get a cheap laptop with really good open-source supported hardware. Oh, if I had an infinite supply of round tuits...</div>
<div>
<br /></div>
</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-970326113472850812014-09-24T22:01:00.000+02:002014-09-24T22:01:26.182+02:00Transplant: yet another bridge between MATLAB and Python, but a good one!<div style="text-align: justify;">
This post is basically just an advertisement for a project done by a Master's student that I'm co-supervising at the moment. While there are <a href="http://stackoverflow.com/questions/9845292/a-tool-to-convert-matlab-code-to-python">numerous methods already out there to link MATLAB to Python</a> (and rumour has it that the next(?) release will make it easier to call Python <i>from</i> MATLAB), I think <a href="http://bastibe.de/2014-08-19-transplant.html">Basti's "transplant"</a> (<a href="https://github.com/bastibe/transplant">github link</a>) strikes a good balance between simplicity and capability. Bastian's code is elegant and reliable. My own contribution has just been a small bug fix, the ability to transfer logical (boolean) matrices, and an attempt to add the ability to capture MATLAB's stdout (Bastian came up with a much better solution).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For me the resulting killer feature is that I can write IPython notebooks that call MATLAB code in a sane way. Complex code which would take too much effort to convert to Python can be called, then the results can be plotted in the Notebook, which is great when working remotely (a longer post on my workflow is in the works...). Results become more accessible, with a lot of the complexity hidden away in .m files.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, <a href="https://github.com/bastibe/transplant">check it out</a> and spread the word!</div>
<div style="text-align: justify;">
<br /></div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-58768527769266720382014-07-04T13:51:00.000+02:002014-07-04T13:51:34.227+02:00My workspace for the next month or two<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNM7Y3JY_1b99hvwvfR3PaaXClNelvtldkky-s2XoXbdmCPEcJeSBPOPn-TO6gcNJalsoaXF_QYbRpwtTgcXtzqUPUDk-toOLfpYzPBg5WHfZrDTHReYOoyMKOBxB13-9QOJESbcQrX2Gy/s1600/IMG_20140704_113000.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNM7Y3JY_1b99hvwvfR3PaaXClNelvtldkky-s2XoXbdmCPEcJeSBPOPn-TO6gcNJalsoaXF_QYbRpwtTgcXtzqUPUDk-toOLfpYzPBg5WHfZrDTHReYOoyMKOBxB13-9QOJESbcQrX2Gy/s1600/IMG_20140704_113000.jpg" height="400" width="300" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The two arc source positioning system in the anechoic chamber<br />of the Carl-von-Ossietzky University of Oldenburg</td></tr>
</tbody></table>
Yeah, I'll be doing HRTF measurements on dummy heads with multichannel hearing aids. Should be fun.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-8912868046526483742014-06-30T14:39:00.000+02:002014-06-30T17:43:43.044+02:00Samsung ARM Chromebook XE303 with VGA adapter - power problemsI have a Samsung ARM Chromebook (the 303 series) which is pretty nice, and I really like it for its size, weight and complete lack of fan and hard drive noise.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwdkAtZMpfG4anaRs3MQUfofxnYPu95H1E_EgoEjpm-gO_2elCfsGUbkpXDfd9lVGS-Lqp8s_wuNhzqR5DnUcCTWIq43fowy4bmPpc0_voe6hePmofpPwezuVBu7ySUClO2Kn12cpbF_c9/s1600/IMG_20140630_135446.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwdkAtZMpfG4anaRs3MQUfofxnYPu95H1E_EgoEjpm-gO_2elCfsGUbkpXDfd9lVGS-Lqp8s_wuNhzqR5DnUcCTWIq43fowy4bmPpc0_voe6hePmofpPwezuVBu7ySUClO2Kn12cpbF_c9/s1600/IMG_20140630_135446.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Samsung XE303C12-H01DE Chromebook: with 3G modem and<br />
a German keyboard which I'm still not used to.</td></tr>
</tbody></table>
<br />
However, I need to give presentations on occasions. No problem, I just get one of these:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpmID98FQ2uBZxPhXJ6kurcc4cGetkuI6PaTRu_BqIPjlXn-MfqCKaO4vBP6El7pchLo3Y2UMzdy0AuevjkmJcsUkPxh5wCJ7GLCixMymmfD5EcQ9qo_vCHn5xX2Q2tRAs4E8DCHmtZwuf/s1600/sku_156981_2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="color: black;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpmID98FQ2uBZxPhXJ6kurcc4cGetkuI6PaTRu_BqIPjlXn-MfqCKaO4vBP6El7pchLo3Y2UMzdy0AuevjkmJcsUkPxh5wCJ7GLCixMymmfD5EcQ9qo_vCHn5xX2Q2tRAs4E8DCHmtZwuf/s1600/sku_156981_2.jpg" height="200" width="200" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: inherit; font-size: x-small;">HDMI to VGA adapter from DX.com (SKU 156981)</span></td></tr>
</tbody></table>
For less than $10, that's hard to beat. Unfortunately, I found it doesn't work as-is with the Samsung Chromebook. Already thinking I need to either give up on the idea of using the Chromebook for presenting or getting a more expensive adapter, I decided to try and see why the bloody thing doesn't work. I verified it does work with my Raspberry Pi, so the problem must be with the Chromebook - perhaps a power problem? <a href="http://en.wikipedia.org/wiki/Hdmi">According to Wikipedia</a>, HDMI should have +5V on pin 18. I opened up the adapter, which can be done with nothing more than one's fingernail, running it along the seam around the VGA socket, then confirmed the absence of 5V on the HDMI port. Lukily, getting 5V is no problem if you have a USB port nearby and here is my solution to this particular annoyance:<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD1JO6lEMvj_gbSVZ2s0-YB8ni8KDoeUTkbcqy4yYxt7l6AFOz2XoAk5AVdabXyAJgxQ6hB3YIMfHiexqD_cQN7uXN_Rr3-PxUDqJk3BP1e-XMDrc8GJgVM5niVGga0AhyBIMNbV9n6AiN/s1600/IMG_20140630_135925.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD1JO6lEMvj_gbSVZ2s0-YB8ni8KDoeUTkbcqy4yYxt7l6AFOz2XoAk5AVdabXyAJgxQ6hB3YIMfHiexqD_cQN7uXN_Rr3-PxUDqJk3BP1e-XMDrc8GJgVM5niVGga0AhyBIMNbV9n6AiN/s1600/IMG_20140630_135925.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HDMI to VGA adapter with power bypass fitted</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<b>I take no responibility for damage you might be inflicting to your Chromebook or any other device you might want to use this mod on. Try this at your own risk, there is a good chance of frying delicate electronics. </b><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4FoGGavN9HJ4AGwfQe-5X4u7g_ge-_4rJ_l_pfWqnMFjC2PD6ZMtFdWnQXiE5TcAsGic1OIeIySuPFUPk9fJWHCZuve1vDQ-aMGcFyJVHj83qZowEvAOyihOOicccia8L-hZs4olJwfZE/s1600/IMG_20140630_140039.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4FoGGavN9HJ4AGwfQe-5X4u7g_ge-_4rJ_l_pfWqnMFjC2PD6ZMtFdWnQXiE5TcAsGic1OIeIySuPFUPk9fJWHCZuve1vDQ-aMGcFyJVHj83qZowEvAOyihOOicccia8L-hZs4olJwfZE/s1600/IMG_20140630_140039.jpg" height="350" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">How to solder the power onto the adapter: +5 on <br />
pin 18, ground to wherever convenient.</td></tr>
</tbody></table>
Basically, take a USB plug and solder two wires to just the outside pins. Drill a hole through the plastic and the rubber fitting of the HDMI to VGA adapter (slide the insides out first!) Solder the 5V wire to the pin 18 endpoint of the cable and the ground to a ground point on the adapter PCB. Done! I put a knot into the cable for strain relief, to prevent the solder points being ripped off.<br />
<br />
That's it! It works nicely, although I don't think the adapter queries the monitor for modes, a decent selection is given to the ChromeOS as soon as the adapter is plugged in. I've only tried it with one projector so far, but there is no reason it should not work with just about any that accept VGA signals.<br />
<br />
Hopefully this information is useful to other (ARM) Chromebook users, but note this is a no-name adapter - yours may look entirely different. Just remember these adapters are active devices which need power (even if very little), and since the Chromebook isn't delivering it on its HDMI port, you need to get it there somehow.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-3843834614368720012014-05-29T22:06:00.000+02:002017-03-17T10:39:16.537+01:00Hello Lisbon! EUSIPCO 2014, here I come!<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQaMa9EW4krS2Z5bq1gBtxrG06Khzw4aKh45FaJY-ax9K7m25DzrcPiXD-swczdfKGRgeT1CAskEGgZo04C2YRaTaaj9y2ekqqcg0rG8JQMJ0y7mgnop7XxzMeYc7lJg0xKR1NCsB6G-7Z/s1600/Downtown_Lisbon.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQaMa9EW4krS2Z5bq1gBtxrG06Khzw4aKh45FaJY-ax9K7m25DzrcPiXD-swczdfKGRgeT1CAskEGgZo04C2YRaTaaj9y2ekqqcg0rG8JQMJ0y7mgnop7XxzMeYc7lJg0xKR1NCsB6G-7Z/s1600/Downtown_Lisbon.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Downtown Lisbon, picture by <br />
Keiran Thomas via Wikimedia Commons</td></tr>
</tbody></table>
<div style="text-align: justify;">
As hinted in <a href="http://signalsprocessed.blogspot.de/2014/05/spatial-properties-of-demand.html">a previous post</a>, together with Menno Müller I had a paper submitted to <a href="http://www.eusipco2014.org/">EUSIPCO 2014</a>, and yesterday we finally got the review results. It got accepted by all reviewers, and several of those six (SIX!?!!) really liked the paper, so naturally I'm pleased as punch about it. And of course I'm already looking into how to get to Lisbon and what else to go see when I'm there. So while I can't publish the paper on <a href="http://jthiem.bitbucket.io/">my own homepage</a> until after the conference is over (and besides, the reviewers did ask for some minor corrections that I still have to put in), I can now refer to: J. Thiemann, M. Müller, and S. van de Par, "A Binaural Hearing Aid Speech Enhancement Method Maintaining Spatial Awareness for the User", <i>to be presented at EUSIPCO 2014</i>.</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0tag:blogger.com,1999:blog-5165508423618418193.post-44787318609224530012014-05-29T14:24:00.000+02:002017-03-17T10:38:45.936+01:00A Sudoku solver in PythonI'm not that great at Python yet. But practice makes perfect, so just to see if I can do it, I wrote <a href="http://jthiem.bitbucket.io/research-files/SuSo.py">this Sudoku solver in Python</a> (needs v3). The algorithm is my own though I don't think it is very (or at all) novel, just actually looking for other solvers would spoil the fun!<br />
<div>
<br /></div>
<div>
The implementation is also probably overly byzantine, mostly due to the way the state is stored. This is done as follows: at the bottom is a list of states for each symbol in a given cell, the states are one of "this symbol is possible here", "this symbol is impossible here", "this symbol is here (set by specification)", and "this symbol is here (set by the solver)". The last two are really the same for the algorithm but eased my own understanding and debugging - but this adds lines to the code since both states need to be checked in some cases.</div>
<div>
<br /></div>
<div>
The set of states for each cell are then bunched into a list for each row, and then all rows are bunched into a list. So, to find out if the "4" is possible in column 3, row 7, check if state[3][7][4] is set to 0.</div>
<div>
<br /></div>
<div>
The solver algorithm can now be simply described by three steps: </div>
<div>
<ol>
<li>After setting a cell to some symbol, mark the same symbol as being impossible in cells in the same groups (row, column box). </li>
<li>For all cells, check if there is the case where a single symbol is not impossible. If so, set the cell to that symbol.</li>
<li>For all groups, check where within a group a given symbol is possible in only one cell. If so, assign that symbol to the open cell.</li>
</ol>
<div>
If in either of step 2 or 3 a cell was set to some symbol, restart from one. Repeat this until neither of the two last steps sets a new cell to a symbol, at which point the puzzle is solved, it's not completely specified, or there is an ambiguity that I don't handle in this code (I think it is possible for some sort of circular ambiguity to exist).</div>
</div>
Joachim Thiemannhttp://www.blogger.com/profile/06186372299937344961noreply@blogger.com0