From e884140eae2b093cc33dae3af20fc72ab621c518 Mon Sep 17 00:00:00 2001 From: Moshe Piekarski Date: Wed, 24 Jun 2020 05:53:44 -0400 Subject: Add support for ID3 tags embedded in AIFF files Change-Id: I15eb50b6ba1c26052f08e01861f47faede3b9b3b --- lib/rbcodec/codecs/aiff.c | 4 ++++ lib/rbcodec/metadata/aiff.c | 33 ++++++++++++++++++++++++++++++--- lib/rbcodec/metadata/id3tags.c | 11 +++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) (limited to 'lib/rbcodec') 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; } -- cgit v1.2.3