Added support for playing arbitrary format audio files with an intelligent audio processor like the VS1053 codec.
Demo added.
This commit is contained in:
parent
8d1ce48800
commit
16fba41d50
10 changed files with 2089 additions and 18 deletions
BIN
demos/modules/gaudio/play-vs1053/allwrong.wav
Normal file
BIN
demos/modules/gaudio/play-vs1053/allwrong.wav
Normal file
Binary file not shown.
3
demos/modules/gaudio/play-vs1053/demo.mk
Normal file
3
demos/modules/gaudio/play-vs1053/demo.mk
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
DEMODIR = $(GFXLIB)/demos/modules/gaudio/play-vs1053
|
||||||
|
GFXINC += $(DEMODIR)
|
||||||
|
GFXSRC += $(DEMODIR)/main.c
|
62
demos/modules/gaudio/play-vs1053/gfxconf.h
Normal file
62
demos/modules/gaudio/play-vs1053/gfxconf.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||||
|
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy this file into your project directory and rename it as gfxconf.h
|
||||||
|
* Edit your copy to turn on the GFX features you want to use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GFXCONF_H
|
||||||
|
#define _GFXCONF_H
|
||||||
|
|
||||||
|
/* The operating system to use. One of these must be defined - preferably in your Makefile */
|
||||||
|
//#define GFX_USE_OS_CHIBIOS FALSE
|
||||||
|
//#define GFX_USE_OS_WIN32 FALSE
|
||||||
|
//#define GFX_USE_OS_LINUX FALSE
|
||||||
|
//#define GFX_USE_OS_OSX FALSE
|
||||||
|
|
||||||
|
/* GFX sub-systems to turn on */
|
||||||
|
#define GFX_USE_GDISP TRUE
|
||||||
|
#define GFX_USE_GAUDIO TRUE
|
||||||
|
#define GFX_USE_GFILE TRUE
|
||||||
|
|
||||||
|
/* Features for the GDISP sub-system. */
|
||||||
|
#define GDISP_NEED_VALIDATION TRUE
|
||||||
|
#define GDISP_NEED_TEXT TRUE
|
||||||
|
|
||||||
|
/* GDISP fonts to include */
|
||||||
|
#define GDISP_INCLUDE_FONT_UI2 TRUE
|
||||||
|
|
||||||
|
/* Features for the GAUDIO sub-system */
|
||||||
|
#define GAUDIO_NEED_PLAY TRUE
|
||||||
|
|
||||||
|
/* Features for the GFILE sub-system */
|
||||||
|
#define GFILE_NEED_ROMFS TRUE
|
||||||
|
|
||||||
|
#endif /* _GFXCONF_H */
|
119
demos/modules/gaudio/play-vs1053/main.c
Normal file
119
demos/modules/gaudio/play-vs1053/main.c
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||||
|
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This demo demonstrates the use of the GAUDOUT module to play a audio file of arbitrary format
|
||||||
|
* eg. WAV, MP3. It is designed to work only with intelligent codecs like the VS1053 that can interpret
|
||||||
|
* the audio data themselves.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
/* Specify our timing parameters */
|
||||||
|
#define MY_AUDIO_CHANNEL 0 /* Use channel 0 */
|
||||||
|
#define MY_PLAY_FILE "allwrong.wav"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Application entry point.
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
font_t font;
|
||||||
|
GFILE *f;
|
||||||
|
char *errmsg;
|
||||||
|
uint32_t toplay;
|
||||||
|
uint32_t len;
|
||||||
|
GDataBuffer *pd;
|
||||||
|
|
||||||
|
// Initialise everything
|
||||||
|
gfxInit();
|
||||||
|
errmsg = 0;
|
||||||
|
|
||||||
|
// Any font will do
|
||||||
|
font = gdispOpenFont("*");
|
||||||
|
|
||||||
|
// Allocate audio buffers - 4 x 512 byte buffers.
|
||||||
|
// You may need to increase this for slower cpu's.
|
||||||
|
// You may be able to decrease this for low latency operating systems.
|
||||||
|
if (!gfxBufferAlloc(4, 512)) {
|
||||||
|
errmsg = "Err: No Memory";
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatplay:
|
||||||
|
// Open the wave file
|
||||||
|
if (!(f = gfileOpen(MY_PLAY_FILE, "r"))) {
|
||||||
|
errmsg = "Err: Open WAV";
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the audio output device - bitrate is ignored
|
||||||
|
if (!gaudioPlayInit(MY_AUDIO_CHANNEL, 22000, GAUDIO_PLAY_FORMAT_FILE)) {
|
||||||
|
errmsg = "Err: Bad format/freq";
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play the file
|
||||||
|
gdispDrawString(0, gdispGetHeight()/2, "Playing...", font, Yellow);
|
||||||
|
toplay = gfileGetSize(f);
|
||||||
|
while(toplay) {
|
||||||
|
// Get a buffer to put the data into
|
||||||
|
pd = gfxBufferGet(TIME_INFINITE); // This should never fail as we are waiting forever
|
||||||
|
|
||||||
|
// How much data can we put in
|
||||||
|
len = toplay > pd->size ? pd->size : toplay;
|
||||||
|
pd->len = len;
|
||||||
|
toplay -= len;
|
||||||
|
|
||||||
|
// Read the data
|
||||||
|
if (gfileRead(f, pd+1, len) != len) {
|
||||||
|
errmsg = "Err: Read fail";
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
|
||||||
|
gaudioPlay(pd);
|
||||||
|
}
|
||||||
|
gfileClose(f);
|
||||||
|
|
||||||
|
// Wait for the play to finish
|
||||||
|
gaudioPlayWait(TIME_INFINITE);
|
||||||
|
gdispDrawString(0, gdispGetHeight()/2+10, "Done", font, Green);
|
||||||
|
|
||||||
|
// Repeat the whole thing
|
||||||
|
gfxSleepMilliseconds(1500);
|
||||||
|
gdispClear(Black);
|
||||||
|
goto repeatplay;
|
||||||
|
|
||||||
|
// The end
|
||||||
|
theend:
|
||||||
|
if (errmsg)
|
||||||
|
gdispDrawString(0, gdispGetHeight()/2, errmsg, font, Red);
|
||||||
|
|
||||||
|
while(TRUE)
|
||||||
|
gfxSleepMilliseconds(1000);
|
||||||
|
}
|
1854
demos/modules/gaudio/play-vs1053/romfs_allwrong.h
Normal file
1854
demos/modules/gaudio/play-vs1053/romfs_allwrong.h
Normal file
File diff suppressed because it is too large
Load diff
7
demos/modules/gaudio/play-vs1053/romfs_files.h
Normal file
7
demos/modules/gaudio/play-vs1053/romfs_files.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/**
|
||||||
|
* This file contains the list of files for the ROMFS.
|
||||||
|
*
|
||||||
|
* The files have been converted using...
|
||||||
|
* file2c -dbcs infile outfile
|
||||||
|
*/
|
||||||
|
#include "romfs_allwrong.h"
|
|
@ -14,10 +14,23 @@
|
||||||
/* Driver hardware support. */
|
/* Driver hardware support. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/* Note:
|
||||||
|
* The VS1053 has an internal processor which can decode many file formats directly.
|
||||||
|
* If you want to use anything other than raw PCM then you should use GAUDIO_PLAY_FORMAT_FILE and pipe
|
||||||
|
* the entire file as if it was sound data. It doesn't matter if you choose the mono or stereo channel
|
||||||
|
* as the codec chip automatically detects the real format itself.
|
||||||
|
* No testing is made of the file format - if there is an error it can only be detected by the codec chip
|
||||||
|
* and its behaviour is undefined (we haven't tested).
|
||||||
|
* Note that some formats require a firmware patch to be installed to play correctly.
|
||||||
|
* In this case define VS1053_FIRMWARE_PATCH as TRUE in your gfxconf.h file and include the patch file
|
||||||
|
* in your project directory. The patch file MUST be called "vs1053_patch.plg".
|
||||||
|
*/
|
||||||
#define GAUDIO_PLAY_MAX_SAMPLE_FREQUENCY 48000
|
#define GAUDIO_PLAY_MAX_SAMPLE_FREQUENCY 48000
|
||||||
#define GAUDIO_PLAY_NUM_FORMATS 2
|
#define GAUDIO_PLAY_NUM_FORMATS 3
|
||||||
#define GAUDIO_PLAY_FORMAT1 ARRAY_DATA_16BITSIGNED
|
#define GAUDIO_PLAY_FORMAT1 ARRAY_DATA_16BITSIGNED
|
||||||
#define GAUDIO_PLAY_FORMAT2 ARRAY_DATA_8BITUNSIGNED
|
#define GAUDIO_PLAY_FORMAT2 ARRAY_DATA_8BITUNSIGNED
|
||||||
|
#define GAUDIO_PLAY_FORMAT3 ARRAY_DATA_UNKNOWN
|
||||||
|
#define GAUDIO_PLAY_FORMAT_FILE ARRAY_DATA_UNKNOWN
|
||||||
#define GAUDIO_PLAY_NUM_CHANNELS 2
|
#define GAUDIO_PLAY_NUM_CHANNELS 2
|
||||||
#define GAUDIO_PLAY_CHANNEL0_IS_STEREO FALSE
|
#define GAUDIO_PLAY_CHANNEL0_IS_STEREO FALSE
|
||||||
#define GAUDIO_PLAY_CHANNEL1_IS_STEREO TRUE
|
#define GAUDIO_PLAY_CHANNEL1_IS_STEREO TRUE
|
||||||
|
|
|
@ -242,7 +242,7 @@ bool_t gaudio_play_lld_init(uint16_t channel, uint32_t frequency, ArrayDataForma
|
||||||
0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (format != ARRAY_DATA_8BITUNSIGNED && format != ARRAY_DATA_16BITSIGNED)
|
if (format != ARRAY_DATA_8BITUNSIGNED && format != ARRAY_DATA_16BITSIGNED && format != ARRAY_DATA_UNKNOWN)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (frequency > VS1053_MAX_SAMPLE_RATE)
|
if (frequency > VS1053_MAX_SAMPLE_RATE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -254,21 +254,23 @@ bool_t gaudio_play_lld_init(uint16_t channel, uint32_t frequency, ArrayDataForma
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
bps = (gfxSampleFormatBits(format)+7)/8;
|
if (format == ARRAY_DATA_8BITUNSIGNED || format == ARRAY_DATA_16BITSIGNED) {
|
||||||
if (channel == GAUDIO_PLAY_STEREO)
|
bps = (gfxSampleFormatBits(format)+7)/8;
|
||||||
bps *= 2;
|
if (channel == GAUDIO_PLAY_STEREO)
|
||||||
brate = frequency * bps;
|
bps *= 2;
|
||||||
|
brate = frequency * bps;
|
||||||
|
|
||||||
// Write the RIFF header
|
// Write the RIFF header
|
||||||
waitforready();
|
waitforready();
|
||||||
data_write(hdr1, sizeof(hdr1));
|
data_write(hdr1, sizeof(hdr1));
|
||||||
buf[0] = channel == GAUDIO_PLAY_STEREO ? 2 : 1; buf[1] = 0; data_write(buf, 2);
|
buf[0] = channel == GAUDIO_PLAY_STEREO ? 2 : 1; buf[1] = 0; data_write(buf, 2);
|
||||||
buf[0] = frequency; buf[1] = frequency>>8; buf[2] = frequency>>16; buf[3] = frequency>>24; data_write(buf, 4);
|
buf[0] = frequency; buf[1] = frequency>>8; buf[2] = frequency>>16; buf[3] = frequency>>24; data_write(buf, 4);
|
||||||
buf[0] = brate; buf[1] = brate>>8; buf[2] = brate>>16; buf[3] = brate>>24; data_write(buf, 4);
|
buf[0] = brate; buf[1] = brate>>8; buf[2] = brate>>16; buf[3] = brate>>24; data_write(buf, 4);
|
||||||
waitforready(); // 32 bytes max before checking
|
waitforready(); // 32 bytes max before checking
|
||||||
buf[0] = bps; buf[1] = 0; data_write(buf, 2);
|
buf[0] = bps; buf[1] = 0; data_write(buf, 2);
|
||||||
buf[0] = gfxSampleFormatBits(format); buf[1] = 0; data_write(buf, 2);
|
buf[0] = gfxSampleFormatBits(format); buf[1] = 0; data_write(buf, 2);
|
||||||
data_write(hdr2, sizeof(hdr2));
|
data_write(hdr2, sizeof(hdr2));
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,14 @@
|
||||||
This chip supports playing in many formats including MP3 etc.
|
This chip supports playing in many formats including MP3 etc.
|
||||||
For this driver however we only support PCM in 8 bit unisgned and 16 bit signed formats.
|
For this driver we support the standard PCM in 8 bit unsigned and 16 bit signed formats.
|
||||||
|
|
||||||
Requires GFX_USE_GTIMER
|
Requires GFX_USE_GTIMER
|
||||||
|
|
||||||
|
* The VS1053 has an internal processor which can decode many file formats directly.
|
||||||
|
* If you want to use anything other than raw PCM then you should use GAUDIO_PLAY_FORMAT_FILE and pipe
|
||||||
|
* the entire file as if it was sound data. It doesn't matter if you choose the mono or stereo channel
|
||||||
|
* as the codec chip automatically detects the real format itself.
|
||||||
|
* No testing is made of the file format - if there is an error it can only be detected by the codec chip
|
||||||
|
* and its behaviour is undefined (we haven't tested).
|
||||||
|
* Note that some formats require a firmware patch to be installed to play correctly.
|
||||||
|
* In this case define VS1053_FIRMWARE_PATCH as TRUE in your gfxconf.h file and include the patch file
|
||||||
|
* in your project directory. The patch file MUST be called "vs1053_patch.plg".
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
* or not as they are used in lots of places.
|
* or not as they are used in lots of places.
|
||||||
*/
|
*/
|
||||||
typedef enum ArrayDataFormat_e {
|
typedef enum ArrayDataFormat_e {
|
||||||
|
ARRAY_DATA_UNKNOWN = 0,
|
||||||
ARRAY_DATA_4BITUNSIGNED = 4, ARRAY_DATA_4BITSIGNED = 5,
|
ARRAY_DATA_4BITUNSIGNED = 4, ARRAY_DATA_4BITSIGNED = 5,
|
||||||
ARRAY_DATA_8BITUNSIGNED = 8, ARRAY_DATA_8BITSIGNED = 9,
|
ARRAY_DATA_8BITUNSIGNED = 8, ARRAY_DATA_8BITSIGNED = 9,
|
||||||
ARRAY_DATA_10BITUNSIGNED = 10, ARRAY_DATA_10BITSIGNED = 11,
|
ARRAY_DATA_10BITUNSIGNED = 10, ARRAY_DATA_10BITSIGNED = 11,
|
||||||
|
|
Loading…
Add table
Reference in a new issue