playmp3/playmp3.c

$Log$ Revision 1.5 2009/02/18 12:18:58 olereinhardt 2009-02-18 Ole Reinhardt <ole.reinhardt@thermotemp.de>

Fixed compilier warnings. Especialy signedness of char buffers as well as unused code on arm platform and main functions without return value

Revision 1.4 2006/08/31 19:14:44 haraldkipp Not all platforms do have devDebug0. Use board.h to determine the correct driver.

Revision 1.3 2006/07/21 09:06:36 haraldkipp Exclude AVR specific parts from building for other platforms. This does not imply, that all samples are working on all platforms.

Revision 1.2 2006/05/15 11:53:15 haraldkipp Now a buffer flush will completely transfer the MP3 file to the decoder.

Revision 1.1 2003/11/21 17:00:15 haraldkipp First release

To run this example code, you need to attach the Medianut Board to the Ethernut or use a similar hardware design based on the VS1001K MP3 decoder.

This sample application plays MP3 files from the UROM filesystem. It demonstrates how to use the global segmented buffer and the MP3 decoder driver and can provide a basis for talking equipment, alarm sound output etc.

The UROM filesystem is located in the CPU's flash ROM. No external file storage device is required. Use the crurom utility to create a C source file named urom.c from the MP3 files located in subdirectory sounds. Here's how to call crurom:

crurom -r -ourom.c sounds

The created file will then be compiled and linked to the application code.

UART0 is used for debug output.

00001 /*
00002  * Copyright (C) 2003-2006 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00059 #include <dev/board.h>
00060 #include <dev/vs1001k.h>
00061 #include <dev/debug.h>
00062 #include <dev/urom.h>
00063 
00064 #include <sys/version.h>
00065 #include <sys/heap.h>
00066 #include <sys/event.h>
00067 #include <sys/timer.h>
00068 #include <sys/thread.h>
00069 #include <sys/bankmem.h>
00070 
00071 #include <stdlib.h>
00072 #include <string.h>
00073 #include <stdio.h>
00074 #include <io.h>
00075 #include <fcntl.h>
00076 #include <errno.h>
00077 
00078 #if defined(__AVR__)
00079 static int PlayMp3File(char *path);
00080 #endif
00081 
00105 int main(void)
00106 {
00107     /* Baudrate for debug output. */
00108     u_long baud = 115200;
00109 
00110     /*
00111      * Register our devices.
00112      */
00113     NutRegisterDevice(&devUrom, 0, 0);
00114     NutRegisterDevice(&DEV_DEBUG, 0, 0);
00115 
00116     /*
00117      * Assign stdout to the debug device.
00118      */
00119     freopen(DEV_DEBUG_NAME, "w", stdout);
00120     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00121 
00122     /*
00123      * Print a banner.
00124      */
00125     printf("\n\nPlay MP3 files on Nut/OS %s\n", NutVersionString());
00126 
00127 #if defined(__AVR__)
00128 
00129     /*
00130      * Initialize the MP3 buffer. The NutSegBuf routines provide a global
00131      * system buffer, which works with banked and non-banked systems.
00132      */
00133     if (NutSegBufInit(8192) == 0) {
00134         puts("NutSegBufInit: Fatal error");
00135     }
00136 
00137     /* 
00138      * Initialize the MP3 decoder hardware.
00139      */
00140     if (VsPlayerInit() || VsPlayerReset(0)) {
00141         puts("VsPlayer: Fatal error");
00142     }
00143 
00144     /*
00145      * Play the MP3 files in an endless loop. For each file set the volume 
00146      * of the left and right channel, call the local routine PlayMp3File() 
00147      * and sleep one second before playing the next sound file.
00148      */
00149     for (;;) {
00150         VsSetVolume(0, 254);
00151         PlayMp3File("UROM:sound1a.mp3");
00152         NutSleep(1000);
00153 
00154         VsSetVolume(0, 0);
00155         PlayMp3File("UROM:sound2a.mp3");
00156         NutSleep(1000);
00157 
00158         VsSetVolume(254, 0);
00159         PlayMp3File("UROM:sound3a.mp3");
00160         NutSleep(1000);
00161 
00162         VsSetVolume(0, 0);
00163         PlayMp3File("UROM:sound4a.mp3");
00164         NutSleep(1000);
00165     }
00166 #else /* !__AVR__ */
00167     for (;;);
00168 #endif /* !__AVR__ */
00169     return 0;
00170 }
00171 
00172 #if defined(__AVR__)
00173 
00174 /*
00175  * Play MP3 file from local file system.
00176  *
00177  * \param path Pathname of the MP3 file to play.
00178  *
00179  * \return 0 on success, -1 if opening the file failed.
00180  */
00181 static int PlayMp3File(char *path)
00182 {
00183     int fd;
00184     size_t rbytes;
00185     char  *mp3buf;
00186     int    got;
00187     u_char ief;
00188 
00189     /*
00190      * Open the MP3 file.
00191      */
00192     printf("Play %s: ", path);
00193     if ((fd = _open(path, _O_RDONLY | _O_BINARY)) == -1) {
00194         printf("Error %d\n", errno);
00195         return -1;
00196     }
00197     puts("OK");
00198 
00199     /* 
00200      * Reset decoder buffer.
00201      */
00202     printf("[B.RST]");
00203     ief = VsPlayerInterrupts(0);
00204     NutSegBufReset();
00205     VsPlayerInterrupts(ief);
00206 
00207     for (;;) {
00208         /*
00209          * Query number of byte available in MP3 buffer.
00210          */
00211         ief = VsPlayerInterrupts(0);
00212         mp3buf = NutSegBufWriteRequest(&rbytes);
00213         VsPlayerInterrupts(ief);
00214 
00215         /* 
00216          * Read data directly into the MP3 buffer. 
00217          */
00218         if (rbytes) {
00219             printf("[B.RD%d]", rbytes);
00220             if ((got = _read(fd, mp3buf, rbytes)) > 0) {
00221                 printf("[B.CMT%d]", got);
00222                 ief = VsPlayerInterrupts(0);
00223                 mp3buf = NutSegBufWriteCommit(got);
00224                 VsPlayerInterrupts(ief);
00225             } else {
00226                 printf("[EOF]");
00227                 break;
00228             }
00229         }
00230 
00231         /*
00232          * If the player is not running, kick it.
00233          */
00234         if (VsGetStatus() != VS_STATUS_RUNNING) {
00235             printf("[P.KICK]");
00236             VsPlayerKick();
00237         }
00238 
00239         /*
00240          * Allow background threads to take over.
00241          */
00242         NutThreadYield();
00243     }
00244 
00245     _close(fd);
00246 
00247     /* 
00248      * Flush decoder and wait until finished. 
00249      */
00250     printf("[P.FLUSH]");
00251     VsPlayerFlush();
00252     while (VsGetStatus() != VS_STATUS_EMPTY) {
00253         NutSleep(1);
00254     }
00255 
00256     /*
00257      * Reset the decoder. 
00258      */
00259     printf("[P.RST]");
00260     VsPlayerReset(0);
00261 
00262     printf("\nDone, %u bytes free\n", NutHeapAvailable());
00263     return 0;
00264 }
00265 
00266 #endif /* !__AVR__ */

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/