Difference between revisions of "MMC MP3 Player"
m (→Playing a file) |
m (1 revision imported) |
(No difference)
| |
Latest revision as of 16:02, 27 October 2016
Contents
Test Environments
| Hardware Comments |
Nut/OS 4.7.4 |
Nut/OS 4.8.0 | |
| Ethernut 3.0 E | requires Medianut | Compiler Error | NT |
| EIR 1.0 C | OK Binaries |
||
| AT91SAM7X-EK | requires Calypso | NT | NT |
| AT91SAM9260-EK | requires Calypso | NT | NT |
| Compiler: ARM-GCC 4.2.2 | |||
Description
This is a simple MP3 player. It scans a MultiMedia Card for files with extension .mp3 and sends the contents to an MP3 decoder.
Source Code
This code requires Nut/OS 4.8 or later. Check the page's history (Nov 2008) for previous versions.
Main routine
The main program does some initialization and then enters an endless loop, reading the MMC.
<source lang="c">
- include <cfg/os.h>
- include <fs/phatfs.h>
- include <sys/timer.h>
- include <dev/board.h>
- include <cfg/arch/gpio.h>
- include <cfg/audio.h>
- include <string.h>
- include <stdlib.h>
- include <stdio.h>
- include <fcntl.h>
- include <io.h>
- include <dirent.h>
- define VERSION "1.4.1"
- if defined(AT91SAM7X_EK) || defined(AT91SAM9260_EK)
- include <dev/hxcodec.h>
- else
- define CS_HARDWARE_CODEC 1
- include <dev/vscodec.h>
- endif
static int ScanFolder(char *root); static int PlayFile(int fd);
int main(void) {
u_long baud = 115200;
int volid;
NutRegisterDevice(&DEV_DEBUG, 0, 0);
freopen(DEV_DEBUG_NAME, "w", stdout);
_ioctl(_fileno(stdout), UART_SETSPEED, &baud);
puts("\nNut/OS MMC MP3 Player " VERSION);
- ifdef CS_HARDWARE_CODEC
NutRegisterSpiDevice(&devSpiVsCodec0, &DEV_SPIBUS, CS_HARDWARE_CODEC);
- else
NutRegisterDevice(&devHelixCodec, 0, 0);
- endif
NutRegisterDevice(&devPhat0, 0, 0);
NutRegisterDevice(&DEV_MMCARD, 0, 0);
for (;;) {
for (;;) {
printf("Card...");
if ((volid = _open(DEV_MMCARD_NAME ":1/PHAT0", _O_RDWR | _O_BINARY)) != -1) {
puts("ready");
break;
}
puts("not found");
NutSleep(2000);
}
ScanFolder("PHAT0:/");
_close(volid);
}
return 0;
} </source>
At the top all required header files are included.
The MP3 Player can either use a hardware decoder chip or do decoding by software.
Scanning a folder
The following routine scans a specified folder for MP3 files.
<source lang="c"> static int ScanFolder(char *root) {
int rc = 0;
DIR *dir;
int fd;
char *path;
printf("Scanning %s\n", root);
dir = opendir(root);
if(dir) {
struct dirent *dep;
path = malloc(256);
while(rc == 0 && (dep = readdir(dir)) != NULL) {
if (strcmp(dep->d_name, ".") && strcmp(dep->d_name, "..")) {
if (dep->d_type) {
strcpy(path, root);
strcat(path, dep->d_name);
strcat(path, "/");
rc = ScanFolder(path);
} else {
char *cp = strrchr(dep->d_name, '.');
if (cp && stricmp(cp, ".mp3") == 0) {
strcpy(path, root);
strcat(path, dep->d_name);
sprintf(path, "%s%s", root, dep->d_name);
printf("Playing %s\n", path);
fd = _open(path, _O_RDONLY | _O_BINARY);
if (fd == -1) {
rc = -1;
} else {
rc = PlayFile(fd);
_close(fd);
}
}
}
}
}
closedir(dir);
free(path);
}
return rc;
} </source>
Playing a file
The routine PlayFile expects a file handle of an opened MP3 file and streams its contents to the audio decoder driver.
<source lang="c"> static int PlayFile(int fd) {
int codec;
uint8_t *mp3buff;
codec = _open("audio0", _O_WRONLY | _O_BINARY);
if (codec == -1) {
printf("No codec\n");
return -1;
}
mp3buff = malloc(512);
for (;;) {
int got;
uint8_t *bp;
bp = mp3buff;
got = _read(fd, bp, 512);
if (got <= 0) {
break;
}
while (got) {
int sent;
sent = _write(codec, bp, got);
if (sent < 0) {
break;
}
if (sent == 0) {
NutSleep(1);
} else {
got -= sent;
bp += sent;
}
}
}
free(mp3buff);
_close(codec);
return 0;
} </source>
Makefile
Here's the Makefile to build the MP3 player.
Note, that the spaces before -rm -f $... have to be tabs instead of spaces.
<source lang="text"> PROJ = cs_mp3mmc
include ../Makedefs
SRCS = $(PROJ).c OBJS = $(SRCS:.c=.o) LIBS = $(LIBDIR)/nutinit.o -lnutfs -lnutos -lnutcrt -lnutdev -lnutarch -lnutcontrib TARG = $(PROJ).hex
all: $(OBJS) $(TARG) $(ITARG) $(DTARG)
include ../Makerules
clean:
-rm -f $(OBJS)
-rm -f $(TARG) $(ITARG) $(DTARG)
-rm -f $(PROJ).obj
-rm -f $(PROJ).map
-rm -f $(SRCS:.c=.lst)
</source>
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.