summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMark Arigo <markarigo@gmail.com>2006-11-14 15:48:20 +0000
committerMark Arigo <markarigo@gmail.com>2006-11-14 15:48:20 +0000
commit9b0ef15c0de787b41b378be88bd01001c1ba3d2d (patch)
tree96563fb423eedf11316af981c3e5159a23e13752 /apps
parent7bc41203afbf8a69dec331d304a226cb70484855 (diff)
downloadrockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.zip
rockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.tar.gz
rockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.tar.bz2
rockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.tar.xz
Strip APE tags during buffering so they do not break MP3 gapless playback.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11525 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/playback.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/apps/playback.c b/apps/playback.c
index bacafc3..8f4e4a6 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -2215,12 +2215,14 @@ static void audio_clear_track_entries(bool clear_unbuffered)
}
/* FIXME: This code should be made more generic and move to metadata.c */
-static void audio_strip_id3v1_tag(void)
+static void audio_strip_tags(void)
{
int i;
static const unsigned char tag[] = "TAG";
+ static const unsigned char apetag[] = "APETAGEX";
size_t tag_idx;
size_t cur_idx;
+ size_t len, version;
tag_idx = RINGBUF_SUB(buf_widx, 128);
@@ -2230,7 +2232,7 @@ static void audio_strip_id3v1_tag(void)
for(i = 0;i < 3;i++)
{
if(filebuf[cur_idx] != tag[i])
- return;
+ goto strip_ape_tag;
cur_idx = RINGBUF_ADD(cur_idx, 1);
}
@@ -2241,6 +2243,37 @@ static void audio_strip_id3v1_tag(void)
tracks[track_widx].available -= 128;
tracks[track_widx].filesize -= 128;
}
+
+strip_ape_tag:
+ /* Check for APE tag (look for the APE tag footer) */
+ tag_idx = RINGBUF_SUB(buf_widx, 32);
+
+ if (FILEBUFUSED > 32 && tag_idx > buf_ridx)
+ {
+ cur_idx = tag_idx;
+ for(i = 0;i < 8;i++)
+ {
+ if(filebuf[cur_idx] != apetag[i])
+ return;
+
+ cur_idx = RINGBUF_ADD(cur_idx, 1);
+ }
+
+ /* Read the version and length from the footer */
+ version = letoh32(*(long *)(filebuf + tag_idx + 8));
+ len = letoh32(*(long *)(filebuf + tag_idx + 12));
+ if (version == 2000)
+ len += 32; /* APEv2 has a 32 byte header */
+
+ /* Skip APE tag */
+ if (FILEBUFUSED > len)
+ {
+ logf("Skipping APE tag (%dB)", len);
+ buf_widx = RINGBUF_SUB(buf_widx, len);
+ tracks[track_widx].available -= len;
+ tracks[track_widx].filesize -= len;
+ }
+ }
}
/* Returns true if a whole file is read, false otherwise */
@@ -2332,7 +2365,7 @@ static bool audio_read_file(size_t minimum)
logf("Finished buf:%dB", tracks[track_widx].filesize);
close(current_fd);
current_fd = -1;
- audio_strip_id3v1_tag();
+ audio_strip_tags();
track_widx++;
track_widx &= MAX_TRACK_MASK;