From 12a0e221de7ae39b221f38fe5cd8165440a79d2e Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sun, 19 Jun 2005 23:33:23 +0000 Subject: [PATCH] iriver: Prescale the digital volume when boosting treble/bass by decreasing the mixer volume. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6770 a1c6a512-1295-4272-9138-f99709370657 --- apps/pcm_recording.c | 2 +- firmware/drivers/uda1380.c | 15 ++++- firmware/export/uda1380.h | 3 +- firmware/sound.c | 128 +++++++++++++++++-------------------- 4 files changed, 75 insertions(+), 73 deletions(-) diff --git a/apps/pcm_recording.c b/apps/pcm_recording.c index dbaf4e0c2a..e906177833 100644 --- a/apps/pcm_recording.c +++ b/apps/pcm_recording.c @@ -73,7 +73,7 @@ bool pcm_rec_screen(void) //cpu_boost(true); uda1380_enable_output(true); - uda1380_setvol(play_vol, play_vol); + uda1380_set_master_vol(play_vol, play_vol); rec_monitor = 0; // No record feedback rec_source = 1; // Mic diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index bba7d19d04..7fd65a75e2 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c @@ -54,7 +54,7 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ REG_MUTE, MUTE_MASTER, /* Mute everything to start with */ - REG_MIX_CTL, 0, + REG_MIX_CTL, MIX_CTL_MIX, /* Enable mixer */ REG_DEC_VOL, 0, REG_PGA, MUTE_ADC, REG_ADC, SKIP_DCFIL, @@ -87,14 +87,23 @@ int uda1380_write_reg(unsigned char reg, unsigned short value) /** * Sets left and right master volume (0(max) to 252(muted)) */ -int uda1380_setvol(int vol_l, int vol_r) +int uda1380_set_master_vol(int vol_l, int vol_r) { return uda1380_write_reg(REG_MASTER_VOL, MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); } /** - * Sets the bass value (0-15) + * Sets mixer volume for both channels (0(max) to 228(muted)) + */ +int uda1380_set_mixer_vol(int channel1, int channel2) +{ + return uda1380_write_reg(REG_MIX_VOL, + MIX_VOL_CH_1(channel1) | MIX_VOL_CH_2(channel2)); +} + +/** + * Sets the bass value (0-12) */ void uda1380_set_bass(int value) { diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index 503b59d102..5a32a50356 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h @@ -22,7 +22,8 @@ extern int uda1380_init(void); extern void uda1380_enable_output(bool enable); -extern int uda1380_setvol(int vol_l, int vol_r); +extern int uda1380_set_master_vol(int vol_l, int vol_r); +extern int uda1380_set_mixer_vol(int channel1, int channel2); extern void uda1380_set_bass(int value); extern void uda1380_set_treble(int value); extern int uda1380_mute(int mute); diff --git a/firmware/sound.c b/firmware/sound.c index 51244f90ac..9cac7cbd02 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -229,7 +229,10 @@ int sound_default(int setting) } #ifndef SIMULATOR -#if CONFIG_HWCODEC == MAS3507D +#if CONFIG_HWCODEC == MAS3507D /* volume/balance/treble/bass interdependency */ +#define VOLUME_MIN -780 +#define VOLUME_MAX 180 + static const unsigned int bass_table[] = { 0x9e400, /* -15dB */ @@ -320,19 +323,41 @@ static const unsigned int prescale_table[] = 0xe9400 /* 15dB */ }; -/* all values in tenth of dB */ -int current_volume = 0; /* -780..+180 */ -int current_balance = 0; /* -960..+960 */ -int current_treble = 0; /* -150..+150 */ -int current_bass = 0; /* -150..+150 */ - -/* convert tenth of dB volume to register value */ +/* convert tenth of dB volume to dac3550 register value */ static int tenthdb2reg(int db) { if (db < -540) return (db + 780) / 30; else return (db + 660) / 15; } +#endif + +#ifdef HAVE_UDA1380 /* volume/balance/treble/bass interdependency */ +#define VOLUME_MIN -840 +#define VOLUME_MAX 0 + +/* convert tenth of dB volume to master volume register value */ +static int tenthdb2master(int db) { + if (db < -720) /* 1.5 dB steps */ + return (2940 - db) / 15; + else if (db < -660) /* 0.75 dB steps */ + return (1110 - db) * 2 / 15; + else if (db < -520) /* 0.5 dB steps */ + return (520 - db) / 5; + else /* 0.25 dB steps */ + return -db * 2 / 5; +} +#endif + +#if (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 + /* volume/balance/treble/bass interdependency main part */ +#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) + +/* all values in tenth of dB MAS3507D UDA1380 */ +int current_volume = 0; /* -780..+180 -840.. 0 */ +int current_balance = 0; /* -960..+960 -840..+840 */ +int current_treble = 0; /* -150..+150 0.. +60 */ +int current_bass = 0; /* -150..+150 0..+240 */ static void set_prescaled_volume(void) { @@ -344,70 +369,39 @@ static void set_prescaled_volume(void) prescale = 0; /* no need to prescale if we don't boost bass or treble */ +#if CONFIG_HWCODEC == 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 reduction gain, - * but limit to +18 dB (the maximum the DAC can do */ - if (current_volume + prescale > 180) - prescale = 180 - current_volume; + /* gain up the analog volume to compensate the prescale gain reduction, + * but limit to the possible maximum */ + if (current_volume + prescale > VOLUME_MAX) + prescale = VOLUME_MAX - current_volume; l = r = current_volume + prescale; if (current_balance > 0) { l -= current_balance; - if (l < -780) - l = -780; + if (l < VOLUME_MIN) + l = VOLUME_MIN; } if (current_balance < 0) { r += current_balance; - if (r < -780) - r = -780; + if (r < VOLUME_MIN) + r = VOLUME_MIN; } +#if CONFIG_HWCODEC == MAS3507D dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); -} -#elif CONFIG_HWCODEC == MASNONE -#ifdef HAVE_UDA1380 /* iriver H1x0 + H3x0 */ -/* all values in tenth of dB */ -int current_volume = 0; /* -840..0 */ -int current_balance = 0; /* -840..+840 */ - -/* convert tenth of dB volume to register value */ -static int tenthdb2reg(int db) { - if (db < -720) /* 1.5 dB steps */ - return (2940 - db) / 15; - else if (db < -660) /* 0.75 dB steps */ - return (1110 - db) * 2 / 15; - else if (db < -520) /* 0.5 dB steps */ - return (520 - db) / 5; - else /* 0.25 dB steps */ - return -db * 2 / 5; -} - -static void set_volume(void) -{ - int l, r; - - l = r = current_volume; - - if (current_balance > 0) - { - l -= current_balance; - if (l < -840) - l = -840; - } - if (current_balance < 0) - { - r += current_balance; - if (r < -840) - r = -840; - } - - uda1380_setvol(tenthdb2reg(l), tenthdb2reg(r)); -} +#else /* UDA1380 */ + uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); #endif -#endif /* MASNONE */ +} +#endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */ #endif /* !SIMULATOR */ int channel_configuration = SOUND_CHAN_STEREO; @@ -516,12 +510,9 @@ void sound_set(int setting, int value) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) tmp = 0x7f00 * value / 100; mas_codec_writereg(0x10, tmp & 0xff00); -#elif CONFIG_HWCODEC == MAS3507D - current_volume = -780 + (value * 960 / 100); /* tenth of dB */ - set_prescaled_volume(); -#elif defined(HAVE_UDA1380) - current_volume = -840 + (value * 840 / 100); /* tenth of dB */ - set_volume(); +#elif (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 + current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100); + set_prescaled_volume(); /* tenth of dB */ #endif break; @@ -529,12 +520,9 @@ void sound_set(int setting, int value) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) tmp = ((value * 127 / 100) & 0xff) << 8; mas_codec_writereg(0x11, tmp & 0xff00); -#elif CONFIG_HWCODEC == MAS3507D - current_balance = value * 960 / 100; /* tenth of dB */ +#elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380 + current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ set_prescaled_volume(); -#elif defined(HAVE_UDA1380) - current_balance = value * 840 / 100; /* tenth of dB */ - set_volume(); #endif break; @@ -548,6 +536,8 @@ void sound_set(int setting, int value) set_prescaled_volume(); #elif defined(HAVE_UDA1380) uda1380_set_bass(value >> 1); + current_bass = value * 10; + set_prescaled_volume(); #endif break; @@ -561,6 +551,8 @@ void sound_set(int setting, int value) set_prescaled_volume(); #elif defined(HAVE_UDA1380) uda1380_set_treble(value >> 1); + current_treble = value * 10; + set_prescaled_volume(); #endif break;