diff --git a/apps/buffering.c b/apps/buffering.c index 9a52d60b3f..cf5f2e53c2 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -1408,6 +1408,16 @@ ssize_t bufread(int handle_id, size_t size, void *dest) return size; } +off_t bufstripsize(int handle_id, off_t size) +{ + struct memory_handle *h = find_handle(handle_id); + if (!h || h->filesize < size) + return ERR_INVALID_VALUE; + + h->filesize = size; + return size; +} + /* Update the "data" pointer to make the handle's data available to the caller. Return the length of the available linear data or < 0 for failure (handle not found). diff --git a/apps/buffering.h b/apps/buffering.h index bc47d6b1a1..2c170d2ebd 100644 --- a/apps/buffering.h +++ b/apps/buffering.h @@ -81,6 +81,7 @@ int bufseek(int handle_id, size_t newpos); int bufadvance(int handle_id, off_t offset); off_t bufftell(int handle_id); ssize_t bufread(int handle_id, size_t size, void *dest); +off_t bufstripsize(int handle_id, off_t size); ssize_t bufgetdata(int handle_id, size_t size, void **data); /*************************************************************************** diff --git a/apps/codec_thread.c b/apps/codec_thread.c index 8b21cd4477..fdfb6acf43 100644 --- a/apps/codec_thread.c +++ b/apps/codec_thread.c @@ -440,6 +440,11 @@ static bool codec_loop_track_callback(void) return global_settings.repeat_mode == REPEAT_ONE; } +void codec_strip_filesize_callback(off_t size) +{ + if (bufstripsize(ci.audio_hid, size) >= 0) + ci.filesize = size; +} /** --- CODEC THREAD --- **/ @@ -647,6 +652,7 @@ void INIT_ATTR codec_thread_init(void) ci.configure = codec_configure_callback; ci.get_command = codec_get_command_callback; ci.loop_track = codec_loop_track_callback; + ci.strip_filesize = codec_strip_filesize_callback; /* Init threading */ queue_init(&codec_queue, false); diff --git a/apps/codecs.c b/apps/codecs.c index 3593501cbd..73c3b20fc1 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -89,6 +89,7 @@ struct codec_api ci = { NULL, /* configure */ NULL, /* get_command */ NULL, /* loop_track */ + NULL, /* strip_filesize */ /* kernel/ system */ #if defined(ARM_NEED_DIV0) diff --git a/lib/rbcodec/codecs/codecs.h b/lib/rbcodec/codecs/codecs.h index 7a1a83044e..7c3a301335 100644 --- a/lib/rbcodec/codecs/codecs.h +++ b/lib/rbcodec/codecs/codecs.h @@ -152,6 +152,7 @@ struct codec_api { long (*get_command)(intptr_t *param); /* Determine whether the track should be looped, if applicable. */ bool (*loop_track)(void); + void (*strip_filesize)(off_t value); /* kernel/ system */ #if defined(ARM_NEED_DIV0) diff --git a/lib/rbcodec/codecs/mpa.c b/lib/rbcodec/codecs/mpa.c index 354e8ce5e2..94b45c49f1 100644 --- a/lib/rbcodec/codecs/mpa.c +++ b/lib/rbcodec/codecs/mpa.c @@ -448,6 +448,11 @@ enum codec_status codec_run(void) ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); current_frequency = ci->id3->frequency; codec_set_replaygain(ci->id3); + if (!ci->id3->is_asf_stream) + { + // End of file might contain ID3v1 or APE tags. Strip them from decoding + ci->strip_filesize(ci->id3->first_frame_offset + ci->id3->filesize); + } if (ci->id3->offset) {