Index: apps/settings.c =================================================================== RCS file: /cvsroot/rockbox/apps/settings.c,v retrieving revision 1.186 diff -u -u -r1.186 settings.c --- apps/settings.c 17 Jan 2004 12:36:30 -0000 1.186 +++ apps/settings.c 19 Jan 2004 07:46:10 -0000 @@ -385,7 +385,8 @@ config_block[0x25] = (unsigned char) ((global_settings.disk_poweroff & 1) | ((global_settings.buffer_margin & 7) << 1) | - ((global_settings.trickle_charge & 1) << 4)); + ((global_settings.trickle_charge & 1) << 4) | + ((global_settings.rva2 & 1) << 5)); { int elapsed_secs; @@ -708,6 +709,7 @@ global_settings.disk_poweroff = config_block[0x25] & 1; global_settings.buffer_margin = (config_block[0x25] >> 1) & 7; global_settings.trickle_charge = (config_block[0x25] >> 4) & 1; + global_settings.rva2 = (config_block[0x25] >> 5) & 1; } if (config_block[0x27] != 0xff) @@ -1064,6 +1066,9 @@ else if (!strcasecmp(name, "auto volume")) { static char* options[] = {"off", "2", "4", "8" }; set_cfg_option(&global_settings.avc, value, options, 4); + } else if (!strcasecmp(name, "use id3 rva2")) { + static char* options[] = {"off", "on"}; + set_cfg_option(&global_settings.rva2, value, options, 2); } else if (!strcasecmp(name, "rec mic gain")) set_sound(value, SOUND_MIC_GAIN, &global_settings.rec_mic_gain); @@ -1501,6 +1506,7 @@ global_settings.loudness = mpeg_sound_default(SOUND_LOUDNESS); global_settings.bass_boost = mpeg_sound_default(SOUND_SUPERBASS); global_settings.avc = mpeg_sound_default(SOUND_AVC); + global_settings.rva2 = 0; global_settings.channel_config = mpeg_sound_default(SOUND_CHANNELS); global_settings.rec_quality = 5; global_settings.rec_source = 0; /* 0=mic */ Index: apps/settings.h =================================================================== RCS file: /cvsroot/rockbox/apps/settings.h,v retrieving revision 1.98 diff -u -u -r1.98 settings.h --- apps/settings.h 14 Jan 2004 00:11:28 -0000 1.98 +++ apps/settings.h 19 Jan 2004 07:46:10 -0000 @@ -71,6 +71,7 @@ int loudness; /* loudness eq: 0-100 0=off 100=max */ int bass_boost; /* bass boost eq: 0-100 0=off 100=max */ int avc; /* auto volume correct: 0=disable, 1=2s 2=4s 3=8s */ + int rva2; /* use id3 rva2 frame for auto volume correct 0=disable */ int channel_config; /* Stereo, Mono, Mono left, Mono right */ int rec_quality; /* 0-7 */ Index: apps/sound_menu.c =================================================================== RCS file: /cvsroot/rockbox/apps/sound_menu.c,v retrieving revision 1.43 diff -u -u -r1.43 sound_menu.c --- apps/sound_menu.c 5 Jan 2004 20:42:50 -0000 1.43 +++ apps/sound_menu.c 19 Jan 2004 07:46:10 -0000 @@ -186,6 +186,25 @@ names, 4, set_avc); } +static bool set_rva2(int val) +{ + if (val == 0) { + global_settings.rva2 &= ~1; + mpeg_volume_rva2(0, global_settings.volume); + } else { + global_settings.rva2 |= 1; + mpeg_volume_rva2(global_settings.rva2 >> 1, global_settings.volume); + } +} + +static bool rva2(void) +{ + char* names[] = { str(LANG_OFF), str(LANG_ON) }; + static int rva2_val; + rva2_val = global_settings.rva2 & 1; + return set_option(str(LANG_AUTOADJ), &rva2_val, INT, names, 2, set_rva2); +} + static bool recsource(void) { char *names[] = {str(LANG_RECORDING_SRC_MIC), str(LANG_RECORDING_SRC_LINE), @@ -292,8 +311,9 @@ #ifdef HAVE_MAS3587F { str(LANG_LOUDNESS), loudness }, { str(LANG_BBOOST), bass_boost }, - { str(LANG_AUTOVOL), avc } + { str(LANG_AUTOVOL), avc }, #endif + { str(LANG_AUTOADJ), rva2 }, }; m=menu_init( items, sizeof items / sizeof(struct menu_items) ); Index: apps/wps.c =================================================================== RCS file: /cvsroot/rockbox/apps/wps.c,v retrieving revision 1.204 diff -u -u -r1.204 wps.c --- apps/wps.c 15 Jan 2004 23:05:13 -0000 1.204 +++ apps/wps.c 19 Jan 2004 07:46:10 -0000 @@ -153,7 +153,7 @@ { int button; int menu_pos = 0; - int menu_max = 8; + int menu_max = 11; bool exit = false; char scroll_text[MAX_PATH]; @@ -250,6 +250,16 @@ lcd_puts(0, 0, str(LANG_ID3_PATH)); lcd_puts_scroll(0, 1, id3->path); break; + + case 11: { + int a, b; + lcd_puts(0, 0, str(LANG_ID3_RVA2)); + a = id3->rva2 >> 9; + b = ((id3->rva2 & 0x1ff) * 10000 + 256) / 512; + snprintf(scroll_text,sizeof(scroll_text), "%d.%04d dbA", a, b); + lcd_puts(0, 1, scroll_text); + break; + } } lcd_update(); @@ -435,6 +445,13 @@ { lcd_stop_scroll(); id3 = mpeg_current_track(); + if ((global_settings.rva2 & 1) != 0) { + mpeg_volume_rva2(id3->rva2, global_settings.volume); + } else { + mpeg_volume_rva2(0, global_settings.volume); + } + global_settings.rva2 = (global_settings.rva2 & 1) | (id3->rva2 << 1); + if (wps_display(id3)) retcode = true; else Index: apps/lang/english.lang =================================================================== RCS file: /cvsroot/rockbox/apps/lang/english.lang,v retrieving revision 1.97 diff -u -u -r1.97 english.lang --- apps/lang/english.lang 14 Jan 2004 14:42:31 -0000 1.97 +++ apps/lang/english.lang 19 Jan 2004 07:46:12 -0000 @@ -423,6 +423,11 @@ eng: "Auto Volume" new: +id: LANG_AUTOADJ +desc: in sound_settings +eng: "Use ID3 RVA2 tag" +new: + id: LANG_SHOWDIR_ERROR_BUFFER desc: in showdir(), displayed on screen when you reach buffer limit eng: "Dir Buffer" @@ -569,6 +574,11 @@ desc: in wps eng: "[Path]" new: + +id: LANG_ID3_RVA2 +desc: in wps +eng: "[Volume adjust]" +new: id: LANG_PITCH_UP desc: in wps Index: firmware/id3.c =================================================================== RCS file: /cvsroot/rockbox/firmware/id3.c,v retrieving revision 1.84 diff -u -u -r1.84 id3.c --- firmware/id3.c 9 Jan 2004 00:47:26 -0000 1.84 +++ firmware/id3.c 19 Jan 2004 07:46:16 -0000 @@ -67,7 +67,7 @@ display it, at a runtime cost.) 2. If any special processing beyond copying the tag value from the Id3 - block to the struct mp3entry is rrequired (such as converting to an + block to the struct mp3entry is required (such as converting to an int), write a function to perform this special processing. This function's prototype must match that of @@ -80,7 +80,7 @@ you don't lengthen or shorten the tag string, you can return the third argument unchanged. - Unless you have a good reason no to, make the function static. + Unless you have a good reason not to, make the function static. TO JUST COPY THE TAG NO SPECIAL PROCESSING FUNCTION IS NEEDED. 3. add one or more entries to the tagList array, using the format: @@ -98,8 +98,8 @@ variable in struct mp3entry, special processing function address - 5. Add code to wps-display.c function get_tag to assign a printf-like - format specifier for the tag */ + 5. Add code to wps-display.c function get_tag to assign a printf-like + format specifier for the tag */ /* Structure for ID3 Tag extraction information */ struct tag_resolver { @@ -232,6 +232,23 @@ } } +/* parse relative volume adjustment */ +static int parserva2( struct mp3entry* entry, char* tag, int bufferpos ) +{ + while(*tag++ && tag < (entry->id3v2buf + bufferpos)) + ; + + while(*tag != 1 && tag < (entry->id3v2buf + bufferpos)) { + tag += 3; + tag += *tag / 8 + 1; + } + + if (tag < (entry->id3v2buf + bufferpos)) + entry->rva2 = ((signed char)tag[1] << 8) | (unsigned char)tag[2]; + + return tag - entry->id3v2buf; +} + static struct tag_resolver taglist[] = { { "TPE1", 4, offsetof(struct mp3entry, artist), NULL }, { "TP1", 3, offsetof(struct mp3entry, artist), NULL }, @@ -245,7 +262,10 @@ { "TYE", 3, offsetof(struct mp3entry, year_string), &parseyearnum }, { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre }, { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre }, - { "TCOM", 4, offsetof(struct mp3entry, composer), NULL } + { "TCOM", 4, offsetof(struct mp3entry, composer), NULL }, + { "RVA2", 4, offsetof(struct mp3entry, rva2_string), &parserva2 }, + { "XRVA", 4, offsetof(struct mp3entry, rva2_string), &parserva2 }, + { "XRV", 3, offsetof(struct mp3entry, rva2_string), &parserva2 }, }; #define TAGLIST_SIZE ((int)(sizeof(taglist) / sizeof(taglist[0]))) Index: firmware/mp3_playback.c =================================================================== RCS file: /cvsroot/rockbox/firmware/mp3_playback.c,v retrieving revision 1.4 diff -u -u -r1.4 mp3_playback.c --- firmware/mp3_playback.c 10 Jan 2004 15:39:56 -0000 1.4 +++ firmware/mp3_playback.c 19 Jan 2004 07:46:16 -0000 @@ -558,6 +558,16 @@ #endif /* HAVE_MAS3507D */ #endif /* !SIMULATOR */ +static int rva2_val; + +void mpeg_volume_rva2(int rva2, int volume) +{ + if (rva2_val != rva2) { + rva2_val = rva2; + mpeg_sound_set(SOUND_VOLUME, volume); + } +} + void mpeg_sound_set(int setting, int value) { #ifdef SIMULATOR @@ -576,8 +586,10 @@ { case SOUND_VOLUME: #ifdef HAVE_MAS3587F - tmp = 0x7f00 * value / 100; - mas_codec_writereg(0x10, tmp & 0xff00); + tmp = 0x7300 * value / 100; + tmp += (rva2_val + 0x100) >> 1; + tmp = MIN(MAX(0, tmp), 0x7f00); + mas_codec_writereg(0x10, (tmp + 0x80) & 0xff00); #else l = value; r = value; Index: firmware/export/id3.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/id3.h,v retrieving revision 1.4 diff -u -u -r1.4 id3.h --- firmware/export/id3.h 4 Jun 2003 15:09:35 -0000 1.4 +++ firmware/export/id3.h 19 Jan 2004 07:46:16 -0000 @@ -30,10 +30,12 @@ char* track_string ; char* year_string ; char* composer ; + char* rva2_string; int tracknum; int version; int layer; int year; + int rva2; /* relative volume adjustment */ unsigned char id3version; unsigned char genre; unsigned int bitrate; Index: firmware/export/mp3_playback.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/mp3_playback.h,v retrieving revision 1.2 diff -u -u -r1.2 mp3_playback.h --- firmware/export/mp3_playback.h 10 Jan 2004 15:39:56 -0000 1.2 +++ firmware/export/mp3_playback.h 19 Jan 2004 07:46:16 -0000 @@ -27,6 +27,7 @@ /* functions formerly in mpeg.c */ void mp3_init(int volume, int bass, int treble, int balance, int loudness, int bass_boost, int avc, int channel_config); +void mpeg_volume_rva2(int rva2, int volume); void mpeg_sound_set(int setting, int value); int mpeg_sound_min(int setting); int mpeg_sound_max(int setting);