summaryrefslogtreecommitdiff
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
parentff8cca70a4651e6a9db9599d3778d7b5d7926d96 (diff)
downloadrockbox-e884140eae2b093cc33dae3af20fc72ab621c518.tar.gz
rockbox-e884140eae2b093cc33dae3af20fc72ab621c518.zip
Add support for ID3 tags embedded in AIFF files
Change-Id: I15eb50b6ba1c26052f08e01861f47faede3b9b3b
-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)
198 } else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) { 198 } else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
199 /* Format Version Chunk (AIFC only chunk) */ 199 /* Format Version Chunk (AIFC only chunk) */
200 /* skip this chunk */ 200 /* skip this chunk */
201 } else if ( (memcmp(buf, "NAME", 4)==0) || (memcmp(buf, "AUTH", 4)==0)
202 || (memcmp(buf, "ANNO", 4)==0)) {
203 /* Text chunks containing only metadata */
204 /* skip this chunk */
201 } else { 205 } else {
202 DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n", 206 DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n",
203 buf[0], buf[1], buf[2], buf[3], (unsigned long)size); 207 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 @@
34/* compressionType: AIFC QuickTime IMA ADPCM */ 34/* compressionType: AIFC QuickTime IMA ADPCM */
35#define AIFC_FORMAT_QT_IMA_ADPCM "ima4" 35#define AIFC_FORMAT_QT_IMA_ADPCM "ima4"
36 36
37static void read_id3_tags(int fd, struct mp3entry* id3)
38{
39 id3->tracknum = 0;
40 id3->discnum = 0;
41 setid3v2title(fd, id3);
42}
43
37bool get_aiff_metadata(int fd, struct mp3entry* id3) 44bool get_aiff_metadata(int fd, struct mp3entry* id3)
38{ 45{
39 unsigned char buf[512]; 46 unsigned char buf[512];
40 unsigned long numChannels = 0; 47 unsigned long numChannels = 0;
41 unsigned long numSampleFrames = 0; 48 unsigned long numSampleFrames = 0;
42 unsigned long numbytes = 0; 49 unsigned long numbytes = 0;
50 unsigned long offset = 0;
43 bool is_aifc = false; 51 bool is_aifc = false;
44 char *p=id3->id3v2buf; 52 char *p=id3->id3v2buf;
45 53
54
46 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, &buf[0], 12) < 12) || 55 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, &buf[0], 12) < 12) ||
47 (memcmp(&buf[0], "FORM", 4) != 0) || (memcmp(&buf[8], "AIF", 3) != 0) || 56 (memcmp(&buf[0], "FORM", 4) != 0) || (memcmp(&buf[8], "AIF", 3) != 0) ||
48 (!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F')) 57 (!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F'))
@@ -50,6 +59,7 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
50 return false; 59 return false;
51 } 60 }
52 61
62
53 while (read(fd, &buf[0], 8) == 8) 63 while (read(fd, &buf[0], 8) == 8)
54 { 64 {
55 size_t size = get_long_be(&buf[4]); /* chunkSize */ 65 size_t size = get_long_be(&buf[4]); /* chunkSize */
@@ -57,6 +67,18 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
57 if (memcmp(&buf[0], "SSND", 4) == 0) 67 if (memcmp(&buf[0], "SSND", 4) == 0)
58 { 68 {
59 numbytes = size - 8; 69 numbytes = size - 8;
70
71 /* check for ID3 tag */
72 offset=lseek(fd, 0, SEEK_CUR);
73 lseek(fd, size, SEEK_CUR);
74 if ((read(fd, &buf[0], 8) == 8) && (memcmp(&buf[0], "ID3", 3) == 0))
75 {
76 id3->id3v2len = get_long_be(&buf[4]);
77 read_id3_tags(fd, id3);
78 }
79 else
80 DEBUGF("ID3 tag not present immediately after sound data");
81 lseek(fd, offset, SEEK_SET);
60 break; /* assume COMM was already read */ 82 break; /* assume COMM was already read */
61 } 83 }
62 84
@@ -72,25 +94,30 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
72 94
73 if (memcmp(&buf[0], "NAME", 4) == 0) 95 if (memcmp(&buf[0], "NAME", 4) == 0)
74 { 96 {
75 read_string(fd, p, 512, 20, size); 97 read_string(fd, p, 512, 0, size);
76 id3->title=p; 98 id3->title=p;
77 p+=size; 99 p+=size;
78 } 100 }
79 101
80 else if (memcmp(&buf[0], "AUTH", 4) == 0) 102 else if (memcmp(&buf[0], "AUTH", 4) == 0)
81 { 103 {
82 read_string(fd, p, 512, 20, size); 104 read_string(fd, p, 512, 0, size);
83 id3->artist=p; 105 id3->artist=p;
84 p+=size; 106 p+=size;
85 } 107 }
86 108
87 else if (memcmp(&buf[0], "ANNO", 4) == 0) 109 else if (memcmp(&buf[0], "ANNO", 4) == 0)
88 { 110 {
89 read_string(fd, p, 512, 20, size); 111 read_string(fd, p, 512, 0, size);
90 id3->comment=p; 112 id3->comment=p;
91 p+=size; 113 p+=size;
92 } 114 }
93 115
116 else if (memcmp(&buf[0], "ID3", 3) == 0)
117 {
118 read_id3_tags(fd, id3);
119 }
120
94 121
95 else if (memcmp(&buf[0], "COMM", 4) == 0) 122 else if (memcmp(&buf[0], "COMM", 4) == 0)
96 { 123 {
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)
717 * entry - the entry to set the title in 717 * entry - the entry to set the title in
718 * 718 *
719 * Returns: true if a title was found and created, else false 719 * Returns: true if a title was found and created, else false
720 *
721 * Assumes that the offset of file is at the start of the ID3 header.
722 * (if the header is at the begining of the file getid3v2len() will ensure this.)
720 */ 723 */
721void setid3v2title(int fd, struct mp3entry *entry) 724void setid3v2title(int fd, struct mp3entry *entry)
722{ 725{
@@ -749,8 +752,9 @@ void setid3v2title(int fd, struct mp3entry *entry)
749 if(entry->id3v2len < 10) 752 if(entry->id3v2len < 10)
750 return; 753 return;
751 754
752 /* Read the ID3 tag version from the header */ 755
753 lseek(fd, 0, SEEK_SET); 756 /* Read the ID3 tag version from the header.
757 Assumes fd is already at the begining of the header */
754 if(10 != read(fd, header, 10)) 758 if(10 != read(fd, header, 10))
755 return; 759 return;
756 760
@@ -1177,12 +1181,15 @@ int getid3v2len(int fd)
1177 1181
1178 /* Now check what the ID3v2 size field says */ 1182 /* Now check what the ID3v2 size field says */
1179 else 1183 else
1184 {
1180 if(read(fd, buf, 4) != 4) 1185 if(read(fd, buf, 4) != 4)
1181 offset = 0; 1186 offset = 0;
1182 else 1187 else
1183 offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10; 1188 offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10;
1189 }
1184 1190
1185 logf("ID3V2 Length: 0x%x", offset); 1191 logf("ID3V2 Length: 0x%x", offset);
1192 lseek(fd, -10, SEEK_CUR);
1186 return offset; 1193 return offset;
1187} 1194}
1188 1195