blog dds

2009.07.13

Madplay on an Intel Mac

Numerous MP3 players around my house pull music from a central file server. The hardware I'm using is extremely diverse and many devices can nowadays be politely described as junk: they include 100MHz Pentiums with 16MB RAM, and an ARM-based prototype lacking support for floating point operations. For the sake of simplicity I've standardized the setups around a web server running on each machine to list static HTML pages containing the available music files, and simple shell-based CGI clients that invoke madplay to play the music. When I added an Intel-based Mac to the mix I found that madplay refused to work, producing only a white noise hiss.

Initially I had cross-compiled madplay from source on a PowerPC machine as a Mach-O fat binary running on both Intel and PowerPC architectures. For this I configured the software using commands like the following.

CFLAGS='-arch i386 -arch ppc' ./configure -disable-dependency-tracking'
Reasoning that this complex configuration was the problem's cause I installed Apple's development tools on the Intel Mac and compiled an Intel-specific binary. This didn't solve the problem. I then thought that somebody else would have solved the problem, so I installed MacPorts and its version of madplay. The problem persisted.

At that point I abandoned madplay and decided to try my luck with VLC. This however proved unwieldy for my purposes. Controlling it from CGI shell scripts required opening a Unix-domain socket, and, according to dtruss, it seemed to ignore the no-auto-preparse and no-mmap command-line options somehow bringing my (severely underpowered) NFS server to its knees by issuing many erroneous NFS requests. I thought I could dig into this problem and fix it, but the source code of VLC brought tears to my eyes, so I decided to abandon that avenue.

After a night's sleep I got up convinced that madplay's white noise was a simple endianess problem, which I could easily solve. A simple grep for the word endian in the source code showed me that there were corresponding preprocessor conditionals, like the following

# if defined(WORDS_BIGENDIAN)
in most audio files, but not in audio_carbon.c; the code seemed to assume that a Mac had a big-endian PowerPC architecture. Bingo!

Fixing the problem was trivial. Here is the corresponding patch.

diff -u -r1.1 audio_carbon.c
--- audio_carbon.c      2009/07/13 06:57:51     1.1
+++ audio_carbon.c      2009/07/13 06:58:57
@@ -234,7 +234,11 @@
     break;

   case 16:
+# if defined(WORDS_BIGENDIAN)
     audio_pcm = audio_pcm_s16be;
+# else
+    audio_pcm = audio_pcm_s16le;
+# endif
     break;
   }

Read and post comments, or share through   


Creative Commons License Last modified: Monday, July 13, 2009 11:46 am
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.