mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-12 00:47:49 -04:00
misc: fix issues with perceptual volume calculations
The constant NVOL_FACTOR used in the calculations needs to be scaled if the target doesn't represent volumes in 1/10th dB units (ie. most targets). Using a wrong factor caused the results to be slightly "off", with wide steps between points on the upper end of the volume curve. Drop use_linear_dB_scale() because the magic constant involved has a similar problem (and we don't use this function anyway). Also, make sure to account for the guaranteed min/max points when generating the normalized volume table to avoid sometimes generating one or two extra volume steps very close to the min/max volumes. Change-Id: I5c15809a7306f14bb1befe6d29a5e2b5b0974eaa
This commit is contained in:
parent
ad9471be3b
commit
3f2ca20245
1 changed files with 20 additions and 35 deletions
51
apps/misc.c
51
apps/misc.c
|
|
@ -904,7 +904,7 @@ static void update_norm_tab(void)
|
|||
norm_tab[0] = min;
|
||||
norm_tab_size = 1;
|
||||
|
||||
for (int i = 0; i < lim; ++i)
|
||||
for (int i = 1; i < lim - 1; ++i)
|
||||
{
|
||||
int vol = from_normalized_volume(i, min, max, lim);
|
||||
int rem = vol % step;
|
||||
|
|
@ -1944,49 +1944,40 @@ int core_load_bmp(const char * filename, struct bitmap *bm, const int bmformat,
|
|||
|
||||
#define NVOL_FRACBITS 16
|
||||
#define NVOL_UNITY (1L << NVOL_FRACBITS)
|
||||
#define NVOL_FACTOR (600L << NVOL_FRACBITS)
|
||||
|
||||
#define NVOL_MAX_LINEAR_DB_SCALE (240L << NVOL_FRACBITS)
|
||||
|
||||
#define nvol_div(x,y) fp_div((x), (y), NVOL_FRACBITS)
|
||||
#define nvol_mul(x,y) fp_mul((x), (y), NVOL_FRACBITS)
|
||||
#define nvol_exp10(x) fp_exp10((x), NVOL_FRACBITS)
|
||||
#define nvol_log10(x) fp_log10((x), NVOL_FRACBITS)
|
||||
|
||||
static bool use_linear_dB_scale(long min_vol, long max_vol)
|
||||
static long get_nvol_factor(void)
|
||||
{
|
||||
/*
|
||||
* Alsamixer uses a linear scale for small ranges.
|
||||
* Commented out so perceptual volume works as advertised on all targets.
|
||||
*/
|
||||
/*
|
||||
return max_vol - min_vol <= NVOL_MAX_LINEAR_DB_SCALE;
|
||||
*/
|
||||
long factor = 600L << NVOL_FRACBITS;
|
||||
long numdecimals = sound_numdecimals(SOUND_VOLUME);
|
||||
|
||||
(void)min_vol;
|
||||
(void)max_vol;
|
||||
return false;
|
||||
if (numdecimals == 0)
|
||||
factor /= 10;
|
||||
|
||||
/* nothing *actually* needs this, but: */
|
||||
while (numdecimals > 1)
|
||||
factor *= 10;
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
long to_normalized_volume(long vol, long min_vol, long max_vol, long max_norm)
|
||||
{
|
||||
long norm, min_norm;
|
||||
long factor = get_nvol_factor();
|
||||
|
||||
vol <<= NVOL_FRACBITS;
|
||||
min_vol <<= NVOL_FRACBITS;
|
||||
max_vol <<= NVOL_FRACBITS;
|
||||
max_norm <<= NVOL_FRACBITS;
|
||||
|
||||
if (use_linear_dB_scale(min_vol, max_vol))
|
||||
{
|
||||
norm = nvol_div(vol - min_vol, max_vol - min_vol);
|
||||
}
|
||||
else
|
||||
{
|
||||
min_norm = nvol_exp10(nvol_div(min_vol - max_vol, NVOL_FACTOR));
|
||||
norm = nvol_exp10(nvol_div(vol - max_vol, NVOL_FACTOR));
|
||||
min_norm = nvol_exp10(nvol_div(min_vol - max_vol, factor));
|
||||
norm = nvol_exp10(nvol_div(vol - max_vol, factor));
|
||||
norm = nvol_div(norm - min_norm, NVOL_UNITY - min_norm);
|
||||
}
|
||||
|
||||
return nvol_mul(norm, max_norm) >> NVOL_FRACBITS;
|
||||
}
|
||||
|
|
@ -1994,6 +1985,7 @@ long to_normalized_volume(long vol, long min_vol, long max_vol, long max_norm)
|
|||
long from_normalized_volume(long norm, long min_vol, long max_vol, long max_norm)
|
||||
{
|
||||
long vol, min_norm;
|
||||
long factor = get_nvol_factor();
|
||||
|
||||
norm <<= NVOL_FRACBITS;
|
||||
min_vol <<= NVOL_FRACBITS;
|
||||
|
|
@ -2002,16 +1994,9 @@ long from_normalized_volume(long norm, long min_vol, long max_vol, long max_norm
|
|||
|
||||
vol = nvol_div(norm, max_norm);
|
||||
|
||||
if (use_linear_dB_scale(min_vol, max_vol))
|
||||
{
|
||||
vol = nvol_mul(vol, max_vol - min_vol) + min_vol;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_norm = nvol_exp10(nvol_div(min_vol - max_vol, NVOL_FACTOR));
|
||||
min_norm = nvol_exp10(nvol_div(min_vol - max_vol, factor));
|
||||
vol = nvol_mul(vol, NVOL_UNITY - min_norm) + min_norm;
|
||||
vol = nvol_mul(nvol_log10(vol), NVOL_FACTOR) + max_vol;
|
||||
}
|
||||
vol = nvol_mul(nvol_log10(vol), factor) + max_vol;
|
||||
|
||||
return vol >> NVOL_FRACBITS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue