diff --git a/apps/plugins/lrcplayer.c b/apps/plugins/lrcplayer.c index 97385ff..e05f41e 100644 --- a/apps/plugins/lrcplayer.c +++ b/apps/plugins/lrcplayer.c @@ -27,7 +27,6 @@ #define MAX_LINE_LEN 256 -#define LRC_BUFFER_SIZE 0x3000 /* 12 kiB */ #if PLUGIN_BUFFER_SIZE >= 0x10000 /* no id3 support for low mem targets */ /* define this to read lyrics in id3 tag */ #define LRC_SUPPORT_ID3 @@ -86,6 +85,7 @@ struct preferences { char lrc_directory[64]; int encoding; #ifdef LRC_SUPPORT_ID3 + int precedence_tag; bool read_id3; #endif }; @@ -1195,7 +1195,7 @@ static void parse_id3v2(int fd) { int minframesize; int size; - long framelen; + long framelen = 0; char header[10]; char tmp[8]; unsigned char version; @@ -1208,6 +1208,14 @@ static void parse_id3v2(int fd) int rc; enum {NOLT, SYLT, USLT} type = NOLT; + struct { + int type; + int offset; + int framelen; + bool global_ff_found; + bool unsynch; + } other = { .type = NOLT }; + /* Bail out if the tag is shorter than 10 bytes */ if(current.id3->id3v2len < 10) return; @@ -1286,7 +1294,7 @@ static void parse_id3v2(int fd) else rc = rb->read(fd, header, 10); if(rc != 10) - return; + break; /* Adjust for the 10 bytes we read */ size -= 10; @@ -1303,7 +1311,7 @@ static void parse_id3v2(int fd) } } else { if(6 != rb->read(fd, header, 6)) - return; + break; /* Adjust for the 6 bytes we read */ size -= 6; @@ -1312,7 +1320,7 @@ static void parse_id3v2(int fd) if(framelen == 0){ if (header[0] == 0 && header[1] == 0 && header[2] == 0) - return; + break; else continue; } @@ -1359,45 +1367,64 @@ static void parse_id3v2(int fd) continue; if (framelen < 0) - return; + break; if(!rb->memcmp( header, "SLT", 3 ) || !rb->memcmp( header, "SYLT", 4 )) { /* found a supported tag */ type = SYLT; - break; + if (prefs.precedence_tag == ID3_SYLT) { + other.type = NOLT; + break; + } } else if(!rb->memcmp( header, "ULT", 3 ) || !rb->memcmp( header, "USLT", 4 )) { /* found a supported tag */ type = USLT; - break; - } - else - { - /* not a supported tag*/ - if(global_unsynch && version <= ID3_VER_2_3) { - size -= read_unsynched(fd, lrc_buffer, framelen, &global_ff_found); - } else { - size -= framelen; - if( rb->lseek(fd, framelen, SEEK_CUR) == -1 ) - return; + if (prefs.precedence_tag == ID3_USLT) { + other.type = NOLT; + break; } } + if (type != NOLT && other.type == NOLT) { + /* save state of first supported tag */ + other.type = type; + other.offset = rb->lseek(fd, 0, SEEK_CUR); + other.framelen = framelen; + other.global_ff_found = global_ff_found; + other.unsynch = unsynch; + } + /* skip to next tag*/ + if(global_unsynch && version <= ID3_VER_2_3) { + size -= read_unsynched(fd, lrc_buffer, framelen, &global_ff_found); + } else { + size -= framelen; + if( rb->lseek(fd, framelen, SEEK_CUR) == -1 ) + return; + } } if(type == NOLT) return; + if (other.type != NOLT) { + type = other.type; + rb->lseek(fd, other.offset, SEEK_SET); + framelen = other.framelen; + global_ff_found = other.global_ff_found; + unsynch = other.unsynch; + } + int encoding = 0, chsiz; char *tag, *p, utf8line[MAX_LINE_LEN*3]; unsigned char* (*utf_decode)(const unsigned char *, unsigned char *, int) = NULL; /* use middle of lrc_buffer to store tag data. */ - if(framelen >= LRC_BUFFER_SIZE/3) - framelen = LRC_BUFFER_SIZE/3-1; - tag = lrc_buffer+LRC_BUFFER_SIZE*2/3-framelen-1; + if(framelen >= (long)lrc_buffer_size/3) + framelen = lrc_buffer_size/3-1; + tag = lrc_buffer+lrc_buffer_size*2/3-framelen-1; if(global_unsynch && version <= ID3_VER_2_3) bytesread = read_unsynched(fd, tag, framelen, &global_ff_found); else @@ -1475,8 +1502,8 @@ static void parse_id3v2(int fd) tag = p; while ( bytesread > 0 - && lrc_buffer_used+bytesread < LRC_BUFFER_SIZE*2/3 - && LRC_BUFFER_SIZE*2/3 < lrc_buffer_end) + && lrc_buffer_used+bytesread < lrc_buffer_size*2/3 + && lrc_buffer_size*2/3 < lrc_buffer_end) { bool is_crlf = false; struct lrc_line *lrc_line = alloc_buf(sizeof(struct lrc_line)); @@ -2288,6 +2315,7 @@ static void load_or_save_settings(bool save) prefs.backlight_on = false; #ifdef LRC_SUPPORT_ID3 prefs.read_id3 = true; + prefs.precedence_tag = ID3_SYLT; #endif rb->strcpy(prefs.lrc_directory, "/Lyrics"); prefs.encoding = -1; /* default codepage */