summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/buffering.c53
-rw-r--r--apps/buffering.h7
-rw-r--r--apps/metadata.c42
-rw-r--r--apps/metadata.h1
-rw-r--r--apps/playback.c4
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
1142ssize_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
1172ssize_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/*
1142SECONDARY EXPORTED FUNCTIONS 1195SECONDARY 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);
82int bufadvance(int handle_id, off_t offset); 87int bufadvance(int handle_id, off_t offset);
83ssize_t bufread(int handle_id, size_t size, void *dest); 88ssize_t bufread(int handle_id, size_t size, void *dest);
84ssize_t bufgetdata(int handle_id, size_t size, void **data); 89ssize_t bufgetdata(int handle_id, size_t size, void **data);
90ssize_t bufgettail(int handle_id, size_t size, void **data);
91ssize_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
328void 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
347strip_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
25unsigned int probe_file_format(const char *filename); 25unsigned int probe_file_format(const char *filename);
26bool get_metadata(struct mp3entry* id3, int fd, const char* trackname); 26bool get_metadata(struct mp3entry* id3, int fd, const char* trackname);
27void 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 }