ARM MP3/AAC Player

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

by Andreas Schwarz

This project is work in progress. Last change: 2006-06-04

Overview

This is my MP3/AAC player project. The difference to most other players is that decoding is not done on a specialized IC (like VS1001), but directly on the microcontroller. It can play MP3 (all bitrates up to 320 kbps) and AAC (up to ~200 kbps) from SD card in real time. The project is work in progress.

The CPU

The main processor is an ARM7TDMI-based AT91SAM7S256 microcontroller. This controller has 256 kB of Flash ROM, 64 kB of RAM, and various other features that are important for this project, most notably a serial interface capable of generating an I2S data stream and a DMA controller that allows fast transfer between memory and peripherals.

The development board is from Olimex and features an SD card socket, an USB connection, two push buttons and a small prototyping area, which makes it a nice development platform for an audio player.

Reading from the SD card

The SD card is connected to the SPI interface of the controller. The SPI is running at the maximum clock frequency (24 MHz) in order to get high read performance. The transfer from the card is done using DMA, not because the processor has to do other tasks while receiving, but because the manual fetch/store of the received bytes in a loop slows down the transfer.

I am using ChaN's Fat File System Module (http://elm-chan.org/fsw/ff/00index_e.html) for SD card access.

Reading one chunk of input data (between 1-2 kB) takes about 2 ms with this configuration.

Decoding MP3 and AAC

The most important part of the software is the MP3 and AAC decoder from the Helix Community. It is made available by Real under the RPSL open source license. You can browse the source code online (ViewCVS) or register to get CVS access.

Because code execution from Flash is rather slow on the AT91SAM7, I had to move some of the MP3 and AAC decoder functions to RAM to get sufficient performance. This is was done by adding the prefix <c>__attribute__ ((section (".data")))</c> to the function definition. With these optimizations decoding one frame takes between 16 ms (MP3, low bitrate) and 21 ms (AAC, high bitrate).

Unfortunately at the moment the AAC decoder can only handle AAC files in ADTS stream format (usually called .aac, can be generated e.g. with FAAC). If you know how to decode the MP4 container format found in .MP4 and .M4A files, please tell me!

The software can also play WAV files (16 bit signed). A central limitation for all audio formats is that only 44.1 kHz stereo is supported right now.

The DAC - First Version: CS4331

First Prototype. The left board is only used because it happens to have a CS4331 on it.

For the first version I have been using a CS4331 DAC. It is very nice for experiments because it is 3.3V compatible, available in a SOIC 8 package, and does not require any configuration. My DAC is mounted on an old MP3 player and connected to the SAM7 dev board with a few wires (by the way, the 12 MHz MCLK signal looks really bad after the 15 cm wire).

The CS4331's I2S interface has one big disadvantage that it shares with the majority of all audio DACs: it requires a fixed ratio between the sample rate and the processor's main clock. If the AT91SAM7 is running with the USB-compatible 48 MHz clock, it is not possible to generate an I2S data stream with the usual 44.1 kHz sample rate. The closest is 46.9 kHz, so everything is played a few percent too fast. It sounds bad, but is OK for testing.

CS4331 Connection

The DAC is connected to the SSC peripheral. The SSC is configured to output a I2S stream with a sample rate of 46.9 kHz (see above), two 16 bit words per sample rate interval (one for each channel). The transfer has to run continuously in the background, and in order to relieve the CPU from this boring and time consuming task DMA is used to feed the raw data from a memory buffer to the SSC.

The DAC - Second Version: TLV320AIC23B

TLV320AIC23B Schematic

For the second version I have replaced the CS4331 with a TLV320AIC23B. When used in Master Mode, this Codec can generate pretty exact 44.1 kHz and 48 kHz sample rates from its own 12 MHz main clock, and feed it to the processor's SSC. It doesn't matter what frequency the CPU is running with. Furthermore it comes with a headphone amplifier, a stereo line input, and a microphone amplifier. It will therefore be possible to extend the player with recording capabilities.

The TLV320AIC23B can be configured over a TWI and SPI interface. I chose TWI, because SPI is already used for the SD card with a high clock frequency, and routing that signal to the DAC didn't seem to be a good idea.

Player-TLV-Top.jpg
Player-TLV-Bottom.jpg


User Interface

At the moment the user interface consists of only two push buttons (start/pause and next) and a RS232 connection. I am not yet sure what kind of display to use for the player. Probably a nice OLED display, but most displays I found were either stamp-sized or didn't have a serial interface. I still have a few boring 2x16 character LCDs lying around, maybe I will just use one of these for now.

Source Code

You can browse the current source code of the project here.

To download the complete source code you need a SVN client. If you have the command line SVN client enter this to fetch the source into the directory "arm_audio_player":

 svn co svn://mikrocontroller.net/mp3dec/trunk/ arm_audio_player

The build requires an arm-elf-gcc compiler toolchain with Newlib. If you are using Windows I recommend WinARM, for Linux and Mac OS X you can get a complete toolchain here.

Questions? Comments?

Please post in this forum. You might also want to try the chat room; my nick is "andreas".