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 --- firmware/export/sound.h | 15 +++++ firmware/sound.c | 158 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 159 insertions(+), 14 deletions(-) (limited to 'firmware') 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