From b9a71b305b98a87f747dc1e0cc91324b73693fd1 Mon Sep 17 00:00:00 2001 From: Adam Boot Date: Sat, 3 Mar 2007 06:08:28 +0000 Subject: 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 --- apps/codecs/spc.c | 27 ++++++++++++-- apps/metadata.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 12b236c53d..1cf20098fa 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c @@ -671,14 +671,31 @@ static int LoadID666(unsigned char *buf) { ID666.emulator=*ib; ib++; } else { - int year, month, day; unsigned long tmp; char buf[64]; DEBUGF("text tag detected\n"); - - year=month=day=0; - ib+=11; + + memcpy(buf, ib, 2); + buf[2] = 0; + tmp = 0; + for (i=0;i<2 && buf[i]>='0' && buf[i]<='9';i++) tmp=tmp*10+buf[i]-'0'; + ID666.month = tmp; + ib+=3; + + memcpy(buf, ib, 2); + buf[2] = 0; + tmp = 0; + for (i=0;i<2 && buf[i]>='0' && buf[i]<='9';i++) tmp=tmp*10+buf[i]-'0'; + ID666.day = tmp; + ib+=3; + + memcpy(buf, ib, 4); + buf[4] = 0; + tmp = 0; + for (i=0;i<4 && buf[i]>='0' && buf[i]<='9';i++) tmp=tmp*10+buf[i]-'0'; + ID666.year = tmp; + ib+=5; memcpy(buf, ib, 3); buf[3] = 0; @@ -861,6 +878,8 @@ enum codec_status codec_main(void) ci->id3->title = ID666.song; ci->id3->album = ID666.game; ci->id3->artist = ID666.artist; + ci->id3->year = ID666.year; + ci->id3->comment = ID666.comments; reset_profile_timers(); } 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))) -- cgit v1.2.3