Flash MP3 Player

From NutWiki

Jump to: navigation, search

Contents

Description

This is a simple MP3 player. It plays an MP3 from Flash. You'll need a data directory in your project directory containing your "example.mp3" file. Also make sure your binary with the included doesn't get larger than your board's Flash.

Source Code

#include <dev/board.h>
#include <dev/vscodec.h>
#include <dev/urom.h>
#include <fs/uromfs.h>
 
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <dirent.h>
 
#include "urom_data.c"
 
static char buff[512];
 
int main(void) {
    int fh;
    int decoder;
    int n;
 
 
    /* register debug device */
    u_long baud = 115200;
 
 
    NutRegisterDevice(&DEV_DEBUG, 0, 0);
    freopen(DEV_DEBUG_NAME, "w", stdout);
    _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
 
    /* NOTE: This assumes the hardware codec is present */
 
    if (NutRegisterSpiDevice(&devSpiVsCodec0, &DEV_SPIBUS, 1)) {
        puts("Codec unavailable.\n");
    }
 
    /* Register UROM device */
 
    if (NutRegisterDevice(&devUrom, 0, 0)) {
        printf("UROM error\n");
    }	
 
    decoder = _open("audio0", _O_WRONLY | _O_BINARY);
    fh = _open("UROM:example.mp3", _O_RDONLY | _O_BINARY);
 
    for (;;) {	
        n = _read(fh, buff, 512);
	if (n <= 0) {
	    break;
	}
	_write(decoder, buff, n);
	_write(decoder, NULL, 0);
    }
 
    _close(decoder);
    _close(fh);
 
    for (;;);	
}

Makefile

Here's the Makefile to build the MP3 player. Note, that all leading spaces have to be tabs instead of spaces. Change the PROJ variable to match the name of your main .c file.

PROJ = mp3_example
DATADIR = data
DATAFILE = urom_data.c
 
include ../Makedefs
 
SRCS =  $(PROJ).c
OBJS =  $(SRCS:.c=.o)
LIBS =  $(LIBDIR)/nutinit.o -lnutpro -lnutos -lnutnet -lnutfs -lnutcrt -lnutdev -lnutarch
TARG =  $(PROJ).hex
 
all: $(DATAFILE) $(OBJS) $(TARG) $(ITARG) $(DTARG)
 
$(DATAFILE): $(DATADIR)/example.mp3
	$(CRUROM) -r -o$(DATAFILE) $(DATADIR)
 
include ../Makerules
 
clean:
	-rm -f $(OBJS)
	-rm -f $(TARG) $(ITARG) $(DTARG)
	-rm -f $(DATAFILE)

Description

u_long baud = 115200;	
 
NutRegisterDevice(&DEV_DEBUG, 0, 0);
freopen(DEV_DEBUG_NAME, "w", stdout);
_ioctl(_fileno(stdout), UART_SETSPEED, &baud);

Set up the debug device so we can output to the terminal.

/* NOTE: This assumes the hardware codec is present */
 
if (NutRegisterSpiDevice(&devSpiVsCodec0, &DEV_SPIBUS, 1)) {
    puts("Codec unavailable.\n");
}

This line registers the VS Codec. Note that we don't use the normal NutRegisterDevice here. Since the VS Codec is a device on the SPI bus, we have to register it using NutRegisterSpiDevice. The parameter DEV_SPIBUS passes the bus we want to register it to.

/* Register UROM device */
 
if (NutRegisterDevice(&devUrom, 0, 0)) {
    printf("UROM error\n");
}

Now we register the uROM device. For more information on uROM access see the Reading UROM Files article.

decoder = _open("audio0", _O_WRONLY | _O_BINARY);
fh = _open("UROM:example.mp3", _O_RDONLY | _O_BINARY);

For the MP3 Codec to play, we need to pass data directly to it. To achieve this, we open both the decoder (audio0) and the mp3 file we want to use (example.mp3) via the open command. This is a lower level command than fopen and does not return a file pointer but a handle of type integer.

for (;;) {	
    n = _read(fh, buff, 512);
    if (n <= 0) {
        break;
    }
    _write(decoder, buff, n);
    _write(decoder, NULL, 0);
}

This loop does the actual MP3 playing. It first reads 512 bytes from the MP3 file and stores the number of bytes read in n.

Before writing the data the decoder, we have to make sure there is actually data left for writing. We do this by checking n (the number of bytes read) for a size <= 0. If it is, we have no more data left to write and can safely exit the play loop.

If there's data left to write, we write it to the decoder.

The line "_write(decoder, NULL, 0);" is something special. Usually all data transfers are buffered, sometimes resulting in data that is not yet written when the _write command returns control to your program. By writing a NULL pointer to the audio device, we instruct Nut/OS to flush all data to the decoder. Do NOT use this elsewhere as this is a special trick of Nut/OS and will result in bugs and crashes if used anywhere else.

_close(decoder);
_close(fh);

We're done playing, now close our open files.

See also

External Links

  • C file input/output The C programming language provides many standard library functions for file input and output.
  • MP3 MPEG-1 Audio Layer 3, more commonly referred to as MP3, is a digital audio encoding format using a form of lossy data compression.


Personal tools