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 5e392da..880fd69 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) {