Bembel-B Blog


Prevent Debian on Linksys NSLU2 Going Out of Memory

After switching from Unslung to Debian I constantly got various programs (mt-daapd, rtorrent, gcc) terminating, because they ran out of memory. Tweaking or even disabling the oom-killer kernel feature didn’t do the trick, so I took a look at the ulimits and found most of them set to unlimited. Setting some of the ulimit defaults like on Ubuntu Linux solved these problems.
Linksys NSLU2


Thanks to Michael the solution to any oom problem is upgrading to Debian Unstable (aka. Lenny). My “solution” didn’t proof. See the comments for more detail.

After some experimenting, I now have two ulimit settings – stack size and max locked memory – pointed out, but am not sure if really both are mandatory. But it shouldn’t hurt either. These limits, being unlimited by default, now got set to sane values as follows.

You can set the ulimits for the current shell with ulimit -l 32 -s 8192. System wide defaults are defined in /etc/security/limits.conf e.g. by adding this:

#restrictions to avoid oom using ubuntu defaults
*       hard    memlock 32
*       hard    stack   8192

As mentioned before, I currently have oom-killer disabled. But I should try to enable it again, to benefit from this feature. This can be done with the sysctl tool and in the /etc/sysctl.conf file.

While I’m at it, that would be the output of the stock Debian settings:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
max nice                        (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) unlimited
max rt priority                 (-r) 0
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

That’s the output for Ubuntu Gutsy:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 8191
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 8191
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


[2008-04-11: Better upgrade to Lenny.]


Fixed-point Ogg Vorbis and Musepack Decoder Packages for Debian Etch ARM

I’m using Firefly Media Server on a Linksys NSLU2 running Debian Etch to stream my whole music collection to my Pinnacle SoundBridge HomeMusic. Many files in my collection are in Ogg Vorbis format and a few in Musepack too, which unfortunately aren’t natively supported by the SoundBridge. Luckily Firefly can transcode audio files on the fly e.g. using the ssc plug-in and any console application via shell scripts. But the problem with the Debian packages is that they don’t take into account the missing floating point unit (FPU) of the NSLU2 hardware, and that makes oggdec/ogg123 and mpc123 take ages – way below real-time – to transcode. Fixed point versions of the transcoders aren’t available in the Debian Etch package repositories even the sourcecode already exists, so I had to build them myself.
Linksys NSLU2
I first searched the Debian packages for fixed point versions.
I found the libvorbisidec package, which is the fixed point version of libvorbis also going by the name Tremor. The vorbis-tools is only available as normal floating-point version linked to libvorbisdec. For Musepack there are (floating-point) packages libmpcdec3 for the library and mpc123 for the application.
In the Firefly forums I found patches for vorbis-tools (providing the ogg123 and oggdec transcoders), so that I could build Tremor versions of the transcoder apps.
In the Musepack sources there’s already a define variable to build with fixed point math only. So I would just have to enable that and rebuild the library and transcoder.

To make a long story short, here are the Debian Etch ARM binary packages for fixed-point Ogg Vorbis and Musepack:

I will gladly provide the sources. Feel free to ask for them! You can download the Deb sources for libmpcdec and vorbis-tools further below.


These are the integer Lenny ARM binaries. Libvorbisidec is available through the official repos.:

Update 2

Here are the Deb sources (.dsc, .diff.gz and .orig.tar.gz) to build your own binary Deb packages.

Performance now is very good on my 266 MHz NSLU2. From what I’ve seen in top, mpc123 and ogg123 stay below 50% CPU usage and decoding is done faster than real-time.

Only to show off how unbelievably cool I am ;), and in case somebody would like to reproduce these builds on another distribution, I’ll roughly describe the steps I’ve taken.

Build libvorbisidec

Pretty straight forward. As far as I remember I only had to rebuild the source package:

mkdir -p ~/debuild/libvorbisdec
cd ~/debuild/libvorbisdec
dget -x
cd libvorbisidec-1.0.2
debuild -rfakeroot -uc -us
cd ..
sudo dpkg -i libvorbisidec1_1.0.2+svn14261-1_arm.deb libvorbisidec-dev_1.0.2+svn14261-1_arm.deb

