diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/codecwav.c | 131 |
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 | ||
25 | extern char iramcopy[]; | ||
26 | extern char iramstart[]; | ||
27 | extern char iramend[]; | ||
28 | #endif | ||
29 | |||
30 | /* This is probably a waste of IRAM, but why not? */ | ||
31 | static unsigned char wavbuf[16384] IDATA_ATTR; | ||
32 | |||
33 | /* this is the plugin entry point */ | ||
34 | enum 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 | } | ||