forked from len0rd/rockbox
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
This commit is contained in:
parent
959d23e231
commit
f95dd56a2c
3 changed files with 50 additions and 13 deletions
|
@ -193,12 +193,12 @@ static bool flac_init(FLACContext* fc, int first_frame_offset)
|
||||||
*/
|
*/
|
||||||
bool flac_seek(FLACContext* fc, uint32_t newsample) {
|
bool flac_seek(FLACContext* fc, uint32_t newsample) {
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (nseekpoints==0) {
|
if (nseekpoints==0) {
|
||||||
offset=0;
|
/* No seekpoints = no seeking */
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
i=nseekpoints-1;
|
int i=nseekpoints-1;
|
||||||
while ((i > 0) && (seekpoints[i].sample > newsample)) {
|
while ((i > 0) && (seekpoints[i].sample > newsample)) {
|
||||||
i--;
|
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)) {
|
/* A very simple seek implementation - seek to the seekpoint before
|
||||||
return true;
|
the target offset.
|
||||||
} else {
|
|
||||||
|
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;
|
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 */
|
/* 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));
|
ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1));
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
||||||
|
/* Need to save offset for later use (cleared indirectly by flac_init) */
|
||||||
|
samplesdone=ci->id3->offset;
|
||||||
|
|
||||||
if (codec_init(api)) {
|
if (codec_init(api)) {
|
||||||
LOGF("FLAC: Error initialising codec\n");
|
LOGF("FLAC: Error initialising codec\n");
|
||||||
|
@ -262,14 +285,18 @@ enum codec_status codec_start(struct codec_api* api)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!*ci->taginfo_ready)
|
while (!*ci->taginfo_ready && !ci->stop_codec)
|
||||||
ci->yield();
|
ci->sleep(1);
|
||||||
|
|
||||||
ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
|
ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
|
||||||
codec_set_replaygain(ci->id3);
|
codec_set_replaygain(ci->id3);
|
||||||
|
|
||||||
|
if (samplesdone) {
|
||||||
|
flac_seek_offset(&fc, samplesdone);
|
||||||
|
samplesdone=0;
|
||||||
|
}
|
||||||
|
|
||||||
/* The main decoding loop */
|
/* The main decoding loop */
|
||||||
samplesdone=0;
|
|
||||||
frame=0;
|
frame=0;
|
||||||
buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
|
buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE);
|
||||||
while (bytesleft) {
|
while (bytesleft) {
|
||||||
|
|
|
@ -410,11 +410,19 @@ next_track:
|
||||||
}
|
}
|
||||||
|
|
||||||
firstblockposn = 1024 - n;
|
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 */
|
/* The main decoder loop */
|
||||||
bytesdone = 0;
|
|
||||||
ci->set_elapsed(0);
|
|
||||||
endofstream = 0;
|
endofstream = 0;
|
||||||
/* chunksize is computed so that one chunk is about 1/50s.
|
/* chunksize is computed so that one chunk is about 1/50s.
|
||||||
* this make 4096 for 44.1kHz 16bits stereo.
|
* this make 4096 for 44.1kHz 16bits stereo.
|
||||||
|
|
|
@ -1744,8 +1744,10 @@ static bool audio_load_track(int offset, bool start_play, bool rebuffer)
|
||||||
ci.curpos = offset;
|
ci.curpos = offset;
|
||||||
tracks[track_widx].start_pos = offset;
|
tracks[track_widx].start_pos = offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFMT_OGG_VORBIS:
|
case AFMT_OGG_VORBIS:
|
||||||
case AFMT_FLAC:
|
case AFMT_FLAC:
|
||||||
|
case AFMT_PCM_WAV:
|
||||||
tracks[track_widx].id3.offset = offset;
|
tracks[track_widx].id3.offset = offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue