From f95dd56a2cfd1df77a3fc5beb664a8fb2018b80a Mon Sep 17 00:00:00 2001 From: Magnus Holmgren Date: Sun, 4 Jun 2006 15:04:03 +0000 Subject: Fix bug 5341: Resume in Wav and Flac doesn't start from the position where it was left off. Mark Arigo helped with the Flac fix. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10051 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/flac.c | 47 +++++++++++++++++++++++++++++++++++++---------- apps/codecs/wav.c | 14 +++++++++++--- apps/playback.c | 2 ++ 3 files changed, 50 insertions(+), 13 deletions(-) (limited to 'apps') 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) */ bool flac_seek(FLACContext* fc, uint32_t newsample) { uint32_t offset; - int i; if (nseekpoints==0) { - offset=0; + /* No seekpoints = no seeking */ + return false; } else { - i=nseekpoints-1; + int i=nseekpoints-1; while ((i > 0) && (seekpoints[i].sample > newsample)) { i--; } @@ -210,13 +210,33 @@ bool flac_seek(FLACContext* fc, uint32_t newsample) { } } - offset+=fc->metadatalength; + return ci->seek_buffer(offset+fc->metadatalength); +} - if (ci->seek_buffer(offset)) { - return true; - } else { +/* A very simple seek implementation - seek to the seekpoint before + the target offset. + + This needs to be improved to seek with greater accuracy +*/ +bool flac_seek_offset(FLACContext* fc, uint32_t offset) { + if (nseekpoints==0) { + /* No seekpoints = no seeking */ return false; + } else { + offset-=fc->metadatalength; + int i=nseekpoints-1; + while ((i > 0) && (seekpoints[i].offset > offset)) { + i--; + } + + if ((i==0) && (seekpoints[i].offset > offset)) { + offset=0; + } else { + offset=seekpoints[i].offset; + } } + + return ci->seek_buffer(offset+fc->metadatalength); } /* this is the codec entry point */ @@ -249,6 +269,9 @@ enum codec_status codec_start(struct codec_api* api) ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1)); next_track: + + /* Need to save offset for later use (cleared indirectly by flac_init) */ + samplesdone=ci->id3->offset; if (codec_init(api)) { LOGF("FLAC: Error initialising codec\n"); @@ -262,14 +285,18 @@ enum codec_status codec_start(struct codec_api* api) goto done; } - while (!*ci->taginfo_ready) - ci->yield(); + while (!*ci->taginfo_ready && !ci->stop_codec) + ci->sleep(1); ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); codec_set_replaygain(ci->id3); + if (samplesdone) { + flac_seek_offset(&fc, samplesdone); + samplesdone=0; + } + /* The main decoding loop */ - samplesdone=0; frame=0; buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE); 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: } firstblockposn = 1024 - n; - ci->advance_buffer(firstblockposn); + + if (ci->id3->offset > (uint32_t) firstblockposn) { + /* Round down to previous block */ + uint32_t offset = ci->id3->offset - ci->id3->offset % blockalign; + + ci->advance_buffer(offset); + bytesdone = offset - firstblockposn; + } else { + ci->advance_buffer(firstblockposn); + bytesdone = 0; + } /* The main decoder loop */ - bytesdone = 0; - ci->set_elapsed(0); endofstream = 0; /* chunksize is computed so that one chunk is about 1/50s. * 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) ci.curpos = offset; tracks[track_widx].start_pos = offset; break; + case AFMT_OGG_VORBIS: case AFMT_FLAC: + case AFMT_PCM_WAV: tracks[track_widx].id3.offset = offset; break; } -- cgit v1.2.3