summaryrefslogtreecommitdiff
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
parent7bc41203afbf8a69dec331d304a226cb70484855 (diff)
downloadrockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.tar.gz
rockbox-9b0ef15c0de787b41b378be88bd01001c1ba3d2d.zip
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
-rw-r--r--apps/playback.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/apps/playback.c b/apps/playback.c
index bacafc30b5..8f4e4a6d0a 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -2215,12 +2215,14 @@ static void audio_clear_track_entries(bool clear_unbuffered)
2215} 2215}
2216 2216
2217/* FIXME: This code should be made more generic and move to metadata.c */ 2217/* FIXME: This code should be made more generic and move to metadata.c */
2218static void audio_strip_id3v1_tag(void) 2218static void audio_strip_tags(void)
2219{ 2219{
2220 int i; 2220 int i;
2221 static const unsigned char tag[] = "TAG"; 2221 static const unsigned char tag[] = "TAG";
2222 static const unsigned char apetag[] = "APETAGEX";
2222 size_t tag_idx; 2223 size_t tag_idx;
2223 size_t cur_idx; 2224 size_t cur_idx;
2225 size_t len, version;
2224 2226
2225 tag_idx = RINGBUF_SUB(buf_widx, 128); 2227 tag_idx = RINGBUF_SUB(buf_widx, 128);
2226 2228
@@ -2230,7 +2232,7 @@ static void audio_strip_id3v1_tag(void)
2230 for(i = 0;i < 3;i++) 2232 for(i = 0;i < 3;i++)
2231 { 2233 {
2232 if(filebuf[cur_idx] != tag[i]) 2234 if(filebuf[cur_idx] != tag[i])
2233 return; 2235 goto strip_ape_tag;
2234 2236
2235 cur_idx = RINGBUF_ADD(cur_idx, 1); 2237 cur_idx = RINGBUF_ADD(cur_idx, 1);
2236 } 2238 }
@@ -2241,6 +2243,37 @@ static void audio_strip_id3v1_tag(void)
2241 tracks[track_widx].available -= 128; 2243 tracks[track_widx].available -= 128;
2242 tracks[track_widx].filesize -= 128; 2244 tracks[track_widx].filesize -= 128;
2243 } 2245 }
2246
2247strip_ape_tag:
2248 /* Check for APE tag (look for the APE tag footer) */
2249 tag_idx = RINGBUF_SUB(buf_widx, 32);
2250
2251 if (FILEBUFUSED > 32 && tag_idx > buf_ridx)
2252 {
2253 cur_idx = tag_idx;
2254 for(i = 0;i < 8;i++)
2255 {
2256 if(filebuf[cur_idx] != apetag[i])
2257 return;
2258
2259 cur_idx = RINGBUF_ADD(cur_idx, 1);
2260 }
2261
2262 /* Read the version and length from the footer */
2263 version = letoh32(*(long *)(filebuf + tag_idx + 8));
2264 len = letoh32(*(long *)(filebuf + tag_idx + 12));
2265 if (version == 2000)
2266 len += 32; /* APEv2 has a 32 byte header */
2267
2268 /* Skip APE tag */
2269 if (FILEBUFUSED > len)
2270 {
2271 logf("Skipping APE tag (%dB)", len);
2272 buf_widx = RINGBUF_SUB(buf_widx, len);
2273 tracks[track_widx].available -= len;
2274 tracks[track_widx].filesize -= len;
2275 }
2276 }
2244} 2277}
2245 2278
2246/* Returns true if a whole file is read, false otherwise */ 2279/* Returns true if a whole file is read, false otherwise */
@@ -2332,7 +2365,7 @@ static bool audio_read_file(size_t minimum)
2332 logf("Finished buf:%dB", tracks[track_widx].filesize); 2365 logf("Finished buf:%dB", tracks[track_widx].filesize);
2333 close(current_fd); 2366 close(current_fd);
2334 current_fd = -1; 2367 current_fd = -1;
2335 audio_strip_id3v1_tag(); 2368 audio_strip_tags();
2336 2369
2337 track_widx++; 2370 track_widx++;
2338 track_widx &= MAX_TRACK_MASK; 2371 track_widx &= MAX_TRACK_MASK;