summaryrefslogtreecommitdiff
path: root/apps/codecs/flac.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/flac.c')
-rw-r--r--apps/codecs/flac.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index 5e392da8e7..880fd69ab2 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -193,12 +193,12 @@ static bool flac_init(FLACContext* fc, int first_frame_offset)
193*/ 193*/
194bool flac_seek(FLACContext* fc, uint32_t newsample) { 194bool flac_seek(FLACContext* fc, uint32_t newsample) {
195 uint32_t offset; 195 uint32_t offset;
196 int i;
197 196
198 if (nseekpoints==0) { 197 if (nseekpoints==0) {
199 offset=0; 198 /* No seekpoints = no seeking */
199 return false;
200 } else { 200 } else {
201 i=nseekpoints-1; 201 int i=nseekpoints-1;
202 while ((i > 0) && (seekpoints[i].sample > newsample)) { 202 while ((i > 0) && (seekpoints[i].sample > newsample)) {
203 i--; 203 i--;
204 } 204 }
@@ -210,13 +210,33 @@ bool flac_seek(FLACContext* fc, uint32_t newsample) {
210 } 210 }
211 } 211 }
212 212
213 offset+=fc->metadatalength; 213 return ci->seek_buffer(offset+fc->metadatalength);
214}
214 215
215 if (ci->seek_buffer(offset)) { 216/* A very simple seek implementation - seek to the seekpoint before
216 return true; 217 the target offset.
217 } else { 218
219 This needs to be improved to seek with greater accuracy
220*/
221bool flac_seek_offset(FLACContext* fc, uint32_t offset) {
222 if (nseekpoints==0) {
223 /* No seekpoints = no seeking */
218 return false; 224 return false;
225 } else {
226 offset-=fc->metadatalength;
227 int i=nseekpoints-1;
228 while ((i > 0) && (seekpoints[i].offset > offset)) {
229 i--;
230 }
231
232 if ((i==0) && (seekpoints[i].offset > offset)) {
233 offset=0;
234 } else {
235 offset=seekpoints[i].offset;
236 }
219 } 237 }
238
239 return ci->seek_buffer(offset+fc->metadatalength);
220} 240}
221 241
222/* this is the codec entry point */ 242/* this is the codec entry point */
@@ -249,6 +269,9 @@ enum codec_status codec_start(struct codec_api* api)
249 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1)); 269 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1));
250 270
251 next_track: 271 next_track:
272
273 /* Need to save offset for later use (cleared indirectly by flac_init) */
274 samplesdone=ci->id3->offset;
252 275
253 if (codec_init(api)) { 276 if (codec_init(api)) {
254 LOGF("FLAC: Error initialising codec\n"); 277 LOGF("FLAC: Error initialising codec\n");
@@ -262,14 +285,18 @@ enum codec_status codec_start(struct codec_api* api)
262 goto done; 285 goto done;
263 } 286 }
264 287
265 while (!*ci->taginfo_ready) 288 while (!*ci->taginfo_ready && !ci->stop_codec)
266 ci->yield(); 289 ci->sleep(1);
267 290
268 ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); 291 ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
269 codec_set_replaygain(ci->id3); 292 codec_set_replaygain(ci->id3);
270 293
294 if (samplesdone) {
295 flac_seek_offset(&fc, samplesdone);
296 samplesdone=0;
297 }
298
271 /* The main decoding loop */ 299 /* The main decoding loop */
272 samplesdone=0;
273 frame=0; 300 frame=0;
274 buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE); 301 buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
275 while (bytesleft) { 302 while (bytesleft) {