summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec
diff options
context:
space:
mode:
authorMoshe Piekarski <dev.rockbox@melachim.net>2020-06-24 05:53:44 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-07-15 18:30:07 +0000
commite884140eae2b093cc33dae3af20fc72ab621c518 (patch)
treed0ace2d21481bebc5598af23860507c023280dbb /lib/rbcodec
parentff8cca70a4651e6a9db9599d3778d7b5d7926d96 (diff)
downloadrockbox-e884140eae2b093cc33dae3af20fc72ab621c518.tar.gz
rockbox-e884140eae2b093cc33dae3af20fc72ab621c518.zip
Add support for ID3 tags embedded in AIFF files
Change-Id: I15eb50b6ba1c26052f08e01861f47faede3b9b3b
Diffstat (limited to 'lib/rbcodec')
-rw-r--r--lib/rbcodec/codecs/aiff.c4
-rw-r--r--lib/rbcodec/metadata/aiff.c33
-rw-r--r--lib/rbcodec/metadata/id3tags.c11
3 files changed, 43 insertions, 5 deletions
diff --git a/lib/rbcodec/codecs/aiff.c b/lib/rbcodec/codecs/aiff.c
index 2900ed2ecb..a82ae5f2e2 100644
--- a/lib/rbcodec/codecs/aiff.c
+++ b/lib/rbcodec/codecs/aiff.c
@@ -198,6 +198,10 @@ enum codec_status codec_run(void)
} else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
/* Format Version Chunk (AIFC only chunk) */
/* skip this chunk */
+ } else if ( (memcmp(buf, "NAME", 4)==0) || (memcmp(buf, "AUTH", 4)==0)
+ || (memcmp(buf, "ANNO", 4)==0)) {
+ /* Text chunks containing only metadata */
+ /* skip this chunk */
} else {
DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n",
buf[0], buf[1], buf[2], buf[3], (unsigned long)size);
diff --git a/lib/rbcodec/metadata/aiff.c b/lib/rbcodec/metadata/aiff.c
index 1bb95f3ed2..eb0b5589d9 100644
--- a/lib/rbcodec/metadata/aiff.c
+++ b/lib/rbcodec/metadata/aiff.c
@@ -34,15 +34,24 @@
/* compressionType: AIFC QuickTime IMA ADPCM */
#define AIFC_FORMAT_QT_IMA_ADPCM "ima4"
+static void read_id3_tags(int fd, struct mp3entry* id3)
+{
+ id3->tracknum = 0;
+ id3->discnum = 0;
+ setid3v2title(fd, id3);
+}
+
bool get_aiff_metadata(int fd, struct mp3entry* id3)
{
unsigned char buf[512];
unsigned long numChannels = 0;
unsigned long numSampleFrames = 0;
unsigned long numbytes = 0;
+ unsigned long offset = 0;
bool is_aifc = false;
char *p=id3->id3v2buf;
+
if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, &buf[0], 12) < 12) ||
(memcmp(&buf[0], "FORM", 4) != 0) || (memcmp(&buf[8], "AIF", 3) != 0) ||
(!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F'))
@@ -50,6 +59,7 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
return false;
}
+
while (read(fd, &buf[0], 8) == 8)
{
size_t size = get_long_be(&buf[4]); /* chunkSize */
@@ -57,6 +67,18 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
if (memcmp(&buf[0], "SSND", 4) == 0)
{
numbytes = size - 8;
+
+ /* check for ID3 tag */
+ offset=lseek(fd, 0, SEEK_CUR);
+ lseek(fd, size, SEEK_CUR);
+ if ((read(fd, &buf[0], 8) == 8) && (memcmp(&buf[0], "ID3", 3) == 0))
+ {
+ id3->id3v2len = get_long_be(&buf[4]);
+ read_id3_tags(fd, id3);
+ }
+ else
+ DEBUGF("ID3 tag not present immediately after sound data");
+ lseek(fd, offset, SEEK_SET);
break; /* assume COMM was already read */
}
@@ -72,25 +94,30 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
if (memcmp(&buf[0], "NAME", 4) == 0)
{
- read_string(fd, p, 512, 20, size);
+ read_string(fd, p, 512, 0, size);
id3->title=p;
p+=size;
}
else if (memcmp(&buf[0], "AUTH", 4) == 0)
{
- read_string(fd, p, 512, 20, size);
+ read_string(fd, p, 512, 0, size);
id3->artist=p;
p+=size;
}
else if (memcmp(&buf[0], "ANNO", 4) == 0)
{
- read_string(fd, p, 512, 20, size);
+ read_string(fd, p, 512, 0, size);
id3->comment=p;
p+=size;
}
+ else if (memcmp(&buf[0], "ID3", 3) == 0)
+ {
+ read_id3_tags(fd, id3);
+ }
+
else if (memcmp(&buf[0], "COMM", 4) == 0)
{
diff --git a/lib/rbcodec/metadata/id3tags.c b/lib/rbcodec/metadata/id3tags.c
index 8236244d79..84b3c593ef 100644
--- a/lib/rbcodec/metadata/id3tags.c
+++ b/lib/rbcodec/metadata/id3tags.c
@@ -717,6 +717,9 @@ bool setid3v1title(int fd, struct mp3entry *entry)
* entry - the entry to set the title in
*
* Returns: true if a title was found and created, else false
+ *
+ * Assumes that the offset of file is at the start of the ID3 header.
+ * (if the header is at the begining of the file getid3v2len() will ensure this.)
*/
void setid3v2title(int fd, struct mp3entry *entry)
{
@@ -749,8 +752,9 @@ void setid3v2title(int fd, struct mp3entry *entry)
if(entry->id3v2len < 10)
return;
- /* Read the ID3 tag version from the header */
- lseek(fd, 0, SEEK_SET);
+
+ /* Read the ID3 tag version from the header.
+ Assumes fd is already at the begining of the header */
if(10 != read(fd, header, 10))
return;
@@ -1177,12 +1181,15 @@ int getid3v2len(int fd)
/* Now check what the ID3v2 size field says */
else
+ {
if(read(fd, buf, 4) != 4)
offset = 0;
else
offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10;
+ }
logf("ID3V2 Length: 0x%x", offset);
+ lseek(fd, -10, SEEK_CUR);
return offset;
}