summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/codecwav.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/apps/plugins/codecwav.c b/apps/plugins/codecwav.c
new file mode 100644
index 0000000000..a02f2cdbff
--- /dev/null
+++ b/apps/plugins/codecwav.c
@@ -0,0 +1,131 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "plugin.h"
21#include "playback.h"
22#include "lib/codeclib.h"
23
24#ifndef SIMULATOR
25extern char iramcopy[];
26extern char iramstart[];
27extern char iramend[];
28#endif
29
30/* This is probably a waste of IRAM, but why not? */
31static unsigned char wavbuf[16384] IDATA_ATTR;
32
33/* this is the plugin entry point */
34enum plugin_status plugin_start(struct plugin_api* api, void* parm)
35{
36 struct plugin_api* rb = (struct plugin_api*)api;
37 struct codec_api* ci = (struct codec_api*)parm;
38 unsigned long samplerate,numbytes,totalsamples,samplesdone,nsamples;
39 int channels,bytespersample,bitspersample;
40 unsigned int i,j,n;
41 int endofstream;
42
43 /* Generic plugin initialisation */
44 TEST_PLUGIN_API(api);
45
46 /* if you are using a global api pointer, don't forget to copy it!
47 otherwise you will get lovely "I04: IllInstr" errors... :-) */
48 rb = api;
49
50#ifndef SIMULATOR
51 rb->memcpy(iramstart, iramcopy, iramend-iramstart);
52#endif
53
54 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10));
55 ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
56
57 next_track:
58
59 if (codec_init(api, ci)) {
60 return PLUGIN_ERROR;
61 }
62
63 /* FIX: Correctly parse WAV header - we assume canonical 44-byte header */
64
65 n=(unsigned)(ci->read_filebuf(wavbuf,44));
66 if (n!=44) {
67 return PLUGIN_ERROR;
68 }
69 if ((memcmp(wavbuf,"RIFF",4)!=0) || (memcmp(&wavbuf[8],"WAVEfmt",7)!=0)) {
70 return PLUGIN_ERROR;
71 }
72
73 samplerate=wavbuf[24]|(wavbuf[25]<<8)|(wavbuf[26]<<16)|(wavbuf[27]<<24);
74 bitspersample=wavbuf[34];
75 channels=wavbuf[22];
76 bytespersample=((bitspersample/8)*channels);
77 numbytes=(wavbuf[40]|(wavbuf[41]<<8)|(wavbuf[42]<<16)|(wavbuf[43]<<24));
78 totalsamples=numbytes/bytespersample;
79
80 if ((bitspersample!=16) || (channels != 2)) {
81 return PLUGIN_ERROR;
82 }
83
84 /* The main decoder loop */
85
86 samplesdone=0;
87 ci->set_elapsed(0);
88 endofstream=0;
89 while (!endofstream) {
90 rb->yield();
91 if (ci->stop_codec || ci->reload_codec) {
92 break;
93 }
94
95 n=(unsigned)(ci->read_filebuf(wavbuf,sizeof(wavbuf)));
96
97 rb->yield();
98
99 if (n==0) break; /* End of stream */
100
101 nsamples=(n/bytespersample);
102
103 /* WAV files can contain extra data at the end - so we can't just
104 process until the end of the file */
105
106 if (samplesdone+nsamples > totalsamples) {
107 nsamples=(totalsamples-samplesdone);
108 n=nsamples*bytespersample;
109 endofstream=1;
110 }
111
112 /* Byte-swap data */
113 for (i=0;i<n;i+=2) {
114 j=wavbuf[i];
115 wavbuf[i]=wavbuf[i+1];
116 wavbuf[i+1]=j;
117 }
118
119 samplesdone+=nsamples;
120 ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
121
122 rb->yield();
123 while (!ci->audiobuffer_insert(wavbuf, n))
124 rb->yield();
125 }
126
127 if (ci->request_next_track())
128 goto next_track;
129
130 return PLUGIN_OK;
131}