Audio Compression Schemes

A project log for Radio-to-Internet Streamer

This project adapts a AM/FM radio receiver to a private Internet stream. It also provides various TiVo-esque features.

ziggurat29ziggurat29 08/26/2017 at 17:020 Comments


Today I managed to get the basic build system working for the STM32F405 board that I am going (try to) use for the first prototype.

I reviewed some audio compression technologies, and am either going to do MP3 or Vorbis.  I found a fixed-point implementation of MP3 (a library named 'shine'), but I am going to try my hand at Vorbis first, since it's legally unencumbered.  Another candidate at some point might be AAC.


My first step in any project is to bring up the tool chain.  Since I am currently going to try to use an STM32F405 (in this particular case, re-purposing an old Netduino Plus 2 board), I already have a build system with the 'System Workbench' and STM32CubeMX tools installed (in turn, gcc, libnano, gdb, and openocd).  I had a bit of trouble for a while until it occurred to me that my debugging pod is an 'SL-Link v2' (and specifically NOT a v2.1).  The salient difference has to do with reset, and apparently the v2 does not do hardware reset, so you need to select 'software reset'.  Failing to do this causes all sorts of complaints about the board not being halted, and whatnot.  For the curious, the 'software reset' is a command send over the SWD connector, whereas 'hardware reset' is -- you guessed it -- pulling the /RESET line low.  You only need 'hardware reset' in the cases where the firmware changes the SWD pins to some other IO function, which is not applicable in this case because those lines are simply brought out to the debugging connector.

Having successfully made a 'blinky' and being able to debug and step it was time to move one.  Actually, there was one little detour I should mention for posterity -- along the way I found out about a thing called 'semi hosting'.  SWD has an optional trace feature that can be used to send log-like information to your debugging terminal.  As you might imagine, things like 'sprintf' to format such data can take a toll on a firmware image, so someone came up with 'semi hosting' which sends the parameter data, and relies upon the host to do the formatting.  Nifty!  The way it works is you link to a library and make a special call, and then you 'printf' gets redirected to the semi hosting host.  I went through all these motions, but all I got was hard faults as soon as I tried to do a 'printf', and I didn't see the source to the 'librdimon' so I decided to punt on that.  I've got interactive stepping, and that's enough for now.  The topic is interesting, though, so I'll come back to it at a later time.

Further things I need to do for this board are support the SD card and the Ethernet socket.  This means writing some board-specific drivers for the FatFS and lwip libraries, but this should be straightforward.  More pressing was seeing if I can even get the libvorbis in the flash itself.  If I can't get that working, who cares about Ethernet and SD.

The libvorbis code is a reference implementation.  First, I tried compiling it in Visual Studio Community 2017.  This was more-or-less straightforward (some project file tweaks, since there wasn't a configuration for 2017, and for include paths, etc.).  The sample encoder was also trivially modified since it had a naive WAV reader that further assumed the sampling rate of 44.1 ksps, and I'm probably going to be using 32 ksps (the radio chip can output at that sample rate, and it's the lowest it supports.)  I found a song that is in FLAC format for a source, decompressed it to WAV, and converted the sample rate to 32 ksps.  I compressed it with the sample encoder and it sounds fine.  I'm still very concerned about processing speed and also RAM footprint.  In optimised release build, it took about 11 sec to compress a 5:22 song, but that's on my 2.8 GHz desktop computer.  How will the little 168 MHz STM32F processor fare?  (*gulp*)  Also, this reference code uses double all over the place, and the STM32F only has a single-precision FPU.  There is going to have to be plenty of surgery for that.  And heaven only knows about RAM usage -- there's only 128+64 kib on the chip.

So, next steps are to move the source code into the STM32F project, and see if I can even compile it, and if so, see how big the firmware image gets.  Then a lot of surgery and profiling, I'm sure.


For my next amazing feat, I will attempt to integrate the libvorbis code into the System Workbench project I have set up, and see if there is early bad news.  Fail fast!

Also, I need to figure out a clever project picture.  I don't have anything interesting yet to photograph, it's all just code and a hopeful dev board.  Maybe a system diagram will work.