playmp3.c

Go to the documentation of this file.
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 
00052 #include <dev/board.h>
00053 #include <dev/vs1001k.h>
00054 #include <dev/debug.h>
00055 #include <dev/urom.h>
00056 
00057 #include <sys/version.h>
00058 #include <sys/heap.h>
00059 #include <sys/event.h>
00060 #include <sys/timer.h>
00061 #include <sys/thread.h>
00062 #include <sys/bankmem.h>
00063 
00064 #include <stdlib.h>
00065 #include <string.h>
00066 #include <stdio.h>
00067 #include <io.h>
00068 #include <fcntl.h>
00069 #include <errno.h>
00070 
00071 static int PlayMp3File(char *path);
00072 
00096 int main(void)
00097 {
00098     /* Baudrate for debug output. */
00099     u_long baud = 115200;
00100 
00101     /*
00102      * Register our devices.
00103      */
00104     NutRegisterDevice(&devUrom, 0, 0);
00105     NutRegisterDevice(&DEV_DEBUG, 0, 0);
00106 
00107     /*
00108      * Assign stdout to the debug device.
00109      */
00110     freopen(DEV_DEBUG_NAME, "w", stdout);
00111     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00112 
00113     /*
00114      * Print a banner.
00115      */
00116     printf("\n\nPlay MP3 files on Nut/OS %s\n", NutVersionString());
00117 
00118 #if defined(__AVR__)
00119 
00120     /*
00121      * Initialize the MP3 buffer. The NutSegBuf routines provide a global
00122      * system buffer, which works with banked and non-banked systems.
00123      */
00124     if (NutSegBufInit(8192) == 0) {
00125         puts("NutSegBufInit: Fatal error");
00126     }
00127 
00128     /* 
00129      * Initialize the MP3 decoder hardware.
00130      */
00131     if (VsPlayerInit() || VsPlayerReset(0)) {
00132         puts("VsPlayer: Fatal error");
00133     }
00134 
00135     /*
00136      * Play the MP3 files in an endless loop. For each file set the volume 
00137      * of the left and right channel, call the local routine PlayMp3File() 
00138      * and sleep one second before playing the next sound file.
00139      */
00140     for (;;) {
00141         VsSetVolume(0, 254);
00142         PlayMp3File("UROM:sound1a.mp3");
00143         NutSleep(1000);
00144 
00145         VsSetVolume(0, 0);
00146         PlayMp3File("UROM:sound2a.mp3");
00147         NutSleep(1000);
00148 
00149         VsSetVolume(254, 0);
00150         PlayMp3File("UROM:sound3a.mp3");
00151         NutSleep(1000);
00152 
00153         VsSetVolume(0, 0);
00154         PlayMp3File("UROM:sound4a.mp3");
00155         NutSleep(1000);
00156     }
00157 #else /* !__AVR__ */
00158     for (;;);
00159 #endif /* !__AVR__ */
00160 }
00161 
00162 #if defined(__AVR__)
00163 
00164 /*
00165  * Play MP3 file from local file system.
00166  *
00167  * \param path Pathname of the MP3 file to play.
00168  *
00169  * \return 0 on success, -1 if opening the file failed.
00170  */
00171 static int PlayMp3File(char *path)
00172 {
00173     int fd;
00174     size_t rbytes;
00175     u_char *mp3buf;
00176     int got;
00177     u_char ief;
00178 
00179     /*
00180      * Open the MP3 file.
00181      */
00182     printf("Play %s: ", path);
00183     if ((fd = _open(path, _O_RDONLY | _O_BINARY)) == -1) {
00184         printf("Error %d\n", errno);
00185         return -1;
00186     }
00187     puts("OK");
00188 
00189     /* 
00190      * Reset decoder buffer.
00191      */
00192     printf("[B.RST]");
00193     ief = VsPlayerInterrupts(0);
00194     NutSegBufReset();
00195     VsPlayerInterrupts(ief);
00196 
00197     for (;;) {
00198         /*
00199          * Query number of byte available in MP3 buffer.
00200          */
00201         ief = VsPlayerInterrupts(0);
00202         mp3buf = NutSegBufWriteRequest(&rbytes);
00203         VsPlayerInterrupts(ief);
00204 
00205         /* 
00206          * Read data directly into the MP3 buffer. 
00207          */
00208         if (rbytes) {
00209             printf("[B.RD%d]", rbytes);
00210             if ((got = _read(fd, mp3buf, rbytes)) > 0) {
00211                 printf("[B.CMT%d]", got);
00212                 ief = VsPlayerInterrupts(0);
00213                 mp3buf = NutSegBufWriteCommit(got);
00214                 VsPlayerInterrupts(ief);
00215             } else {
00216                 printf("[EOF]");
00217                 break;
00218             }
00219         }
00220 
00221         /*
00222          * If the player is not running, kick it.
00223          */
00224         if (VsGetStatus() != VS_STATUS_RUNNING) {
00225             printf("[P.KICK]");
00226             VsPlayerKick();
00227         }
00228 
00229         /*
00230          * Allow background threads to take over.
00231          */
00232         NutThreadYield();
00233     }
00234 
00235     _close(fd);
00236 
00237     /* 
00238      * Flush decoder and wait until finished. 
00239      */
00240     printf("[P.FLUSH]");
00241     VsPlayerFlush();
00242     while (VsGetStatus() != VS_STATUS_EMPTY) {
00243         NutSleep(1);
00244     }
00245 
00246     /*
00247      * Reset the decoder. 
00248      */
00249     printf("[P.RST]");
00250     VsPlayerReset(0);
00251 
00252     printf("\nDone, %u bytes free\n", NutHeapAvailable());
00253     return 0;
00254 }
00255 
00256 #endif /* !__AVR__ */

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