diff options
author | Brandon Low <lostlogic@rockbox.org> | 2007-11-28 04:58:16 +0000 |
---|---|---|
committer | Brandon Low <lostlogic@rockbox.org> | 2007-11-28 04:58:16 +0000 |
commit | 3386dd7be90f4f4a23d36359f2052fa834fb20e7 (patch) | |
tree | 4765c534909e8d55455872bf7b0b2b1e464ff2c5 /apps | |
parent | 05784b52abb3d21dfe0e7b1e014e601ce1d10803 (diff) | |
download | rockbox-3386dd7be90f4f4a23d36359f2052fa834fb20e7.tar.gz rockbox-3386dd7be90f4f4a23d36359f2052fa834fb20e7.zip |
Fix FS8069, because Nico_P made it easy
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15840 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/buffering.c | 53 | ||||
-rw-r--r-- | apps/buffering.h | 7 | ||||
-rw-r--r-- | apps/metadata.c | 42 | ||||
-rw-r--r-- | apps/metadata.h | 1 | ||||
-rw-r--r-- | apps/playback.c | 4 |
5 files changed, 107 insertions, 0 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index f0a50c274c..f5bc2eeb19 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -657,6 +657,7 @@ static bool buffer_handle(int handle_id) | |||
657 | /* finished buffering the file */ | 657 | /* finished buffering the file */ |
658 | close(h->fd); | 658 | close(h->fd); |
659 | h->fd = -1; | 659 | h->fd = -1; |
660 | call_buffering_callbacks(EVENT_HANDLE_FINISHED, h->id); | ||
660 | } | 661 | } |
661 | 662 | ||
662 | return true; | 663 | return true; |
@@ -1138,6 +1139,58 @@ ssize_t bufgetdata(int handle_id, size_t size, void **data) | |||
1138 | return size; | 1139 | return size; |
1139 | } | 1140 | } |
1140 | 1141 | ||
1142 | ssize_t bufgettail(int handle_id, size_t size, void **data) | ||
1143 | { | ||
1144 | size_t tidx; | ||
1145 | |||
1146 | const struct memory_handle *h; | ||
1147 | |||
1148 | h = find_handle(handle_id); | ||
1149 | |||
1150 | if (!h) | ||
1151 | return ERR_HANDLE_NOT_FOUND; | ||
1152 | |||
1153 | if (h->filerem) | ||
1154 | return ERR_HANDLE_NOT_DONE; | ||
1155 | |||
1156 | /* We don't support tail requests of > guardbuf_size, for simplicity */ | ||
1157 | if (size > GUARD_BUFSIZE) | ||
1158 | return ERR_INVALID_VALUE; | ||
1159 | |||
1160 | tidx = RINGBUF_SUB(h->widx, size); | ||
1161 | |||
1162 | if (tidx + size > buffer_len) | ||
1163 | { | ||
1164 | size_t copy_n = tidx + size - buffer_len; | ||
1165 | memcpy(guard_buffer, (unsigned char *)buffer, copy_n); | ||
1166 | } | ||
1167 | |||
1168 | *data = &buffer[tidx]; | ||
1169 | return size; | ||
1170 | } | ||
1171 | |||
1172 | ssize_t bufcuttail(int handle_id, size_t size) | ||
1173 | { | ||
1174 | struct memory_handle *h; | ||
1175 | |||
1176 | h = find_handle(handle_id); | ||
1177 | |||
1178 | if (!h) | ||
1179 | return ERR_HANDLE_NOT_FOUND; | ||
1180 | |||
1181 | if (h->filerem) | ||
1182 | return ERR_HANDLE_NOT_DONE; | ||
1183 | |||
1184 | if (h->available < size) | ||
1185 | size = h->available; | ||
1186 | |||
1187 | h->available -= size; | ||
1188 | h->filesize -= size; | ||
1189 | h->widx = RINGBUF_SUB(h->widx, size); | ||
1190 | return size; | ||
1191 | } | ||
1192 | |||
1193 | |||
1141 | /* | 1194 | /* |
1142 | SECONDARY EXPORTED FUNCTIONS | 1195 | SECONDARY EXPORTED FUNCTIONS |
1143 | ============================ | 1196 | ============================ |
diff --git a/apps/buffering.h b/apps/buffering.h index f6a9f7883b..bc61ec5e6d 100644 --- a/apps/buffering.h +++ b/apps/buffering.h | |||
@@ -41,6 +41,7 @@ enum callback_event { | |||
41 | EVENT_HANDLE_REBUFFER, | 41 | EVENT_HANDLE_REBUFFER, |
42 | EVENT_HANDLE_CLOSED, | 42 | EVENT_HANDLE_CLOSED, |
43 | EVENT_HANDLE_MOVED, | 43 | EVENT_HANDLE_MOVED, |
44 | EVENT_HANDLE_FINISHED, | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | /* Error return values */ | 47 | /* Error return values */ |
@@ -48,6 +49,7 @@ enum callback_event { | |||
48 | #define ERR_BUFFER_FULL -2 | 49 | #define ERR_BUFFER_FULL -2 |
49 | #define ERR_INVALID_VALUE -3 | 50 | #define ERR_INVALID_VALUE -3 |
50 | #define ERR_FILE_ERROR -4 | 51 | #define ERR_FILE_ERROR -4 |
52 | #define ERR_HANDLE_NOT_DONE -5 | ||
51 | 53 | ||
52 | 54 | ||
53 | /* Initialise the buffering subsystem */ | 55 | /* Initialise the buffering subsystem */ |
@@ -68,9 +70,12 @@ bool buffering_reset(char *buf, size_t buflen); | |||
68 | * bufadvance: Move handle reading index, relatively to current position | 70 | * bufadvance: Move handle reading index, relatively to current position |
69 | * bufread : Copy data from a handle to a buffer | 71 | * bufread : Copy data from a handle to a buffer |
70 | * bufgetdata: Obtain a pointer for linear access to a "size" amount of data | 72 | * bufgetdata: Obtain a pointer for linear access to a "size" amount of data |
73 | * bufgettail: Out-of-band get the last size bytes of a handle. | ||
74 | * bufcuttail: Out-of-band remove the trailing 'size' bytes of a handle. | ||
71 | * | 75 | * |
72 | * NOTE: bufread and bufgetdata will block the caller until the requested | 76 | * NOTE: bufread and bufgetdata will block the caller until the requested |
73 | * amount of data is ready (unless EOF is reached). | 77 | * amount of data is ready (unless EOF is reached). |
78 | * NOTE: Tail operations are only legal when the end of the file is buffered. | ||
74 | ****************************************************************************/ | 79 | ****************************************************************************/ |
75 | 80 | ||
76 | #define BUF_MAX_HANDLES 256 | 81 | #define BUF_MAX_HANDLES 256 |
@@ -82,6 +87,8 @@ int bufseek(int handle_id, size_t newpos); | |||
82 | int bufadvance(int handle_id, off_t offset); | 87 | int bufadvance(int handle_id, off_t offset); |
83 | ssize_t bufread(int handle_id, size_t size, void *dest); | 88 | ssize_t bufread(int handle_id, size_t size, void *dest); |
84 | ssize_t bufgetdata(int handle_id, size_t size, void **data); | 89 | ssize_t bufgetdata(int handle_id, size_t size, void **data); |
90 | ssize_t bufgettail(int handle_id, size_t size, void **data); | ||
91 | ssize_t bufcuttail(int handle_id, size_t size); | ||
85 | 92 | ||
86 | 93 | ||
87 | /*************************************************************************** | 94 | /*************************************************************************** |
diff --git a/apps/metadata.c b/apps/metadata.c index 66719754ad..3a0ff574bf 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -30,6 +30,9 @@ | |||
30 | 30 | ||
31 | #if CONFIG_CODEC == SWCODEC | 31 | #if CONFIG_CODEC == SWCODEC |
32 | 32 | ||
33 | /* For trailing tag stripping */ | ||
34 | #include "buffering.h" | ||
35 | |||
33 | #include "metadata/metadata_common.h" | 36 | #include "metadata/metadata_common.h" |
34 | #include "metadata/metadata_parsers.h" | 37 | #include "metadata/metadata_parsers.h" |
35 | 38 | ||
@@ -322,3 +325,42 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname) | |||
322 | return true; | 325 | return true; |
323 | } | 326 | } |
324 | 327 | ||
328 | void strip_tags(int handle_id) | ||
329 | { | ||
330 | int i; | ||
331 | static const unsigned char tag[] = "TAG"; | ||
332 | static const unsigned char apetag[] = "APETAGEX"; | ||
333 | size_t len, version; | ||
334 | unsigned char *tail; | ||
335 | |||
336 | if (bufgettail(handle_id, 128, (void **)&tail) != 128) | ||
337 | return; | ||
338 | |||
339 | for(i = 0;i < 3;i++) | ||
340 | if(tail[i] != tag[i]) | ||
341 | goto strip_ape_tag; | ||
342 | |||
343 | /* Skip id3v1 tag */ | ||
344 | logf("Cutting off ID3v1 tag"); | ||
345 | bufcuttail(handle_id, 128); | ||
346 | |||
347 | strip_ape_tag: | ||
348 | /* Check for APE tag (look for the APE tag footer) */ | ||
349 | |||
350 | if (bufgettail(handle_id, 32, (void **)&tail) != 32) | ||
351 | return; | ||
352 | |||
353 | for(i = 0;i < 8;i++) | ||
354 | if(tail[i] != apetag[i]) | ||
355 | return; | ||
356 | |||
357 | /* Read the version and length from the footer */ | ||
358 | version = tail[8] | (tail[9] << 8) | (tail[10] << 16) | (tail[11] << 24); | ||
359 | len = tail[12] | (tail[13] << 8) | (tail[14] << 16) | (tail[15] << 24); | ||
360 | if (version == 2000) | ||
361 | len += 32; /* APEv2 has a 32 byte header */ | ||
362 | |||
363 | /* Skip APE tag */ | ||
364 | logf("Cutting off APE tag (%ldB)", len); | ||
365 | bufcuttail(handle_id, len); | ||
366 | } | ||
diff --git a/apps/metadata.h b/apps/metadata.h index f07209f2dc..11d85942ed 100644 --- a/apps/metadata.h +++ b/apps/metadata.h | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | unsigned int probe_file_format(const char *filename); | 25 | unsigned int probe_file_format(const char *filename); |
26 | bool get_metadata(struct mp3entry* id3, int fd, const char* trackname); | 26 | bool get_metadata(struct mp3entry* id3, int fd, const char* trackname); |
27 | void strip_tags(int handle_id); | ||
27 | 28 | ||
28 | #endif | 29 | #endif |
29 | 30 | ||
diff --git a/apps/playback.c b/apps/playback.c index a19c2d745a..8467614329 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -1485,6 +1485,10 @@ static void buffering_audio_callback(enum callback_event ev, int value) | |||
1485 | queue_send(&audio_queue, Q_AUDIO_FLUSH, 0); | 1485 | queue_send(&audio_queue, Q_AUDIO_FLUSH, 0); |
1486 | break; | 1486 | break; |
1487 | 1487 | ||
1488 | case EVENT_HANDLE_FINISHED: | ||
1489 | strip_tags(value); | ||
1490 | break; | ||
1491 | |||
1488 | default: | 1492 | default: |
1489 | break; | 1493 | break; |
1490 | } | 1494 | } |