ARM MP3/AAC Player

Jump to: navigation, search
Player-TLV-Top.jpg

by Andreas Schwarz

Last update: 2007-04-12 (added IR remote control receiver)

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 the VS1001), but directly on the microcontroller. It can play MP3 (all bit rates) and AAC (up to ~256 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 processor is running at 54 MHz, generated with the PLL from a 12 MHz crystal.

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 (27 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).

The AAC decoder can handle AAC files in ADTS stream format (.aac) and MP4 container format (.mp4, .m4a).

The software can also play WAV files (16 bit signed, 44.1 kHz only).

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 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.

The 12 MHz clock from the CPU's crsytal is fed to the TLV's clock input via the programmable clock output of the AT91SAM7S256.

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), a RS232 connection and an IR remote control receiver (RC5). I am using a PNA4702M IR receiver connected to PA30.

Source Code

You can browse the source code of the project here.

To download the source code from the SVN repository 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://embdev.net/arm-mp3-aac-player/trunk/ arm_audio_player

Alternatively you can download a tar.gz snapshot of the repository here: http://embdev.net/svnbrowser/arm-mp3-aac-player/trunk/?view=tar

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.

Discussion in the German forum: