Index: apps/metadata/mp4.c =================================================================== --- apps/metadata/mp4.c (revision 15005) +++ apps/metadata/mp4.c (working copy) @@ -30,6 +30,7 @@ #include "debug.h" #include "replaygain.h" #include "atoi.h" +#include "settings.h" #define MP4_ID(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) @@ -68,6 +69,7 @@ #define MP4_trak MP4_ID('t', 'r', 'a', 'k') #define MP4_trkn MP4_ID('t', 'r', 'k', 'n') #define MP4_udta MP4_ID('u', 'd', 't', 'a') +#define MP4_rate MP4_ID('r', 'a', 't', 'e') #define MP4_extra MP4_ID('-', '-', '-', '-') /* Read the tag data from an MP4 file, storing up to buffer_size bytes in @@ -447,6 +449,17 @@ } break; + case MP4_rate: + { + if (global_settings.rating_file) + { + read_mp4_tag_string(fd, size, &buffer, &buffer_left, + &id3->rating_string); + id3->rating=atoi(id3->rating_string)/10; /* rating in MP4 0-100 */ + } + } + break; + case MP4_extra: { char tag_name[TAG_NAME_LENGTH]; Index: apps/metadata/asf.c =================================================================== --- apps/metadata/asf.c (revision 15005) +++ apps/metadata/asf.c (working copy) @@ -30,6 +30,7 @@ #include "metadata_common.h" #include "system.h" #include +#include "settings.h" /* TODO: Just read the GUIDs into a 16-byte array, and use memcmp to compare */ struct guid_s { @@ -386,7 +387,17 @@ asf_utf16LEdecode(fd, strlength[3], &id3buf, &id3buf_remaining); } - lseek(fd, strlength[4], SEEK_CUR); /* 4 - rating */ + if (strlength[4] > 0) { /* 4 - rating */ + if(global_settings.rating_file) + { + id3->rating_string = id3buf; + asf_utf16LEdecode(fd, strlength[4], &id3buf, &id3buf_remaining); + id3->rating = atoi(id3->rating_string)/10; + } + else + lseek(fd, strlength[4], SEEK_CUR); /* skip rating */ + } + } else if (asf_guid_match(¤t.guid, &asf_guid_extended_content_description)) { uint16_t count; int i; @@ -431,6 +442,26 @@ } else if ((!strcmp("WM/Composer",utf8buf)) && (type == 0)) { id3->composer = id3buf; asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + } else if (!strcmp("WM/SharedUserRating",utf8buf) && global_settings.rating_file) { + if (type == 0) { + id3->rating_string = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + id3->rating = (atoi(id3->rating_string)+1)/10; + } else if ((type >=2) && (type <=5)) { + id3->rating = (asf_intdecode(fd, type, length)+1)/10; /*1 to 99*/ + } else { + lseek(fd, length, SEEK_CUR); + } + } else if (!strcmp("SDB/Rating",utf8buf) && global_settings.rating_file) { + if (type == 0) { + id3->rating_string = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + id3->rating = atoi(id3->rating_string)/10; + } else if ((type >=2) && (type <=5)) { + id3->rating = asf_intdecode(fd, type, length)/10; /*0 to 100*/ + } else { + lseek(fd, length, SEEK_CUR); + } } else if (!strcmp("WM/Year",utf8buf)) { if (type == 0) { id3->year_string = id3buf; Index: apps/metadata/metadata_common.c =================================================================== --- apps/metadata/metadata_common.c (revision 15005) +++ apps/metadata/metadata_common.c (working copy) @@ -27,6 +27,7 @@ #include "metadata_common.h" #include "replaygain.h" #include "atoi.h" +#include "settings.h" /* Skip an ID3v2 tag if it can be found. We assume the tag is located at the * start of the file, which should be true in all cases where we need to skip it. @@ -292,6 +293,11 @@ { p = &(id3->grouping); } + else if ((strcasecmp(name, "rating") == 0) && global_settings.rating_file) + { + id3->rating=(atoi(value)/10); /* VORBIS and APEv2 rating 0 to 100)*/ + p = &(value); + } else { len = parse_replaygain(name, value, id3, buf, buf_remaining); Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 15005) +++ apps/lang/english.lang (working copy) @@ -11243,6 +11243,34 @@ + id: LANG_RATING_SOURCE + desc: Menu item to select source for rating display on WPS (file or tagcache) + user: + + *: "Display Rating From File:" + + + *: "Display Rating From File:" + + + *: "" + + + + id: LANG_MENU_VIEW_RATING + desc: View the rating of a file (from file tags) in the wps context menu + user: + + *: "Song Rating (file)" + + + *: "Song Rating (file)" + + + *: "Song Rating (file)" + + + id: LANG_SELECTOR_START_COLOR desc: line selector color option user: Index: apps/onplay.c =================================================================== --- apps/onplay.c (revision 15005) +++ apps/onplay.c (working copy) @@ -966,10 +966,18 @@ (void)selected_item; (void)data; struct mp3entry* id3 = audio_current_track(); if(id3) - snprintf(buffer, MAX_PATH, - "%s: %d", str(LANG_MENU_SET_RATING), id3->rating); + if(global_settings.rating_file) + snprintf(buffer, MAX_PATH, + "%s: %d", str(LANG_MENU_VIEW_RATING), id3->rating); + else + snprintf(buffer, MAX_PATH, + "%s: %d", str(LANG_MENU_SET_RATING), id3->rating); else - snprintf(buffer, MAX_PATH, + if(global_settings.rating_file) + snprintf(buffer, MAX_PATH, + "%s: -", str(LANG_MENU_VIEW_RATING)); + else + snprintf(buffer, MAX_PATH, "%s: -", str(LANG_MENU_SET_RATING)); return buffer; } @@ -979,12 +987,15 @@ struct mp3entry* id3 = audio_current_track(); if (id3 && id3->tagcache_idx) { - if (id3->rating<10) - id3->rating++; - else - id3->rating=0; + if (!global_settings.rating_file) /* if reading rating from music file, don't allow changes to rating */ + { + if (id3->rating<10) + id3->rating++; + else + id3->rating=0; - tagcache_update_numeric(id3->tagcache_idx, tag_rating, id3->rating); + tagcache_update_numeric(id3->tagcache_idx, tag_rating, id3->rating); + } } return false; } Index: apps/gui/gwps-common.c =================================================================== --- apps/gui/gwps-common.c (revision 15005) +++ apps/gui/gwps-common.c (working copy) @@ -1245,6 +1245,13 @@ } snprintf(buf, buf_size, "%d", id3->rating); return buf; + + case WPS_TOKEN_DATABASE_RATING_SOURCE: + if (intval) { + *intval = global_settings.rating_file; + } + snprintf(buf, buf_size, "%d", global_settings.rating_file); + return buf; case WPS_TOKEN_DATABASE_AUTOSCORE: if (intval) Index: apps/gui/gwps.h =================================================================== --- apps/gui/gwps.h (revision 15005) +++ apps/gui/gwps.h (working copy) @@ -164,6 +164,7 @@ /* Database */ WPS_TOKEN_DATABASE_PLAYCOUNT, WPS_TOKEN_DATABASE_RATING, + WPS_TOKEN_DATABASE_RATING_SOURCE, WPS_TOKEN_DATABASE_AUTOSCORE, /* File */ Index: apps/gui/wps_parser.c =================================================================== --- apps/gui/wps_parser.c (revision 15005) +++ apps/gui/wps_parser.c (working copy) @@ -263,6 +263,7 @@ { WPS_TOKEN_DATABASE_PLAYCOUNT, "rp", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_DATABASE_RATING, "rr", WPS_REFRESH_DYNAMIC, NULL }, + { WPS_TOKEN_DATABASE_RATING_SOURCE, "rs", WPS_REFRESH_DYNAMIC, NULL }, { WPS_TOKEN_DATABASE_AUTOSCORE, "ra", WPS_REFRESH_DYNAMIC, NULL }, #if CONFIG_CODEC == SWCODEC { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, Index: apps/settings.h =================================================================== --- apps/settings.h (revision 15005) +++ apps/settings.h (working copy) @@ -752,6 +752,7 @@ int usb_stack_mode; /* device or host */ unsigned char usb_stack_device_driver[32]; /* usb device driver to load */ #endif + bool rating_file; /* read ratings from file?(true) or from tagcache (false)*/ }; /** global variables **/ Index: apps/menus/settings_menu.c =================================================================== --- apps/menus/settings_menu.c (revision 15005) +++ apps/menus/settings_menu.c (working copy) @@ -82,12 +82,13 @@ MENUITEM_FUNCTION(tc_import, 0, ID2P(LANG_TAGCACHE_IMPORT), (int(*)(void))tagtree_import, NULL, NULL, Icon_NOICON); +MENUITEM_SETTING(rating_file, &global_settings.rating_file, NULL); MAKE_MENU(tagcache_menu, ID2P(LANG_TAGCACHE), 0, Icon_NOICON, #ifdef HAVE_TC_RAMCACHE &tagcache_ram, #endif &tagcache_autoupdate, &tc_init, &tc_update, &runtimedb, - &tc_export, &tc_import); + &tc_export, &tc_import, &rating_file); #endif /* HAVE_TAGCACHE */ /* TAGCACHE MENU */ /***********************************/ Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 15005) +++ apps/settings_list.c (working copy) @@ -1014,6 +1014,7 @@ #endif #ifdef HAVE_TAGCACHE + OFFON_SETTING(0,rating_file,LANG_RATING_SOURCE,true,"rating_file",NULL), #ifdef HAVE_TC_RAMCACHE OFFON_SETTING(0,tagcache_ram,LANG_TAGCACHE_RAM,false,"tagcache_ram",NULL), #endif Index: wps/Rockboxed.176x132x16.wps =================================================================== --- wps/Rockboxed.176x132x16.wps (revision 15005) +++ wps/Rockboxed.176x132x16.wps (working copy) @@ -1,56 +1,56 @@ -# (C) 2007, Roan Horning -# License: GNU GPL v2 or later. -%wd -%X|bg-176x132x16.bmp|0|0| -%P|pg-156.bmp| -%x|o|pgln-156.bmp|10|75| -%xl|p|ply-color-big.bmp|81|113| -%xl|q|ps-color-big.bmp|80|113| -%xl|f|ff-color-big.bmp|80|113| -%xl|r|rw-color-big.bmp|80|113| -%xl|b|sl-color-big.bmp|40|113| -%x|s|spk-color.bmp|3|113| -%xl|A|v01-color.bmp|15|113| -%xl|B|v02-color.bmp|17|113| -%xl|C|v03-color.bmp|19|113| -%xl|D|v04-color.bmp|21|113| -%xl|E|v05-color.bmp|23|113| -%xl|F|v06-color.bmp|25|113| -%xl|G|v07-color.bmp|27|113| -%xl|H|v08-color.bmp|29|113| -%xl|I|v09-color-big.bmp|31|113| -%xl|J|v10-color.bmp|33|113| -%xl|K|v11-color.bmp|35|113| -%xl|Z|n-color-big.bmp|166|117| -%xl|Y|n-color-big.bmp|163|117| -%xl|X|n-color-big.bmp|160|117| -%xl|W|n-color-big.bmp|157|117| -%xl|V|n-color-big.bmp|154|117| -%xl|U|n-color-big.bmp|151|117| -%xl|T|n-color-big.bmp|148|117| -%xl|S|n-color-big.bmp|145|117| -%xl|R|n-color-big.bmp|142|117| -%xl|Q|n-color-big.bmp|139|117| -%xl|P|l-color-big.bmp|142|117| -%xl|O|l-color-big.bmp|139|117| -%x|N|bt-color-big.bmp|137|115| -%xl|M|bu.bmp|139|117| -%xl|z|ra-color-big.bmp|60|113| -%xl|y|ro-color-big.bmp|60|113| -%xl|x|rs-color-big.bmp|60|113| -%xl|w|rab-color-big.bmp|60|113| -%xl|h|hd-color.bmp|110|112| - -%al %s%ac%?ia<%ia|%d2>%ar -%al %s%ac%?id<%id|%d1>%ar -%al %s%ac%?it<%it|%fn>%ar - -%ac%t3%ig;%ac%iy -%pb|5|10|166|75| -%al %pc%ac%?fc%ar%pt -%?ps<%xdb> -%?mp<%xdq|%xdp|%xdq|%xdf|%xdr> -%?mm<|%xdz|%xdy|%xdx|%xdw> -%?mh<%xdh> -%?pv<|%xdA|%xdA%xdB|%xdA%xdB%xdC|%xdA%xdB%xdC%xdD|%xdA%xdB%xdC%xdD%xdE|%xdA%xdB%xdC%xdD%xdE%xdF|%xdA%xdB%xdC%xdD%xdE%xdF%xdG|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI%xdJ|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI%xdJ%xdK> -%?bl<%xdM|%xdO|%xdO%xdP|%xdQ%xdR|%xdQ%xdR%xdS|%xdQ%xdR%xdS%xdT|%xdQ%xdR%xdS%xdT%xdU|%xdQ%xdR%xdS%xdT%xdU%xdV|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX%xdY|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX%xdY%xdZ> +# (C) 2007, Roan Horning +# License: GNU GPL v2 or later. +%wd +%X|bg-176x132x16.bmp|0|0| +%P|pg-156.bmp| +%x|o|pgln-156.bmp|10|75| +%xl|p|ply-color-big.bmp|81|113| +%xl|q|ps-color-big.bmp|80|113| +%xl|f|ff-color-big.bmp|80|113| +%xl|r|rw-color-big.bmp|80|113| +%xl|b|sl-color-big.bmp|40|113| +%x|s|spk-color.bmp|3|113| +%xl|A|v01-color.bmp|15|113| +%xl|B|v02-color.bmp|17|113| +%xl|C|v03-color.bmp|19|113| +%xl|D|v04-color.bmp|21|113| +%xl|E|v05-color.bmp|23|113| +%xl|F|v06-color.bmp|25|113| +%xl|G|v07-color.bmp|27|113| +%xl|H|v08-color.bmp|29|113| +%xl|I|v09-color-big.bmp|31|113| +%xl|J|v10-color.bmp|33|113| +%xl|K|v11-color.bmp|35|113| +%xl|Z|n-color-big.bmp|166|117| +%xl|Y|n-color-big.bmp|163|117| +%xl|X|n-color-big.bmp|160|117| +%xl|W|n-color-big.bmp|157|117| +%xl|V|n-color-big.bmp|154|117| +%xl|U|n-color-big.bmp|151|117| +%xl|T|n-color-big.bmp|148|117| +%xl|S|n-color-big.bmp|145|117| +%xl|R|n-color-big.bmp|142|117| +%xl|Q|n-color-big.bmp|139|117| +%xl|P|l-color-big.bmp|142|117| +%xl|O|l-color-big.bmp|139|117| +%x|N|bt-color-big.bmp|137|115| +%xl|M|bu.bmp|139|117| +%xl|z|ra-color-big.bmp|60|113| +%xl|y|ro-color-big.bmp|60|113| +%xl|x|rs-color-big.bmp|60|113| +%xl|w|rab-color-big.bmp|60|113| +%xl|h|hd-color.bmp|110|112| + +%al %s%ac%?ia<%ia|%d2>%ar +%al %s%ac%?id<%id|%d1>%ar +%al %s%ac%?it<%it|%fn>%ar +Rating: %rr Source: %?rs +%ac%t3%ig;%ac%iy +%pb|5|10|166|75| +%al %pc%ac%?fc%ar%pt +%?ps<%xdb> +%?mp<%xdq|%xdp|%xdq|%xdf|%xdr> +%?mm<|%xdz|%xdy|%xdx|%xdw> +%?mh<%xdh> +%?pv<|%xdA|%xdA%xdB|%xdA%xdB%xdC|%xdA%xdB%xdC%xdD|%xdA%xdB%xdC%xdD%xdE|%xdA%xdB%xdC%xdD%xdE%xdF|%xdA%xdB%xdC%xdD%xdE%xdF%xdG|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI%xdJ|%xdA%xdB%xdC%xdD%xdE%xdF%xdG%xdH%xdI%xdJ%xdK> +%?bl<%xdM|%xdO|%xdO%xdP|%xdQ%xdR|%xdQ%xdR%xdS|%xdQ%xdR%xdS%xdT|%xdQ%xdR%xdS%xdT%xdU|%xdQ%xdR%xdS%xdT%xdU%xdV|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX%xdY|%xdQ%xdR%xdS%xdT%xdU%xdV%xdW%xdX%xdY%xdZ> Index: firmware/export/id3.h =================================================================== --- firmware/export/id3.h (revision 15005) +++ firmware/export/id3.h (working copy) @@ -206,6 +206,7 @@ /* runtime database fields */ long tagcache_idx; + char* rating_string; short rating; short score; long playcount; Index: firmware/id3.c =================================================================== --- firmware/id3.c (revision 15005) +++ firmware/id3.c (working copy) @@ -43,6 +43,7 @@ #include "system.h" #include "replaygain.h" #include "rbunicode.h" +#include <../apps/settings.h> /** Database of audio formats **/ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = @@ -344,6 +345,54 @@ return len; } +/* parse numeric value from rating entry */ +static int parserating( struct mp3entry* entry, char* tag, int bufferpos ) +{ +char* value_str=NULL; +unsigned char value=0; +int desc_len = strlen(tag); + +if (global_settings.rating_file) /* if we are reading ratings from the file and not tagcache */ + { + + /* tag is a string with an e-mail address in it, rating is one byte after the (null terminated) e-mail*/ + /* no@email is for mediamonkey ratings*/ + + value_str = tag + desc_len + 1; + value=value_str[0]; + + if (!strcmp(tag, "no@email")) + { + if (value >= 255) + entry->rating=10; + else if (value >= 230) + entry->rating=9; + else if (value >= 204) + entry->rating=8; + else if (value >= 178) + entry->rating=7; + else if (value >= 153) + entry->rating=6; + else if (value >= 128) + entry->rating=5; + else if (value >= 102) + entry->rating=4; + else if (value >= 76) + entry->rating=3; + else if (value >= 51) + entry->rating=2; + else if (value >= 26) + entry->rating=1; + else + entry->rating=0; + + } + else + entry->rating=((value*11)/256); /* rough calculation for other rating schemes */ + } +return bufferpos; /* POPM length after e-mail should this be +5? ie bytes after e-mail?*/ +} + /* parse numeric value from string */ static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos ) { @@ -496,6 +545,7 @@ { "COMM", 4, offsetof(struct mp3entry, comment), NULL, false }, { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, + { "POPM", 4, offsetof(struct mp3entry, rating_string), &parserating, true }, #if CONFIG_CODEC == SWCODEC { "TXXX", 4, 0, &parseuser, false }, { "RVA2", 4, 0, &parserva2, true },