summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/flac.c211
1 files changed, 102 insertions, 109 deletions
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index 0d21c3cdf1..61605bc9ec 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -29,7 +29,6 @@
29#define FLAC_MAX_SUPPORTED_BLOCKSIZE 4608 29#define FLAC_MAX_SUPPORTED_BLOCKSIZE 4608
30#define FLAC_MAX_SUPPORTED_CHANNELS 2 30#define FLAC_MAX_SUPPORTED_CHANNELS 2
31 31
32static struct codec_api* rb;
33static uint32_t samplesdone; 32static uint32_t samplesdone;
34 33
35static FLAC__StreamMetadata *stream_info; 34static FLAC__StreamMetadata *stream_info;
@@ -39,15 +38,16 @@ unsigned int metadata_length;
39/* Called when the FLAC decoder needs some FLAC data to decode */ 38/* Called when the FLAC decoder needs some FLAC data to decode */
40FLAC__SeekableStreamDecoderReadStatus flac_read_handler(const FLAC__SeekableStreamDecoder *dec, 39FLAC__SeekableStreamDecoderReadStatus flac_read_handler(const FLAC__SeekableStreamDecoder *dec,
41 FLAC__byte buffer[], unsigned *bytes, void *data) 40 FLAC__byte buffer[], unsigned *bytes, void *data)
42{ struct codec_api* ci = (struct codec_api*)data; 41{
42 struct codec_api* ci = (struct codec_api*)data;
43 (void)dec; 43 (void)dec;
44 44
45 *bytes=(unsigned)(ci->read_filebuf(buffer,*bytes)); 45 *bytes=(unsigned)(ci->read_filebuf(buffer,*bytes));
46 46
47 if (*bytes==0) { 47 if (*bytes==0) {
48 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 48 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
49 } else { 49 } else {
50 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; 50 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
51 } 51 }
52} 52}
53 53
@@ -55,44 +55,44 @@ static unsigned char pcmbuf[FLAC_MAX_SUPPORTED_BLOCKSIZE*FLAC_MAX_SUPPORTED_CHAN
55 55
56/* Called when the FLAC decoder has some decoded PCM data to write */ 56/* Called when the FLAC decoder has some decoded PCM data to write */
57FLAC__StreamDecoderWriteStatus flac_write_handler(const FLAC__SeekableStreamDecoder *dec, 57FLAC__StreamDecoderWriteStatus flac_write_handler(const FLAC__SeekableStreamDecoder *dec,
58 const FLAC__Frame *frame, 58 const FLAC__Frame *frame,
59 const FLAC__int32 * const buf[], 59 const FLAC__int32 * const buf[],
60 void *data) 60 void *data)
61{ 61{
62 struct codec_api* ci = (struct codec_api*)data; 62 struct codec_api* ci = (struct codec_api*)data;
63 (void)dec; 63 (void)dec;
64 unsigned int c_samp, c_chan, d_samp; 64 unsigned int c_samp, c_chan, d_samp;
65 uint32_t data_size = frame->header.blocksize * frame->header.channels * 2; /* Assume 16-bit words */ 65 uint32_t data_size = frame->header.blocksize * frame->header.channels * 2; /* Assume 16-bit words */
66 uint32_t samples = frame->header.blocksize; 66 uint32_t samples = frame->header.blocksize;
67 int yieldcounter = 0; 67 int yieldcounter = 0;
68 68
69 69
70 if (samples*frame->header.channels > (FLAC_MAX_SUPPORTED_BLOCKSIZE*FLAC_MAX_SUPPORTED_CHANNELS)) { 70 if (samples*frame->header.channels > (FLAC_MAX_SUPPORTED_BLOCKSIZE*FLAC_MAX_SUPPORTED_CHANNELS)) {
71 // ERROR!!! 71 // ERROR!!!
72 DEBUGF("ERROR: samples*frame->header.channels=%d\n",samples*frame->header.channels); 72 DEBUGF("ERROR: samples*frame->header.channels=%d\n",samples*frame->header.channels);
73 return(FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE); 73 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
74 } 74 }
75 75
76 (void)dec; 76 (void)dec;
77 for(c_samp = d_samp = 0; c_samp < samples; c_samp++) { 77 for (c_samp = d_samp = 0; c_samp < samples; c_samp++) {
78 for(c_chan = 0; c_chan < frame->header.channels; c_chan++, d_samp++) { 78 for(c_chan = 0; c_chan < frame->header.channels; c_chan++, d_samp++) {
79 pcmbuf[d_samp*2] = (buf[c_chan][c_samp]&0xff00)>>8; 79 pcmbuf[d_samp*2] = (buf[c_chan][c_samp]&0xff00)>>8;
80 pcmbuf[(d_samp*2)+1] = buf[c_chan][c_samp]&0xff; 80 pcmbuf[(d_samp*2)+1] = buf[c_chan][c_samp]&0xff;
81 if (yieldcounter++ == 100) { 81 if (yieldcounter++ == 100) {
82 rb->yield(); 82 ci->yield();
83 yieldcounter = 0; 83 yieldcounter = 0;
84 } 84 }
85 } 85 }
86 } 86 }
87 87
88 samplesdone+=samples; 88 samplesdone+=samples;
89 ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); 89 ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
90 90
91 rb->yield(); 91 ci->yield();
92 while (!ci->pcmbuf_insert(pcmbuf, data_size)) 92 while (!ci->pcmbuf_insert(pcmbuf, data_size))
93 rb->yield(); 93 ci->yield();
94 94
95 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 95 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
96} 96}
97 97
98void flac_metadata_handler(const FLAC__SeekableStreamDecoder *dec, 98void flac_metadata_handler(const FLAC__SeekableStreamDecoder *dec,
@@ -105,15 +105,15 @@ void flac_metadata_handler(const FLAC__SeekableStreamDecoder *dec,
105 metadata_length += meta->length; 105 metadata_length += meta->length;
106 106
107 if ( meta->type == FLAC__METADATA_TYPE_STREAMINFO ) { 107 if ( meta->type == FLAC__METADATA_TYPE_STREAMINFO ) {
108 stream_info = FLAC__metadata_object_clone( meta ); 108 stream_info = FLAC__metadata_object_clone( meta );
109 if ( stream_info == NULL ) { 109 if ( stream_info == NULL ) {
110 //return CODEC_ERROR; 110 //return CODEC_ERROR;
111 } 111 }
112 } else if ( meta->type == FLAC__METADATA_TYPE_SEEKTABLE ) { 112 } else if ( meta->type == FLAC__METADATA_TYPE_SEEKTABLE ) {
113 seek_table = FLAC__metadata_object_clone( meta ); 113 seek_table = FLAC__metadata_object_clone( meta );
114 if ( seek_table == NULL ) { 114 if ( seek_table == NULL ) {
115 //return CODEC_ERROR; 115 //return CODEC_ERROR;
116 } 116 }
117 } 117 }
118} 118}
119 119
@@ -126,50 +126,50 @@ void flac_error_handler(const FLAC__SeekableStreamDecoder *dec,
126 (void)data; 126 (void)data;
127} 127}
128 128
129FLAC__SeekableStreamDecoderSeekStatus flac_seek_handler (const FLAC__SeekableStreamDecoder *decoder, 129FLAC__SeekableStreamDecoderSeekStatus flac_seek_handler(const FLAC__SeekableStreamDecoder *decoder,
130 FLAC__uint64 absolute_byte_offset, 130 FLAC__uint64 absolute_byte_offset,
131 void *client_data) 131 void *client_data)
132{ 132{
133 (void)decoder; 133 (void)decoder;
134 struct codec_api* ci = (struct codec_api*)client_data; 134 struct codec_api* ci = (struct codec_api*)client_data;
135 135
136 if (ci->seek_buffer(absolute_byte_offset)) { 136 if (ci->seek_buffer(absolute_byte_offset)) {
137 return(FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK); 137 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
138 } else { 138 } else {
139 return(FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR); 139 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
140 } 140 }
141} 141}
142 142
143FLAC__SeekableStreamDecoderTellStatus flac_tell_handler (const FLAC__SeekableStreamDecoder *decoder, 143FLAC__SeekableStreamDecoderTellStatus flac_tell_handler(const FLAC__SeekableStreamDecoder *decoder,
144 FLAC__uint64 *absolute_byte_offset, void *client_data) 144 FLAC__uint64 *absolute_byte_offset, void *client_data)
145{ 145{
146 struct codec_api* ci = (struct codec_api*)client_data; 146 struct codec_api* ci = (struct codec_api*)client_data;
147 147
148 (void)decoder; 148 (void)decoder;
149 *absolute_byte_offset=ci->curpos; 149 *absolute_byte_offset = ci->curpos;
150 return(FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK); 150 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
151} 151}
152 152
153FLAC__SeekableStreamDecoderLengthStatus flac_length_handler (const FLAC__SeekableStreamDecoder *decoder, 153FLAC__SeekableStreamDecoderLengthStatus flac_length_handler(const FLAC__SeekableStreamDecoder *decoder,
154 FLAC__uint64 *stream_length, void *client_data) 154 FLAC__uint64 *stream_length, void *client_data)
155{ 155{
156 struct codec_api* ci = (struct codec_api*)client_data; 156 struct codec_api* ci = (struct codec_api*)client_data;
157 157
158 (void)decoder; 158 (void)decoder;
159 *stream_length=ci->filesize; 159 *stream_length = ci->filesize;
160 return(FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK); 160 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
161} 161}
162 162
163FLAC__bool flac_eof_handler (const FLAC__SeekableStreamDecoder *decoder, 163FLAC__bool flac_eof_handler(const FLAC__SeekableStreamDecoder *decoder,
164 void *client_data) 164 void *client_data)
165{ 165{
166 struct codec_api* ci = (struct codec_api*)client_data; 166 struct codec_api* ci = (struct codec_api*)client_data;
167 167
168 (void)decoder; 168 (void)decoder;
169 if (ci->curpos >= ci->filesize) { 169 if (ci->curpos >= ci->filesize) {
170 return(true); 170 return true;
171 } else { 171 } else {
172 return(false); 172 return false;
173 } 173 }
174} 174}
175 175
@@ -179,37 +179,37 @@ extern char iramstart[];
179extern char iramend[]; 179extern char iramend[];
180#endif 180#endif
181 181
182FLAC__uint64 find_sample_number(size_t offset) 182FLAC__uint64 find_sample_number(struct codec_api *ci, size_t offset)
183{ 183{
184 FLAC__StreamMetadata_SeekPoint *points; 184 FLAC__StreamMetadata_SeekPoint *points;
185 FLAC__uint64 prev_sample, next_sample; 185 FLAC__uint64 prev_sample, next_sample;
186 size_t prev_offset, next_offset; 186 size_t prev_offset, next_offset;
187 int percent; 187 int percent;
188 188
189 if ( offset >= (rb->id3->filesize - metadata_length)) { 189 if (offset >= (ci->id3->filesize - metadata_length)) {
190 return stream_info->data.stream_info.total_samples; 190 return stream_info->data.stream_info.total_samples;
191 } 191 }
192 192
193 prev_offset = 0; 193 prev_offset = 0;
194 prev_sample = 0; 194 prev_sample = 0;
195 next_offset = rb->id3->filesize - metadata_length; 195 next_offset = ci->id3->filesize - metadata_length;
196 next_sample = stream_info->data.stream_info.total_samples; 196 next_sample = stream_info->data.stream_info.total_samples;
197 197
198 if ( seek_table ) { 198 if (seek_table) {
199 int left, right, middle; 199 int left, right, middle;
200 200
201 middle = 0; /* Silence compiler warnings */ 201 middle = 0; /* Silence compiler warnings */
202 points = seek_table->data.seek_table.points; 202 points = seek_table->data.seek_table.points;
203 left = 0; 203 left = 0;
204 right = seek_table->data.seek_table.num_points - 1; 204 right = seek_table->data.seek_table.num_points - 1;
205 205
206 /* Do a binary search to find the matching seek point */ 206 /* Do a binary search to find the matching seek point */
207 while ( left <= right ) { 207 while (left <= right) {
208 middle = (left + right) / 2; 208 middle = (left + right) / 2;
209 209
210 if ( (FLAC__uint64)offset < points[middle].stream_offset ) { 210 if ((FLAC__uint64)offset < points[middle].stream_offset) {
211 right = middle - 1; 211 right = middle - 1;
212 } else if ( (FLAC__uint64)offset > points[middle].stream_offset ) { 212 } else if ((FLAC__uint64)offset > points[middle].stream_offset) {
213 left = middle + 1; 213 left = middle + 1;
214 } else { 214 } else {
215 return points[middle].sample_number; 215 return points[middle].sample_number;
@@ -221,10 +221,10 @@ FLAC__uint64 find_sample_number(size_t offset)
221 * accurate. Accuracy depends on how close these sample numbers are to 221 * accurate. Accuracy depends on how close these sample numbers are to
222 * each other. 222 * each other.
223 */ 223 */
224 if ( (unsigned)left >= seek_table->data.seek_table.num_points ) { 224 if ((unsigned)left >= seek_table->data.seek_table.num_points) {
225 prev_offset = points[middle].stream_offset; 225 prev_offset = points[middle].stream_offset;
226 prev_sample = points[middle].sample_number; 226 prev_sample = points[middle].sample_number;
227 } else if ( right < 0 ) { 227 } else if (right < 0) {
228 next_offset = points[middle].stream_offset; 228 next_offset = points[middle].stream_offset;
229 next_sample = points[middle].sample_number; 229 next_sample = points[middle].sample_number;
230 } else { 230 } else {
@@ -250,15 +250,10 @@ enum codec_status codec_start(struct codec_api* api)
250 FLAC__SeekableStreamDecoder* flacDecoder; 250 FLAC__SeekableStreamDecoder* flacDecoder;
251 FLAC__uint64 offset; 251 FLAC__uint64 offset;
252 252
253 /* Generic codec initialisation */ 253 TEST_CODEC_API(ci);
254 TEST_CODEC_API(api);
255
256 /* if you are using a global api pointer, don't forget to copy it!
257 otherwise you will get lovely "I04: IllInstr" errors... :-) */
258 rb = api;
259 254
260#ifndef SIMULATOR 255#ifndef SIMULATOR
261 rb->memcpy(iramstart, iramcopy, iramend-iramstart); 256 ci->memcpy(iramstart, iramcopy, iramend-iramstart);
262#endif 257#endif
263 258
264 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10)); 259 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10));
@@ -270,25 +265,23 @@ enum codec_status codec_start(struct codec_api* api)
270 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); 265 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED);
271 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); 266 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16));
272 267
273 next_track: 268next_track:
274
275 metadata_length = 0; 269 metadata_length = 0;
276 seek_table = NULL; 270 seek_table = NULL;
277 stream_info = NULL; 271 stream_info = NULL;
278 272
279 if (codec_init(api)) { 273 if (codec_init(api)) {
280 return CODEC_ERROR; 274 return CODEC_ERROR;
281 } 275 }
282 276
283 while (!rb->taginfo_ready) 277 while (!ci->taginfo_ready)
284 rb->yield(); 278 ci->yield();
285 279
286 rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); 280 ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
287 codec_set_replaygain(ci->id3); 281 codec_set_replaygain(ci->id3);
288 282
289 /* Create a decoder instance */ 283 /* Create a decoder instance */
290 284 flacDecoder = FLAC__seekable_stream_decoder_new();
291 flacDecoder=FLAC__seekable_stream_decoder_new();
292 285
293 /* Set up the decoder and the callback functions - this must be done before init */ 286 /* Set up the decoder and the callback functions - this must be done before init */
294 287
@@ -309,41 +302,41 @@ enum codec_status codec_start(struct codec_api* api)
309 302
310 /* QUESTION: What do we do when the init fails? */ 303 /* QUESTION: What do we do when the init fails? */
311 if (FLAC__seekable_stream_decoder_init(flacDecoder)) { 304 if (FLAC__seekable_stream_decoder_init(flacDecoder)) {
312 return CODEC_ERROR; 305 return CODEC_ERROR;
313 } 306 }
314 307
315 /* The first thing to do is to parse the metadata */ 308 /* The first thing to do is to parse the metadata */
316 FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDecoder); 309 FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDecoder);
317 310
318 if ( ci->id3->offset && stream_info ) { 311 if (ci->id3->offset && stream_info) {
319 FLAC__uint64 sample; 312 FLAC__uint64 sample;
320 313
321 sample = find_sample_number( ci->id3->offset - metadata_length ); 314 sample = find_sample_number(ci, ci->id3->offset - metadata_length);
322 ci->advance_buffer(ci->id3->offset); 315 ci->advance_buffer(ci->id3->offset);
323 FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample); 316 FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample);
324 FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset); 317 FLAC__seekable_stream_decoder_get_decode_position(flacDecoder, &offset);
325 ci->set_offset(offset); 318 ci->set_offset(offset);
326 samplesdone=(uint32_t)sample; 319 samplesdone = (uint32_t)sample;
327 ci->set_elapsed(sample/(ci->id3->frequency/1000)); 320 ci->set_elapsed(sample/(ci->id3->frequency/1000));
328 } else { 321 } else {
329 samplesdone=0; 322 samplesdone = 0;
330 ci->set_elapsed(0); 323 ci->set_elapsed(0);
331 } 324 }
332 325
333 /* The main decoder loop */ 326 /* The main decoder loop */
334 while (FLAC__seekable_stream_decoder_get_state(flacDecoder)!=FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) { 327 while (FLAC__seekable_stream_decoder_get_state(flacDecoder) != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
335 rb->yield(); 328 ci->yield();
336 if (ci->stop_codec || ci->reload_codec) { 329 if (ci->stop_codec || ci->reload_codec) {
337 break; 330 break;
338 } 331 }
339 332
340 if (ci->seek_time) { 333 if (ci->seek_time) {
341 int sample_loc; 334 int sample_loc;
342 335
343 sample_loc = ci->seek_time/1000 * ci->id3->frequency; 336 sample_loc = ci->seek_time/1000 * ci->id3->frequency;
344 if (FLAC__seekable_stream_decoder_seek_absolute(flacDecoder,sample_loc)) { 337 if (FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, sample_loc)) {
345 samplesdone=sample_loc; 338 samplesdone = sample_loc;
346 ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); 339 ci->set_elapsed(samplesdone/(ci->id3->frequency/1000));
347 } 340 }
348 ci->seek_time = 0; 341 ci->seek_time = 0;
349 } 342 }
@@ -357,11 +350,11 @@ enum codec_status codec_start(struct codec_api* api)
357 FLAC__seekable_stream_decoder_finish(flacDecoder); 350 FLAC__seekable_stream_decoder_finish(flacDecoder);
358 351
359 if (ci->request_next_track()) { 352 if (ci->request_next_track()) {
360 if ( stream_info ) { 353 if (stream_info) {
361 FLAC__metadata_object_delete(stream_info); 354 FLAC__metadata_object_delete(stream_info);
362 } 355 }
363 if ( seek_table ) { 356 if (seek_table) {
364 FLAC__metadata_object_delete(seek_table); 357 FLAC__metadata_object_delete(seek_table);
365 } 358 }
366 metadata_length = 0; 359 metadata_length = 0;
367 goto next_track; 360 goto next_track;