Dan Ellis : Resources : Matlab :

mp3read and mp3write for Matlab

Introduction

These are a couple of m-files I wrote to read and write mp3 audio files (i.e. files compressed using MPEG-Audio layer 3 encoding) under Matlab.

mp3read

The mp3read script started out little, but has now become somewhat larger. Rather than actually decoding the mp3 stream, it cheats by calling an external mp3 decoder program to convert the file to wav, then reading in that temporary file. But it does do some tricks like only decompressing the part of the file that is required rather than the whole thing; this can be useful for accessing very large mp3 files.

Although it's called mp3read, it will, in fact, read any MPEG Audio file recognized by the underlying Unix utilities (i.e. MPEG-1 Audio layers 1, 2, and 3). It does not recognize MPEG-4 audio files (*.m4a etc.) but you can convert these to mp3 with mplayer and lame e.g.


  mplayer file.m4a -ao pcm:file=file.wav
  lame -h -b 128 file.wav file.mp3
  rm file.wav

The syntax of mp3read() attempts to duplicate wavread() as closely as possible, including trying to duplicate the OPTS.fmt fields and the 'size' syntax etc. Because mpg123 supports on-the-fly downsampling by 2 or 4, and conversion to mono, these are supported as options beyond the first two arguments.

I recently noticed that mp3read followed by mp3write followed by mp3read effectively delayed the waveform by 2257 samples (at 44 kHz). So I introduced code to discard the first 2257 samples; now that loop results in waveforms that are time aligned. However, it does add extra samples on to the end every time (when it rounds out to an even number of blocks), so if you want to keep your data the same length, you should truncate when you read back, e.g.


 >> mp3write(d,sr,'tmp.mp3');
 >> d1 = mp3read('tmp.mp3',length(d));
You can suppress this delay-chopping by specifying 0 (or however many samples you want to discard) as a 5th argument to mp3read.

Here is the function: mp3read.m Note that it won't work unless you also have the mpg123 and mp3info binaries; see "External Commands" below.

Here are some examples of use:

mp3write

Since mp3read seemed useful, I decided to write a complementary mp3write. This uses the same dodge of calling an external program (lame) to do the actual encoding. Under Unix, it actually uses my popen mex extension to write it a bit at a time; if popen is not available (e.g. Windows), it just writes a temporary uncompressed wav file, then executes the lame compressor on that.

Here is the function: mp3write.m Note that it won't work unless you also have the lame binary; see "External Commands" below. It will also work without using a large temporary file if you can install the popenw mex extension.

Usage is analogous to wavwrite i.e. mp3write(data, srate, filename[, opts]). If opts is specified, it gives extra command line options for lame (e.g. to control the compressed bitrate). The default opts are "--quiet -h".

External commands

The functions actually use some freely-available Unix utilities. As such, they work principally on Unix versions of Matlab (e.g. Linux and Mac OS X). However, these utilities have been ported to Windows, so you should be able to get them to work there also (more details at the bottom of the page).

Specifically, for mp3read you need the mpg123 decoder (note: mpg321 is not an adequate substitute, because it lacks certain options), and the mp3info scanner. You can find them here:

Using under Windows

As mentioned above, the mp3read Matlab function depends on two external programs, mpg123 and mp3info, which were originally developed for Linux. To make the script work on a Windows system, you need versions of these programs that work on that architecture, which we provide here for your convenience:

To make them work, you also need to make small changes to the mp3read.m and mp3write.m scripts. First, you must change the location that the script looks for binaries e.g. change the lines:

    %%%%%% Location of the binaries
    mpg123 = '/usr/bin/mpg123';             % for mp3read
    mp3info = '/usr/bin/mp3info';           % for mp3read
    lame = '/usr/bin/lame';                 % for mp3write

to point to the directory where you put the binaries above, e.g.

    mpg123 = 'C:\Matlab6p5\work\project\mpg123.exe';
    mp3info = 'C:\Matlab6p5\work\project\mp3info.exe';
    lame = 'C:\Matlab6p5\work\project\lame.exe';

Secondly, you must also change the directory where temporary files are written, and the command used to delete them, e.g.:

    %%%%%% Directory for temporary file (if needed)
    tmpdir = '/tmp/';
    %%%%%% Command to delete temporary file (if needed)
    rmcmd = 'rm';

.. to be a suitable directory for temporary files on your system and the appropriate command to delete them, e.g.

    tmpdir = 'C:\Matlab6p5\work\project\tmp\';  % don't forget trailing slash
    rmcmd = 'del';

Thanks to Keansub Lee and Meredith Morris for their help.


Last updated: $Date: 2007/07/24 00:56:26 $

Dan Ellis <dpwe@ee.columbia.edu>