From 2654d91aebb50453a52bba7de5bd0ec5ebcdfdd3 Mon Sep 17 00:00:00 2001 From: Anton Oleynikov Date: Sun, 4 Dec 2005 14:33:10 +0000 Subject: iRiver: new sound option "prevent clipping:adjust volume/adjust bass/adjust current/off" git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8145 a1c6a512-1295-4272-9138-f99709370657 --- apps/lang/english.lang | 30 +++++++++ apps/settings.c | 11 +++- apps/settings.h | 3 + apps/sound_menu.c | 18 ++++++ firmware/export/sound.h | 15 +++++ firmware/sound.c | 158 +++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 220 insertions(+), 15 deletions(-) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 40b84bbeab..502348def2 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -3466,3 +3466,33 @@ desc: in radio screen / menu eng: "Mode:" voice: "" new: + +id: LANG_SCALING_MODE +desc: in sound_settings. How to scale volume/bass to prevent clipping +eng: "Prevent clipping" +voice: "Prevent clipping" +new: + +id: LANG_SCALE_OFF +desc: in sound_settings. Do not reduce volume/bass +eng: "Off" +voice: "Off" +new: + +id: LANG_SCALE_VOLUME +desc: in sound_settings. Reduce volume +eng: "Adjust volume" +voice: "Adjust volume" +new: + +id: LANG_SCALE_BASS +desc: in sound_settings. Reduce bass +eng: "Adjust bass" +voice: "Adjust bass" +new: + +id: LANG_SCALE_CURRENT +desc: in sound_settings. Reduce other metric than currently modified +eng: "Adjust current" +voice: "Adjust current" +new: diff --git a/apps/settings.c b/apps/settings.c index edcef4a271..302cf51e26 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -85,7 +85,7 @@ const char rec_base_directory[] = REC_BASE_DIR; #include "dsp.h" #endif -#define CONFIG_BLOCK_VERSION 33 +#define CONFIG_BLOCK_VERSION 34 #define CONFIG_BLOCK_SIZE 512 #define RTC_BLOCK_SIZE 44 @@ -210,6 +210,9 @@ static const struct bit_entry rtc_bits[] = {3, S_O(channel_config), 0, "channels", "stereo,mono,custom,mono left,mono right,karaoke" }, {8, S_O(stereo_width), 100, "stereo width", NULL}, +#ifdef HAVE_UDA1380 + {2, S_O(sound_scaling), SOUND_SCALE_VOLUME, "prevent clipping", "adjust volume,adjust bass,adjust current,off"}, +#endif /* playback */ {1, S_O(resume), false, "resume", off_on }, {1, S_O(playlist_shuffle), false, "shuffle", off_on }, @@ -836,6 +839,9 @@ void sound_settings_apply(void) sound_set(SOUND_VOLUME, global_settings.volume); sound_set(SOUND_CHANNELS, global_settings.channel_config); sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width); +#ifdef HAVE_UDA1380 + sound_set(SOUND_SCALING, global_settings.sound_scaling); +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) sound_set(SOUND_LOUDNESS, global_settings.loudness); sound_set(SOUND_AVC, global_settings.avc); @@ -1415,6 +1421,9 @@ void settings_reset(void) { global_settings.treble = sound_default(SOUND_TREBLE); global_settings.channel_config = sound_default(SOUND_CHANNELS); global_settings.stereo_width = sound_default(SOUND_STEREO_WIDTH); +#ifdef HAVE_UDA1380 + global_settings.sound_scaling = sound_default(SOUND_SCALING); +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) global_settings.loudness = sound_default(SOUND_LOUDNESS); global_settings.avc = sound_default(SOUND_AVC); diff --git a/apps/settings.h b/apps/settings.h index 958703396d..9f9cc63602 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -157,6 +157,9 @@ struct user_settings int avc; /* auto volume correct: 0=off, 1=20ms, 2=2s 3=4s 4=8s */ int channel_config; /* Stereo, Mono, Custom, Mono left, Mono right, Karaoke */ int stereo_width; /* 0-255% */ +#ifdef HAVE_UDA1380 + int sound_scaling; /* Off, Volume, Bass, Current metric */ +#endif int mdb_strength; /* 0-127dB */ int mdb_harmonics; /* 0-100% */ int mdb_center; /* 20-300Hz */ diff --git a/apps/sound_menu.c b/apps/sound_menu.c index d8795ab8ae..06887cf9d3 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c @@ -349,6 +349,21 @@ static bool stereo_width(void) SOUND_STEREO_WIDTH); } +#ifdef HAVE_UDA1380 +static bool sound_scaling(void) +{ + static const struct opt_items names[] = { + { STR(LANG_SCALE_VOLUME) }, + { STR(LANG_SCALE_BASS) }, + { STR(LANG_SCALE_CURRENT)}, + { STR(LANG_SCALE_OFF) } + }; + + return set_option(str(LANG_SCALING_MODE), &global_settings.sound_scaling, INT, + names, 4, sound_set_scaling); +} +#endif + bool sound_menu(void) { int m; @@ -360,6 +375,9 @@ bool sound_menu(void) { ID2P(LANG_BALANCE), balance }, { ID2P(LANG_CHANNEL_MENU), chanconf }, { ID2P(LANG_STEREO_WIDTH), stereo_width }, +#ifdef HAVE_UDA1380 + { ID2P(LANG_SCALING_MODE), sound_scaling }, +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) { ID2P(LANG_LOUDNESS), loudness }, { ID2P(LANG_AUTOVOL), avc }, diff --git a/firmware/export/sound.h b/firmware/export/sound.h index 2c002063db..3c7dec62b0 100644 --- a/firmware/export/sound.h +++ b/firmware/export/sound.h @@ -26,6 +26,9 @@ enum { SOUND_BALANCE, SOUND_CHANNELS, SOUND_STEREO_WIDTH, +#ifdef HAVE_UDA1380 + SOUND_SCALING, +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) SOUND_LOUDNESS, SOUND_AVC, @@ -56,6 +59,15 @@ enum { SOUND_CHAN_KARAOKE, }; +#ifdef HAVE_UDA1380 +enum { + SOUND_SCALE_VOLUME = 0, + SOUND_SCALE_BASS, + SOUND_SCALE_CURRENT, + SOUND_SCALE_OFF +}; +#endif + typedef void sound_set_type(int value); const char *sound_unit(int setting); @@ -72,6 +84,9 @@ void sound_set_bass(int value); void sound_set_treble(int value); void sound_set_channels(int value); void sound_set_stereo_width(int value); +#ifdef HAVE_UDA1380 +void sound_set_scaling(int value); +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_loudness(int value); void sound_set_avc(int value); diff --git a/firmware/sound.c b/firmware/sound.c index 9ab545f51d..0516987e26 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -63,6 +63,7 @@ static const struct sound_settings_info sound_settings_table[] = { #elif defined(HAVE_UDA1380) [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0, sound_set_bass}, [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0, sound_set_treble}, + [SOUND_SCALING] = {"", 0, 1, 0, 1, 0, sound_set_scaling}, #else /* MAS3507D */ [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, [SOUND_TREBLE] = {"dB", 0, 1, -15, 15, 7, sound_set_treble}, @@ -251,6 +252,20 @@ static int tenthdb2master(int db) { else /* 0.25 dB steps */ return -db * 2 / 5; } + +static int tenthdb2mixer(int db) { + if (db < -720) + return 228; + else if (db < -660) + return 224; + else if (db < -600) + return 216; + else if (db < -470) + return (460 - db) / 5; + else + return -db * 2 / 5; +} + #endif #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 @@ -263,6 +278,89 @@ int current_balance = 0; /* -960..+960 -840..+840 */ int current_treble = 0; /* -150..+150 0.. +60 */ int current_bass = 0; /* -150..+150 0..+240 */ +#ifdef HAVE_UDA1380 + +#define MODIFYING_VOLUME 0 +#define MODIFYING_BASS 1 +#define MODIFYING_BALANCE 2 +#define MODIFYING_NONE 3 + +int current_scaling_mode = SOUND_SCALE_VOLUME; +int current_start_l_r = VOLUME_MAX; + +static void set_prescaled_volume_and_bass(int scaling_mode, bool just_balance) +{ + int l = VOLUME_MAX, r = VOLUME_MAX, prescale; + int new_bass = 0, new_volume = 0; + + if(scaling_mode == SOUND_SCALE_OFF) + { + if (current_volume > VOLUME_MAX) + current_volume = VOLUME_MAX; + new_bass = (current_bass/10) >> 1; + new_volume = tenthdb2mixer(current_volume); + + } + else if(scaling_mode == SOUND_SCALE_BASS) + { + if (current_volume > VOLUME_MAX) + current_volume = VOLUME_MAX; + + prescale = ((VOLUME_MAX - current_volume) / 20); + + if ((current_bass + current_volume) <= VOLUME_MAX) + new_bass = current_bass / 20; + else + new_bass = prescale; /* limit bass with volume */ + + new_volume = tenthdb2mixer(current_volume); + + } + else if(scaling_mode == SOUND_SCALE_VOLUME) + { + prescale = current_bass; + if (prescale < 0) + prescale = 0; + + new_bass = (current_bass/10) >> 1; + new_volume = prescale*2/5; + + if (current_volume + prescale > VOLUME_MAX) + prescale = VOLUME_MAX - current_volume; + + l = r = current_volume + prescale; + } + else if(scaling_mode == SOUND_SCALE_CURRENT) + { + l = r = current_start_l_r; + + } + + if(!just_balance) + { + uda1380_set_bass(new_bass); + uda1380_set_mixer_vol(new_volume, new_volume); + } + + current_start_l_r = l; + + if (current_balance > 0) { + l -= current_balance; + if (l < VOLUME_MIN) + l = VOLUME_MIN; + } + if (current_balance < 0) { + r += current_balance; + if (r < VOLUME_MIN) + r = VOLUME_MIN; + } + + uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); +} + +#endif + +#if CONFIG_CODEC == MAS3507D static void set_prescaled_volume(void) { int prescale; @@ -273,12 +371,7 @@ static void set_prescaled_volume(void) prescale = 0; /* no need to prescale if we don't boost bass or treble */ -#if CONFIG_CODEC == MAS3507D mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); -#else /* UDA1380 */ - uda1380_set_mixer_vol(prescale*2/5, prescale*2/5); - /* The needed range of 0..-24 dB is fortunately linear */ -#endif /* gain up the analog volume to compensate the prescale gain reduction, * but limit to the possible maximum */ @@ -299,12 +392,28 @@ static void set_prescaled_volume(void) r = VOLUME_MIN; } -#if CONFIG_CODEC == MAS3507D dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); -#else /* UDA1380 */ - uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); +} #endif + +#ifdef HAVE_UDA1380 +static void set_prescaled_volume(int modifying) +{ + if (modifying == MODIFYING_BALANCE) + set_prescaled_volume_and_bass(current_scaling_mode,true); + else if (current_scaling_mode == SOUND_SCALE_OFF) + set_prescaled_volume_and_bass(current_scaling_mode,false); + else if(( (modifying == MODIFYING_BASS) + && (current_scaling_mode == SOUND_SCALE_CURRENT)) || + (current_scaling_mode == SOUND_SCALE_VOLUME)) + set_prescaled_volume_and_bass(SOUND_SCALE_VOLUME,false); + else if(( (modifying == MODIFYING_VOLUME) + && (current_scaling_mode == SOUND_SCALE_CURRENT)) || + (current_scaling_mode == SOUND_SCALE_BASS)) + set_prescaled_volume_and_bass(SOUND_SCALE_BASS,false); } +#endif + #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ #endif /* !SIMULATOR */ @@ -402,9 +511,12 @@ void sound_set_volume(int value) #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) int tmp = 0x7f00 * value / 100; mas_codec_writereg(0x10, tmp & 0xff00); -#elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 +#elif (CONFIG_CODEC == MAS3507D) + current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100); + set_prescaled_volume(); /* tenth of dB */ +#elif defined HAVE_UDA1380 current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100); - set_prescaled_volume(); /* tenth of dB */ + set_prescaled_volume(MODIFYING_VOLUME); /* tenth of dB */ #elif (CONFIG_CPU == PP5020) /* TODO: Implement sound_set_volume() */ (void)value; @@ -418,9 +530,12 @@ void sound_set_balance(int value) #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) int tmp = ((value * 127 / 100) & 0xff) << 8; mas_codec_writereg(0x11, tmp & 0xff00); -#elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 +#elif CONFIG_CODEC == MAS3507D current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ set_prescaled_volume(); +#elif defined HAVE_UDA1380 + current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ + set_prescaled_volume(MODIFYING_BALANCE); #elif (CONFIG_CPU == PP5020) /* TODO: Implement sound_set_balance() */ (void)value; @@ -439,9 +554,8 @@ void sound_set_bass(int value) current_bass = value * 10; set_prescaled_volume(); #elif defined(HAVE_UDA1380) - uda1380_set_bass(value >> 1); current_bass = value * 10; - set_prescaled_volume(); + set_prescaled_volume(MODIFYING_BASS); #elif (CONFIG_CPU == PP5020) /* TODO: Implement sound_set_bass() */ (void)value; @@ -462,7 +576,6 @@ void sound_set_treble(int value) #elif defined(HAVE_UDA1380) uda1380_set_treble(value >> 1); current_treble = value * 10; - set_prescaled_volume(); #elif (CONFIG_CPU == PP5020) /* TODO: Implement sound_set_treble() */ (void)value; @@ -486,6 +599,16 @@ void sound_set_stereo_width(int value) set_channel_config(); } +#ifdef HAVE_UDA1380 +void sound_set_scaling(int value) +{ + current_scaling_mode = value; + if(!audio_is_initialized) + return; + set_prescaled_volume(MODIFYING_NONE); +} +#endif + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_loudness(int value) { @@ -603,6 +726,13 @@ void sound_set_stereo_width(int value) (void)value; } +#ifdef HAVE_UDA1380 +void sound_set_scaling(int value) +{ + (void)value; +} +#endif + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_loudness(int value) { -- cgit v1.2.3