Index: CATEGORIES =================================================================== --- CATEGORIES (revision 16229) +++ CATEGORIES (working copy) @@ -34,6 +34,7 @@ jewels,games jpeg,viewers logo,demos +lyric_viewer,viewers mandelbrot,demos maze,games mazezam,games Index: viewers.config =================================================================== --- viewers.config (revision 16229) +++ viewers.config (working copy) @@ -1,3 +1,4 @@ +mp3,viewers/lyric_viewer,5 ch8,viewers/chip8,0 txt,viewers/viewer,1 nfo,viewers/viewer,1 Index: lyric_viewer.c =================================================================== --- lyric_viewer.c (revision 0) +++ lyric_viewer.c (revision 0) @@ -0,0 +1,218 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * lyric_viewer.c (c) 2008 smoking gnu + * + * Copyright (C) 2002 Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + + * This plugin is my first rockbox project, so please don't expect it to be perfect ;) + * I guess the "lyric-finding" part of this plugin could be handled by the rockbox core metadata parser, but this works too... + + *Update: + *Now it checks how long the ID3 tag is before it searches for the lyric tag - therefore it doesn't have to search the + *whole file if there's no lyric tag at all. + + * This plugin will NOT work when some other ID3-tag (e.g. Artist, Title etc) contains the string "USLT". + + ****************************************************************************/ +#include "plugin.h" +#define BUF_SIZE 5000 /*Size of the lyrics buffer - 5k should be way enough*/ + +static struct plugin_api* rb; +static int line_count, fd; +static struct gui_synclist gui_lyrics; +static unsigned char lyr_buffer[BUF_SIZE]; + +PLUGIN_HEADER + +char * get_lyric_line(int selected_line, void *data, char *buffer) +{ + + int i=0, start=0, stop; + (void) data; + + rb->strcpy(buffer,"Couldn't read line!"); /*Just in case something goes wrong*/ + + for (i=0; isnprintf(buffer, stop-start, "%s", &lyr_buffer[start]); + + return buffer; +} + +int show_lyrics(void) +{ + /*a standard gui_list*/ + rb->gui_synclist_init(&gui_lyrics, &get_lyric_line, NULL, false, 1); + rb->gui_synclist_set_nb_items(&gui_lyrics, line_count+1); + rb->gui_synclist_limit_scroll(&gui_lyrics, false); + rb->gui_synclist_select_item(&gui_lyrics, 0); + rb->gui_synclist_draw(&gui_lyrics); + + int button; + while (true) + { + rb->gui_syncstatusbar_draw(rb->statusbars, true); + button = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK); + if (rb->gui_synclist_do_button(&gui_lyrics, &button, LIST_WRAP_UNLESS_HELD)) + { + continue; + } + if (button==ACTION_STD_CANCEL) return 0; + } +} + +int find_lyr_tag(void) +{ + + int pos=0, eof_check, tag_pos=0, i, id3_length=0; + char lyr_tag[5], temp; + + rb->strcpy(lyr_tag, "USLT"); + + eof_check=rb->read(fd, lyr_buffer, 6); + if (eof_check==0) return 0; + + if (lyr_buffer[0]!='I' || lyr_buffer[1]!='D' || lyr_buffer[2]!='3') + return 0; /*check whether there's an ID3 tag*/ + + for (i=0; i<4; i++) /*get its length*/ + { + id3_length<<=8; + + eof_check=rb->read(fd, &temp, 1); + if (eof_check==0) return 0; + + id3_length+=temp; + } + + for (i=0; i< id3_length; i++) /*... and finally search for the tag*/ + { + + eof_check=rb->read(fd, &temp, 1); + if (eof_check==0) return 0; + + pos++; + + if (temp==lyr_tag[tag_pos]) + { + if ((unsigned int)tag_pos < (rb->strlen(lyr_tag)-1)) + { + tag_pos++; + } + else + { + return pos; + } + } + else tag_pos=0; + } + return 0; +} + +int get_lyr_len(void) +{ + int eof_check, pos=0, lyr_len=0, i; + unsigned char temp; + + /*get the length of the lyrics*/ + for (i=0; i<4; i++) + { + lyr_len<<=8; + + eof_check=rb->read(fd, &temp, 1); + if (eof_check==0) return 0; + + lyr_len+=temp; + } + + /*go to the beginning of the lyrics*/ + temp=0; + while(temp==0) + { + eof_check=rb->read(fd, &temp, 1); + if (eof_check==0) return 0; + pos++; + } + while(temp!=0) + { + eof_check=rb->read(fd, &temp, 1); + if (eof_check==0) return 0; + pos++; + } + return lyr_len-pos+2; +} + +int save_lyrics(int len) +{ + int eof_check, pos; + unsigned char temp; + + /*just copy the whole lyric block to lyr_buffer[] */ + for (pos=0; posread(fd, &temp, 1); + if (eof_check==0) return 0; + if (pos==BUF_SIZE) return -1; + + lyr_buffer[pos]=temp; + if (temp=='\n') line_count++; + } + lyr_buffer[pos+1]=0; + return 1; +} + +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) +{ + + int lyr_len=0; + + rb = api; + fd=rb->open((char*)parameter, O_RDONLY); + line_count=0; + + + if (fd>=0) + { + if (find_lyr_tag()) /*check whether there is a USLT lyric tag */ + { + lyr_len=get_lyr_len(); /*get length of the lyrics */ + save_lyrics(lyr_len); /*read lyrics and save them to the buffer */ + + show_lyrics(); /*show us those lyrics! */ + } + else rb->splash(HZ*2, "No Lyric tag found!"); + + rb->close(fd); + + } + else rb->splash(HZ*2, "Could not open file '%s'!", (char*) parameter); + + return PLUGIN_OK; +} Index: SOURCES =================================================================== --- SOURCES (revision 16229) +++ SOURCES (working copy) @@ -9,6 +9,7 @@ firmware_flash.c jackpot.c logo.c +lyric_viewer.c mosaique.c properties.c random_folder_advance_config.c