|
Rockbox mail archiveSubject: WPS modeWPS mode
From: Magnus Holmgren <lear_at_algonet.se>
Date: Sat, 03 Aug 2002 20:09:16 +0200 Hi, Here's another WPS patch, adding a display mode primarily intended for players. The first line displays the following information, if available: "<tracknum> - <title> (<artist>, <album>)". The second line alters every five seconds between two displays, "<mm:ss><s><p><nnnn>" and "<-mm:ss><kbps><*>". The fields are as follows: play time, shuffle flag, playlist flag, playlist index; remaining play time, bitrate, vbr flag. ID3 information is used if available, otherwise the path is parsed, assuming the path _ends_ with artist/album/title.mp3. The patch also makes the time display update 5 times per second rather than 2, which looks better. There are a couple of things that could be improved in this patch though: * The shuffle, playlist and maybe VBR flags should be symbols, but I couldn't find any suitable ones. * The code in draw_screen() uses static buffers to do its work, as I wasn't sure how much stack was available. * tracknum isn't displayed at the moment. Seems like it isn't set properly if a ID3V2 file is playing (haven't tried ID3V1 only). * The playlist flag remains set even after a playlist isn't used any more (it needs to be cleard on playlist stop/exit). * During song change, a random time is sometimes displayed briefly. * If shuffle is on, the playlist index doesn't refer to the order in the file, but rather the order in memory. Despite these things, I use this mode all the time. -- Magnus Holmgren Index: wps.c =================================================================== RCS file: /cvsroot/rockbox/apps/wps.c,v retrieving revision 1.45 diff -b -u -r1.45 wps.c --- wps.c 1 Aug 2002 13:29:59 -0000 1.45 +++ wps.c 3 Aug 2002 17:46:18 -0000 _at__at_ -40,6 +40,10 _at__at_ #define PLAY_DISPLAY_DEFAULT 0 #define PLAY_DISPLAY_FILENAME_SCROLL 1 #define PLAY_DISPLAY_TRACK_TITLE 2 +#define PLAY_DISPLAY_COMPACT_VERBOSE 3 + +#define BUTTON_POLL_FREQUENCY 10 /* Number of ticks between each button poll */ +#define BUTTON_POLLS_PER_UPDATE 2 /* Number of polls between display update */ #ifdef HAVE_RECORDER_KEYPAD #define RELEASE_MASK (BUTTON_F1 | BUTTON_DOWN) _at__at_ -47,6 +51,81 _at__at_ #define RELEASE_MASK (BUTTON_MENU | BUTTON_STOP) #endif +/* Tokenize a string from the end. An empty string contains no tokens. + * + * buffer - pointer to buffer to parse. Always pass it unchanged. + * separator - chars that limits a token. + * end - tracks current scan position; initialize to NULL before the + * first call. + * returns the current token, or NULL if there are no more tokens. + */ +static char* strrtok_r(char* buffer, char* separator, char** end) +{ + if (*end == NULL) + { + /* First call, init to last char */ + *end = buffer + strlen(buffer) - 1; + } + + /* No more to search? */ + if (*end < buffer) + { + return NULL; + } + + /* Locate previous separator */ + while ((*end > buffer) && !strchr(separator, **end)) + { + --*end; + } + + /* On a separator? */ + if (strchr(separator, **end)) + { + **end = 0; /* Terminate preceeding token */ + } + + --*end; /* Prepare for next round */ + return *end + 2; /* Return char after sparator */ +} + +/* strncat and snprintf rolled into one, with a twist. The string in buffer + * will not be made longer than buffer_len. + */ +static int strfmt(char* buffer, int buffer_len, char* format, ...) +{ + int len; + va_list args; + + va_start (args, format); + len = strlen(buffer); + len = vsnprintf(buffer + len, buffer_len - len, format, args); + va_end (args); + + return len; +} + +/* Assume path format of: .../Artist/Album/Title.mp3. */ +static void id3_from_path(char* path, char** artist, char** album, char** title) +{ + char* end = NULL; + + *title = strrtok_r(path, "/", &end); + *album = strrtok_r(path, "/", &end); + *artist = strrtok_r(path, "/", &end); + + if (*title != NULL) + { + /* Remove any .mp3 suffix */ + int length = strlen(*title) - 4; + + if ((length > 0) && !strcasecmp(*title + length, ".mp3")) + { + *(*title + length) = 0; + } + } +} + static void draw_screen(struct mp3entry* id3) { lcd_clear_display(); _at__at_ -132,6 +211,52 _at__at_ #endif break; } + case PLAY_DISPLAY_COMPACT_VERBOSE: + { + static char buffer[MAX_PATH]; + static char id3buffer[MAX_PATH]; + char* artist; + char* album; + char* title; + int tracknum; + + if (id3->title) + { + artist = id3->artist; + album = id3->album; + title = id3->title; + /* Doesn't seem to get set... */ + tracknum = id3->tracknum; + } + else + { + strncpy(id3buffer, id3->path, sizeof(id3buffer)); + id3buffer[sizeof(id3buffer) - 1] = 0; + id3_from_path(id3buffer, &artist, &album, &title); + tracknum = 0; + } + + buffer[0] = 0; + + if (tracknum) + { + strfmt(buffer, sizeof(buffer), "%d - ", tracknum); + } + + strfmt(buffer, sizeof(buffer), "%s", title ? title : "<N/A>"); + + if (artist || album) + { + strfmt(buffer, sizeof(buffer), " (%s, %s)", + artist ? artist : "<N/A>", + album ? album : "<N/A>"); + } + + buffer[sizeof(buffer) - 1] = 0; + lcd_puts_scroll(0, 0, buffer); + + break; + } } } status_draw(); _at__at_ -222,6 +347,38 _at__at_ lcd_puts(0, 1, buffer); lcd_update(); } + else if (global_settings.wps_display == PLAY_DISPLAY_COMPACT_VERBOSE) + { + /* Change display every 5 seconds */ + #define PDCV_CHANGE_FREQUENCY (5 * BUTTON_POLL_FREQUENCY / BUTTON_POLLS_PER_UPDATE) + static int count = 0; + + if (count++ < PDCV_CHANGE_FREQUENCY) + { + snprintf(buffer, sizeof(buffer), "%02d:%02d%s%s%04d", + id3->elapsed / 60000, + id3->elapsed % 60000 / 1000, + global_settings.playlist_shuffle ? "s" : " ", + playlist.amount ? "p" : " ", + playlist.index + 1); + } + else + { + snprintf(buffer, sizeof(buffer), "-%02d:%02d %3d%s", + (id3->length - id3->elapsed) / 60000, + (id3->length - id3->elapsed) % 60000 / 1000, + id3->bitrate, + id3->vbr ? "*" : " "); + } + + if (count > (PDCV_CHANGE_FREQUENCY * 2)) + { + count = 0; + } + + lcd_puts(0, 1, buffer); + lcd_update(); + } #endif } _at__at_ -233,7 +390,7 _at__at_ lcd_drawline(0,LCD_HEIGHT-1,battery_level() * (LCD_WIDTH-1) / 100, LCD_HEIGHT-1); #endif - for ( i=0;i<5;i++ ) { + for ( i=0;i<BUTTON_POLLS_PER_UPDATE;i++ ) { int button = button_get(false); switch ( button ) _at__at_ -452,7 +609,7 _at__at_ break; #endif } - sleep(HZ/10); + sleep(HZ / BUTTON_POLL_FREQUENCY); } } } Index: settings_menu.c =================================================================== RCS file: /cvsroot/rockbox/apps/settings_menu.c,v retrieving revision 1.8 diff -b -u -r1.8 settings_menu.c --- settings_menu.c 2 Aug 2002 13:20:03 -0000 1.8 +++ settings_menu.c 3 Aug 2002 17:46:30 -0000 _at__at_ -63,8 +63,8 _at__at_ static void wps_set(void) { - char* names[] = { "Id3 ", "File ", "Parse" }; - set_option("[WPS display]", &global_settings.wps_display, names, 3 ); + char* names[] = { "Id3 ", "File ", "Parse ", "Verbose" }; + set_option("[WPS display]", &global_settings.wps_display, names, 4 ); } void settings_menu(void) Received on 2002-08-03 Page template was last modified "Tue Sep 7 00:00:02 2021" The Rockbox Crew -- Privacy Policy |