diff options
author | Adam Boot <rotator@gmail.com> | 2007-03-03 06:08:28 +0000 |
---|---|---|
committer | Adam Boot <rotator@gmail.com> | 2007-03-03 06:08:28 +0000 |
commit | b9a71b305b98a87f747dc1e0cc91324b73693fd1 (patch) | |
tree | c6e033835b4fc63ad0955ea3124f4b699cc9fd69 /apps/metadata.c | |
parent | 411f8198b46764a7c29030f8da1da90dc332308c (diff) |
Add get_metadata() and year & comment tag support for SPC.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12563 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index 84ee37c2fe..42ae435aea 100644 --- a/apps/metadata.c +++ b/apps/metadata.c @@ -33,6 +33,7 @@ #include "system.h" #include "cuesheet.h" #include "structec.h" +#include "settings.h" enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS }; @@ -1858,6 +1859,104 @@ static bool get_adx_metadata(int fd, struct mp3entry* id3) return true; } +static bool get_spc_metadata(int fd, struct mp3entry* id3) +{ + /* Use the trackname part of the id3 structure as a temporary buffer */ + unsigned char * buf = (unsigned char *)id3->path; + int read_bytes; + char * p; + + unsigned long length; + unsigned long fade; + bool isbinary = true; + int i; + + /* try to get the ID666 tag */ + if ((lseek(fd, 0x2e, SEEK_SET) < 0) + || ((read_bytes = read(fd, buf, 0xD2)) < 0xD2)) + { + DEBUGF("lseek or read failed\n"); + return false; + } + + p = id3->id3v2buf; + + id3->title = p; + buf[31] = 0; + p = iso_decode(buf, p, 0, 32); + buf += 32; + + id3->album = p; + buf[31] = 0; + p = iso_decode(buf, p, 0, 32); + buf += 48; + + id3->comment = p; + buf[31] = 0; + p = iso_decode(buf, p, 0, 32); + buf += 32; + + /* Date check */ + if(buf[2] == '/' && buf[5] == '/') + isbinary = false; + + /* Reserved bytes check */ + if(buf[0xD2 - 0x2E - 112] >= '0' && + buf[0xD2 - 0x2E - 112] <= '9' && + buf[0xD3 - 0x2E - 112] == 0x00) + isbinary = false; + + /* is length & fade only digits? */ + for (i=0;i<8 && ( + (buf[0xA9 - 0x2E - 112+i]>='0'&&buf[0xA9 - 0x2E - 112+i]<='9') || + buf[0xA9 - 0x2E - 112+i]=='\0'); + i++); + if (i==8) isbinary = false; + + if(isbinary) { + unsigned char * tbuf = buf; + + id3->year = tbuf[0] | (tbuf[1]<<8); + buf += 11; + + length = (buf[0] | (buf[1]<<8) | (buf[2]<<16)) * 1000; + buf += 3; + + fade = (buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24)); + buf += 4; + } else { + char tbuf[6]; + + buf += 6; + buf[4] = 0; + id3->year = atoi(buf); + buf += 5; + + memcpy(tbuf, buf, 3); + tbuf[3] = 0; + length = atoi(tbuf) * 1000; + buf += 3; + + memcpy(tbuf, buf, 5); + tbuf[5] = 0; + fade = atoi(tbuf); + buf += 5; + } + + id3->artist = p; + buf[31] = 0; + p = iso_decode(buf, p, 0, 32); + + if (global_settings.repeat_mode!=REPEAT_ONE && length==0) { + length=3*60*1000; /* 3 minutes */ + fade=5*1000; /* 5 seconds */ + } + + id3->length = length+fade; + + return true; +} + static bool get_aiff_metadata(int fd, struct mp3entry* id3) { /* Use the trackname part of the id3 structure as a temporary buffer */ @@ -2173,6 +2272,11 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, } break; case AFMT_SPC: + if(!get_spc_metadata(fd, &(track->id3))) + { + DEBUGF("get_spc_metadata error\n"); + } + track->id3.filesize = filesize(fd); track->id3.genre_string = id3_get_num_genre(36); break; @@ -2182,7 +2286,7 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, DEBUGF("get_adx_metadata error\n"); return false; } - + break; case AFMT_NSF: buf = (unsigned char *)track->id3.path; @@ -2194,7 +2298,7 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, track->id3.vbr = false; track->id3.filesize = filesize(fd); if (memcmp(buf,"NESM",4) && memcmp(buf,"NSFE",4)) return false; - break; + break; case AFMT_AIFF: if (!get_aiff_metadata(fd, &(track->id3))) |