summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/flac.c47
-rw-r--r--apps/codecs/wav.c14
-rw-r--r--apps/playback.c2
3 files changed, 50 insertions, 13 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) {
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index d9be0a3420..f83f1d1e58 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -410,11 +410,19 @@ next_track:
410 } 410 }
411 411
412 firstblockposn = 1024 - n; 412 firstblockposn = 1024 - n;
413 ci->advance_buffer(firstblockposn); 413
414 if (ci->id3->offset > (uint32_t) firstblockposn) {
415 /* Round down to previous block */
416 uint32_t offset = ci->id3->offset - ci->id3->offset % blockalign;
417
418 ci->advance_buffer(offset);
419 bytesdone = offset - firstblockposn;
420 } else {
421 ci->advance_buffer(firstblockposn);
422 bytesdone = 0;
423 }
414 424
415 /* The main decoder loop */ 425 /* The main decoder loop */
416 bytesdone = 0;
417 ci->set_elapsed(0);
418 endofstream = 0; 426 endofstream = 0;
419 /* chunksize is computed so that one chunk is about 1/50s. 427 /* chunksize is computed so that one chunk is about 1/50s.
420 * this make 4096 for 44.1kHz 16bits stereo. 428 * this make 4096 for 44.1kHz 16bits stereo.
diff --git a/apps/playback.c b/apps/playback.c
index ce0b45fe5e..4ab9e66117 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -1744,8 +1744,10 @@ static bool audio_load_track(int offset, bool start_play, bool rebuffer)
1744 ci.curpos = offset; 1744 ci.curpos = offset;
1745 tracks[track_widx].start_pos = offset; 1745 tracks[track_widx].start_pos = offset;
1746 break; 1746 break;
1747
1747 case AFMT_OGG_VORBIS: 1748 case AFMT_OGG_VORBIS:
1748 case AFMT_FLAC: 1749 case AFMT_FLAC:
1750 case AFMT_PCM_WAV:
1749 tracks[track_widx].id3.offset = offset; 1751 tracks[track_widx].id3.offset = offset;
1750 break; 1752 break;
1751 } 1753 }