mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
Add support for ID3 tags embedded in AIFF files
Change-Id: I15eb50b6ba1c26052f08e01861f47faede3b9b3b
This commit is contained in:
parent
ff8cca70a4
commit
e884140eae
3 changed files with 43 additions and 5 deletions
|
@ -198,6 +198,10 @@ enum codec_status codec_run(void)
|
||||||
} else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
|
} else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
|
||||||
/* Format Version Chunk (AIFC only chunk) */
|
/* Format Version Chunk (AIFC only chunk) */
|
||||||
/* skip this 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 {
|
} else {
|
||||||
DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n",
|
DEBUGF("unsupported AIFF chunk: '%c%c%c%c', size=%lu\n",
|
||||||
buf[0], buf[1], buf[2], buf[3], (unsigned long)size);
|
buf[0], buf[1], buf[2], buf[3], (unsigned long)size);
|
||||||
|
|
|
@ -34,15 +34,24 @@
|
||||||
/* compressionType: AIFC QuickTime IMA ADPCM */
|
/* compressionType: AIFC QuickTime IMA ADPCM */
|
||||||
#define AIFC_FORMAT_QT_IMA_ADPCM "ima4"
|
#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)
|
bool get_aiff_metadata(int fd, struct mp3entry* id3)
|
||||||
{
|
{
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
unsigned long numChannels = 0;
|
unsigned long numChannels = 0;
|
||||||
unsigned long numSampleFrames = 0;
|
unsigned long numSampleFrames = 0;
|
||||||
unsigned long numbytes = 0;
|
unsigned long numbytes = 0;
|
||||||
|
unsigned long offset = 0;
|
||||||
bool is_aifc = false;
|
bool is_aifc = false;
|
||||||
char *p=id3->id3v2buf;
|
char *p=id3->id3v2buf;
|
||||||
|
|
||||||
|
|
||||||
if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, &buf[0], 12) < 12) ||
|
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) ||
|
(memcmp(&buf[0], "FORM", 4) != 0) || (memcmp(&buf[8], "AIF", 3) != 0) ||
|
||||||
(!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F'))
|
(!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F'))
|
||||||
|
@ -50,6 +59,7 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while (read(fd, &buf[0], 8) == 8)
|
while (read(fd, &buf[0], 8) == 8)
|
||||||
{
|
{
|
||||||
size_t size = get_long_be(&buf[4]); /* chunkSize */
|
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)
|
if (memcmp(&buf[0], "SSND", 4) == 0)
|
||||||
{
|
{
|
||||||
numbytes = size - 8;
|
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 */
|
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)
|
if (memcmp(&buf[0], "NAME", 4) == 0)
|
||||||
{
|
{
|
||||||
read_string(fd, p, 512, 20, size);
|
read_string(fd, p, 512, 0, size);
|
||||||
id3->title=p;
|
id3->title=p;
|
||||||
p+=size;
|
p+=size;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (memcmp(&buf[0], "AUTH", 4) == 0)
|
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;
|
id3->artist=p;
|
||||||
p+=size;
|
p+=size;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (memcmp(&buf[0], "ANNO", 4) == 0)
|
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;
|
id3->comment=p;
|
||||||
p+=size;
|
p+=size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (memcmp(&buf[0], "ID3", 3) == 0)
|
||||||
|
{
|
||||||
|
read_id3_tags(fd, id3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
else if (memcmp(&buf[0], "COMM", 4) == 0)
|
else if (memcmp(&buf[0], "COMM", 4) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -717,6 +717,9 @@ bool setid3v1title(int fd, struct mp3entry *entry)
|
||||||
* entry - the entry to set the title in
|
* entry - the entry to set the title in
|
||||||
*
|
*
|
||||||
* Returns: true if a title was found and created, else false
|
* 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)
|
void setid3v2title(int fd, struct mp3entry *entry)
|
||||||
{
|
{
|
||||||
|
@ -749,8 +752,9 @@ void setid3v2title(int fd, struct mp3entry *entry)
|
||||||
if(entry->id3v2len < 10)
|
if(entry->id3v2len < 10)
|
||||||
return;
|
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))
|
if(10 != read(fd, header, 10))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1177,12 +1181,15 @@ int getid3v2len(int fd)
|
||||||
|
|
||||||
/* Now check what the ID3v2 size field says */
|
/* Now check what the ID3v2 size field says */
|
||||||
else
|
else
|
||||||
|
{
|
||||||
if(read(fd, buf, 4) != 4)
|
if(read(fd, buf, 4) != 4)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
else
|
else
|
||||||
offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10;
|
offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10;
|
||||||
|
}
|
||||||
|
|
||||||
logf("ID3V2 Length: 0x%x", offset);
|
logf("ID3V2 Length: 0x%x", offset);
|
||||||
|
lseek(fd, -10, SEEK_CUR);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue