ASCIIMath creating images

Wednesday, November 1, 2017

Halloween Raspberry Pi project

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.

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.

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.

The SD card has Raspbian Stretch Lite on it, to which I added the Adafruit SSD1306 Python library.  The Python script (placed in a Gist here) 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 Read-Only Raspbian script 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 USB Ethernet gadget, and I can just ssh into it.

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.

Sunday, May 7, 2017

NNResample package on PyPI

In the previous post, 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 Nyquist.  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 PyPI.  The package depends only on numpy and scipy>=0.18.0.

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 https://github.com/jthiem/nnresample.

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.

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...

Wednesday, May 3, 2017

Resampling in Python: Electric Bugaloo

In a previous post, 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 scipy.signal.resample_poly (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.  Here is the link to it instead.

For the impatient, here are the interesting bits:

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))

Recycling my test sweep from the previous post, I get:
Sweep resampled using my own filter
But really, please read the Notebook.  Comments are welcome!

Monday, March 20, 2017

Publication update

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 was winter - that means statistically, there is always someone in the family who is sick (kids bring home every germ that is going around...).

View of Kiel. Source: Johannes Barre 2006, on Wikipedia
But it is spring now!  And I have just returned from DAGA 2017 in Kiel (where we found a very nice Thai restaurant) so time to update some of my work!

First off, my colleagues in Hannover published "Customized high performance low power processor for binaural speaker localization" at ICECS 2016 in Monte Carlo, Monaco (paper on IEEE Xplore), there was the Winter plenary of Hearing4all, and at DAGA 2017, I presented "Pitch features for low-complexity online speaker tracking", and Sarina (Ph.D. student I'm co-supervising) presented "A distance measure to combine monaural and binaural auditory cues for sound source segregation", both of which can be found on my homepage.  In the pipeline is now "Real-time Implementation of a GMM-based Binaural Localization Algorithm on a VLIW-SIMD Processor" by Christopher, which has been accepted and will be presented at ICME 2017 in Hong Kong in July, and I submitted a paper ("Segregation and Linking of Speech Glimpses in Multisource Scenarios on a Hearing Aid") to EUSIPCO 2017; that one is still in review.

I was also teaching a class in the past semester ("5.04.4223 Introduction into Music Information Retrieval") 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.

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.)

Friday, March 17, 2017

What 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 Atlassian in January.  It meant to inform me that the personal homepages on BitBucket 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.

I noticed this of course only when I suddenly couldn't access my homepage. D'Oh!

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!

Sunday, October 23, 2016

A (very) short trip to Korea

Panorama view from my room at the Nest Hotel in Incheon.  The Incheon Airport is visible on the right.
Earlier this month, I was in Incheon, South Korea, to present a talk at the Symposium for "Statistical physics, machine learning, and its application to speech and pattern recognition", organized by Prof. Kang-Hun Ahn as part of the Korea Institute for Advanced Study (KIAS).  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.

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.
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

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 MLSP 2016, 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.

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!)

Wednesday, September 14, 2016

MLSP2016 paper: Speaker Tracking for Hearing Aids

MLSP 2016 poster, the print version
can be found here.
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.
The beach of the conference venue,
with view towards Salerno.
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) on my homepage.
Overall, I like these small, highly focused conferences - and being in a nice sunny environment is not to be sneezed at either.