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
This commit is contained in:
Jens Arnold 2005-06-19 23:33:23 +00:00
parent 2c28390972
commit 12a0e221de
4 changed files with 75 additions and 73 deletions

View file

@ -73,7 +73,7 @@ bool pcm_rec_screen(void)
//cpu_boost(true); //cpu_boost(true);
uda1380_enable_output(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_monitor = 0; // No record feedback
rec_source = 1; // Mic rec_source = 1; // Mic

View file

@ -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_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_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */
REG_MUTE, MUTE_MASTER, /* Mute everything to start with */ 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_DEC_VOL, 0,
REG_PGA, MUTE_ADC, REG_PGA, MUTE_ADC,
REG_ADC, SKIP_DCFIL, 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)) * 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, return uda1380_write_reg(REG_MASTER_VOL,
MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); 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) void uda1380_set_bass(int value)
{ {

View file

@ -22,7 +22,8 @@
extern int uda1380_init(void); extern int uda1380_init(void);
extern void uda1380_enable_output(bool enable); 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_bass(int value);
extern void uda1380_set_treble(int value); extern void uda1380_set_treble(int value);
extern int uda1380_mute(int mute); extern int uda1380_mute(int mute);

View file

@ -229,7 +229,10 @@ int sound_default(int setting)
} }
#ifndef SIMULATOR #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[] = static const unsigned int bass_table[] =
{ {
0x9e400, /* -15dB */ 0x9e400, /* -15dB */
@ -320,19 +323,41 @@ static const unsigned int prescale_table[] =
0xe9400 /* 15dB */ 0xe9400 /* 15dB */
}; };
/* all values in tenth of dB */ /* convert tenth of dB volume to dac3550 register value */
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 */
static int tenthdb2reg(int db) { static int tenthdb2reg(int db) {
if (db < -540) if (db < -540)
return (db + 780) / 30; return (db + 780) / 30;
else else
return (db + 660) / 15; 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) 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 prescale = 0; /* no need to prescale if we don't boost
bass or treble */ bass or treble */
#if CONFIG_HWCODEC == MAS3507D
mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); 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, /* gain up the analog volume to compensate the prescale gain reduction,
* but limit to +18 dB (the maximum the DAC can do */ * but limit to the possible maximum */
if (current_volume + prescale > 180) if (current_volume + prescale > VOLUME_MAX)
prescale = 180 - current_volume; prescale = VOLUME_MAX - current_volume;
l = r = current_volume + prescale; l = r = current_volume + prescale;
if (current_balance > 0) if (current_balance > 0)
{ {
l -= current_balance; l -= current_balance;
if (l < -780) if (l < VOLUME_MIN)
l = -780; l = VOLUME_MIN;
} }
if (current_balance < 0) if (current_balance < 0)
{ {
r += current_balance; r += current_balance;
if (r < -780) if (r < VOLUME_MIN)
r = -780; r = VOLUME_MIN;
} }
#if CONFIG_HWCODEC == MAS3507D
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
} #else /* UDA1380 */
#elif CONFIG_HWCODEC == MASNONE uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r));
#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));
}
#endif #endif
#endif /* MASNONE */ }
#endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */
#endif /* !SIMULATOR */ #endif /* !SIMULATOR */
int channel_configuration = SOUND_CHAN_STEREO; int channel_configuration = SOUND_CHAN_STEREO;
@ -516,12 +510,9 @@ void sound_set(int setting, int value)
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
tmp = 0x7f00 * value / 100; tmp = 0x7f00 * value / 100;
mas_codec_writereg(0x10, tmp & 0xff00); mas_codec_writereg(0x10, tmp & 0xff00);
#elif CONFIG_HWCODEC == MAS3507D #elif (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380
current_volume = -780 + (value * 960 / 100); /* tenth of dB */ current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100);
set_prescaled_volume(); set_prescaled_volume(); /* tenth of dB */
#elif defined(HAVE_UDA1380)
current_volume = -840 + (value * 840 / 100); /* tenth of dB */
set_volume();
#endif #endif
break; break;
@ -529,12 +520,9 @@ void sound_set(int setting, int value)
#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
tmp = ((value * 127 / 100) & 0xff) << 8; tmp = ((value * 127 / 100) & 0xff) << 8;
mas_codec_writereg(0x11, tmp & 0xff00); mas_codec_writereg(0x11, tmp & 0xff00);
#elif CONFIG_HWCODEC == MAS3507D #elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380
current_balance = value * 960 / 100; /* tenth of dB */ current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
set_prescaled_volume(); set_prescaled_volume();
#elif defined(HAVE_UDA1380)
current_balance = value * 840 / 100; /* tenth of dB */
set_volume();
#endif #endif
break; break;
@ -548,6 +536,8 @@ void sound_set(int setting, int value)
set_prescaled_volume(); set_prescaled_volume();
#elif defined(HAVE_UDA1380) #elif defined(HAVE_UDA1380)
uda1380_set_bass(value >> 1); uda1380_set_bass(value >> 1);
current_bass = value * 10;
set_prescaled_volume();
#endif #endif
break; break;
@ -561,6 +551,8 @@ void sound_set(int setting, int value)
set_prescaled_volume(); set_prescaled_volume();
#elif defined(HAVE_UDA1380) #elif defined(HAVE_UDA1380)
uda1380_set_treble(value >> 1); uda1380_set_treble(value >> 1);
current_treble = value * 10;
set_prescaled_volume();
#endif #endif
break; break;