Patch and build vorbis-tools

This one was trickier. The patches found on the forum aren’t complete. The older one is blindly changing the endianess of the resulting audio data, thereby producing only noise on the little endian Debian I use. The newer one misses linking mpcdec to libvorbisidec.

mkdir -p ~/debuild/vorbis-tools
cd ~/debuild/vorbis-tools
dget -x
cp -pr vorbis-tools_1.1.1 vorbis-tools_1.1.1.wrk
cd vorbis-tools_1.1.1.wrk
[apply and manually fix the tremor patch]
[create tremor patch file against vorbis-tools_1.1.1/]
[copy patch file to vorbis-tools_1.1.1/debian/patches]
[add patch file at bottom of vorbis-tools_1.1.1/debian/patches/series]
[add libvorbisidec-dev dependency to vorbis-tools_1.1.1/debian/control and document Tremor versions in description]
[increase version and add changes in changelog via dch -i]
cd vorbis-tools_1.1.1
debuild -rfakeroot -uc -us
cd ..
dpkg -i vorbis-tools_1.1.1-7_arm.deb

Patch and build libmpcdec

Here I add a patch to enable the fixed-point define. Beware, the following steps are just written down from memory in a hurry. So expect flaws. :)

mkdir -p ~/debuild/libmpcdec
cd ~/debuild/libmpcdec
dget -x
cp -pr libmpcdec-1.2.2 libmpcdec-1.2.2.wrk
vim libmpcdec-1.2.2.wrk/include/mpcdec/math.h
[uncomment #define MPC_FIXED_POINT]
mkdir libmpcdec-1.2.2.wrk/debian/patches
diff -Naur libmpcdec-1.2.2 libmpcdec-1.2.2.wrk > libmpcdec-1.2.2.wrk/debian/patches/enable_fixed_point.diff
cd libmpcdec-1.2.2.wrk
dch -i
[increases version in changelog. add some notes.]
debuild -rfakeroot -uc -us
cd ..
dpkg -i libmpcdec3_1.2.2-2_arm.deb libmpcdec-dev_1.2.2-2_arm.deb

Build mpc123

This one has only to be rebuilt with the fixed-point libmpcdec version above installed.

mkdir -p ~/debuild/mpc123
cd ~/debuild/mpc123
dget -x
cd mpc123-0.2.2
debuild -rfakeroot -uc -us
cd ..
dpkg -i mpc123_0.2.2-1_arm.deb

I haven’t found a fast enough way to transcode Monkey’s Audio (aka. APE) files yet, but that’s mainly because I don’t have any (which haven’t been transcoded to mp3 by myself already). For your information: Building the Monkey’s Audio Codec (MAC) for Linux did work.
I think when looking for more low resource or fixed-point codecs, a good place to look for is the Rockbox Wiki. That’s what I used too.

To make this Firefly Transcoding post more complete, here’s my current version of the ssc script:

# script to facilitate server-side transcoding of ogg files
# Usage:   
# You may need to fix these paths:


ape_file() {

ffmpeg_file() {
    $FFMPEG -i "$FILE" -acodec pcm_s16le -f wav - | $WAVSTREAMER -o $OFFSET $FORGELEN

mpc_file() {
    $MPC --quiet --wav - "$FILE" | $WAVSTREAMER -o $OFFSET $FORGELEN

ogg_file() {
    $OGG123 -q -d wav -f - "$FILE" | $WAVSTREAMER -o $OFFSET $FORGELEN

flac_file() {
    $FLAC --silent --decode --stdout "$FILE" | $WAVSTREAMER -o $OFFSET $FORGELEN


# this is nonsense!
if [ "$3" != "" ]; then
  FORGELEN="-l ${3%.*}"

case "$1" in
# here you could cat a generic "error" wav...
# cat /path/to/error.wav

Oh, FYI I’m using mt-daapd 0.2.4+r1376-1 from the Debian repo. I got the wavstreamer binary and the ssc script example by extracting them from a newer Debian package. The Firefly Wiki provides more information on transcoding implementation.


[2008-04-11: Add Lenny Debs.]
[2008-06-06: Add Deb sources for libmpcdec and vorbis-tools.]
[2009-04-26: Fix links.]


Scrobbling Everywhere All the Time

I must confess I’ve become quite a fanboy. :) So what would be more important than keeping track of as much music playing as possible. Scrobbling the plays of my PC audioplayer Amarok and Foobar2000 ain’t that spectacular, but feeding statistics of my mobile MP3 Player SanDisk Sansa e200 and my stand-alone player Pinnacle SoundBridge HomeMusic (licensed by Roku) I consider being more of that Social Music Revolution

Scrobbling Sansa e200 with Rockbox

Precondition is using the great alternative Firmware Rockbox. It already has the Audioscrobbler logging built in. To submit the logs I use the PC application QTScrobbler under Linux (and occasionally Windows). That’s very easy and convenient. Just be sure to set your Sansa’s clock somewhat correct.

Scrobbling SoundBridge with Firefly Mediaserver

To gain access to my whole music collection without having a PC running, I’m using the fine Linksys NSLU2 NAS running the Firefly Mediaserver (aka. mt-daapd) with a cheapo 160 GB USB HDD (Storage) and a 2 GB USB Flash Drive (OS) attached. I’ve had a working setup using the alternative NSLU2 firmware Unslung, but soon switched to Debian ARM, for its greater versatility and more straight forward configuration.

I’ll write more detailed posts on the NSLU2 soon, especially regarding Firefly and fixed-point Transcoding and Radio. But for now a quick overview on the setup, which should be possible on other platforms and for any streaming client too.

I obtained the Firefly Mediaserver prebuilt from the Firefly website. Installation is quite easy and well documented.

Submission to is done by the Python application Lastfmsubmitd. As the name suggests it’s a daemon permanently waiting for data to be submitted. That data is gathered from text files placed e.g. in /var/spool/lastfm. Under Unslung I had to manually install it from source (python install), and for Debian it’s in the apt repo (but I built a deb package of the recent version found in Debian unstable).

Creating the data files is done periodically by a shell script based on what I found in the Firefly Forum. It’s run every 5 minutes by cron and queries the “last played field” of Firefly’s collection database and outputs results to Lastfmsubmitd’s spool directory.
That’s my current shell script (converting GMT+1 timestamps to UTC by substracting 3600 seconds):


# fetch newly played songs from fireflydb and write
# into lastfmsubmitd readable format

# config

# get last run time
if [ -e "$LASTFILE" ]

# get last database file date
if [ -e "$DBLSFILE" ]

# exit when database file unchanged
if [ "$DBLSRUN" == "$DBLSNOW" ]

# log file date

# query database
OUTFILE=$(mktemp "$TMPDIR"/mt-daapd-XXXXXXXX)
"$SQLITE" "$DATABASE" 'SELECT artist,album,title,track,song_length,time_played FROM songs where time_played > '"$LASTRUN"' ORDER BY time_played ASC;' | gawk -F '|' '{ printf "---\nartist: \"%s\"\nalbum: \"%s\"\ntitle: \"%s\"\ntrack: %s\nlength: %d\ntime: !timestamp %s\n",$1,$2,$3,$4,$5/1000,strftime("%Y-%m-%d %T",$6-3600) }' > "$OUTFILE"

# place non-zero result into spool, else drop file
if [ -s "$OUTFILE" ]
  chmod 664 "$OUTFILE"
  rm "$OUTFILE"

# log query date
echo "LASTRUN="`date +%s` > "$LASTFILE"

Downside of this solution is, Firefly will only consider a track as played, if it has been completely and continuously been played. So skipping or pausing a track will cause it to not be submitted.
Also there’s no separation between Podcasts and the rest of my music collection. What I haven’t tried yet, is the behaviour when playing web radio via Firefly playlists, as I do all radio streaming directly through the SoundBridge user interface.
To iron out the downsides using the same approach, the first one would need changes to the Firefly code I guess, the others could probably be fixed modifying the shell script.

Blog at