playmp3.c

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

© 2000-2010 by contributors - visit http://www.ethernut.de/