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__ */