[Hardy LPIA LUM]: RealTek hda-intel volume remapping for non-linear volume scales

Tim Gardner tim.gardner at canonical.com
Tue Apr 21 15:33:17 UTC 2009


Colin Ian King wrote:
> LP#249233 - sound volume too low.
> 
> for Hardy LPIA LUM.
> 
> The attached patch fixes a hardware volume scaling issue on a variety of
> Realtek chips found on Atom based netbooks. The main issue is that
> setting the volume at low levels is very low and does not scale
> linearly. Also, at high volume levels one can get distortion. Hence
> there is a requirement to keep the volume levels between a defined
> minimum and maximum and also try and scale the provided volume levels to
> produce a perceived linear scaling response.
> 
> One can select linear or parabolic volume remapping to scale (remap) a
> volume level to physical volume level between a desired minimum
> and maximum range. This allows adjustment if the volume is not audible
> at low settings or distorts if set too high.
> 
> Linear mapping scales the volume linearly between a given low and high.
> 
> Parabolic mapping scales the volume between a given low and high
> so that low volume levels are scaled more favourably (using an inverse
> squared parabolic function) than high volume ranges to overcome
> non-linear volume scaling found on Realtek model cw020 hardware.
> 
> The default is no mapping whatsoever.
> 
> Attached: The patch.
> 
> 

Is this really doing what you expect?

 static int slave_get_val(struct link_slave *slave,
                         struct snd_ctl_elem_value *ucontrol)
 {
@@ -305,8 +360,15 @@ static int master_put(struct snd_kcontrol *kcontrol,
                master->val = old_val;
                uval->id = slave->slave.id;
                slave_get_val(slave, uval);
-               master->val = ucontrol->value.integer.value[0];
+
+               /* Put to slaves a remapped volume */
+               master->val = vol_remap(master->info.min_val,
+                                       master->info.max_val,
+                                       ucontrol->value.integer.value[0]);
                slave_put_val(slave, uval);
+               /* And actually save the original unremapped volume
+                  for master_get() */
+               master->val = ucontrol->value.integer.value[0];
        }
        kfree(uval);
        return 1;

I looks like master-val is simply set twice (unless there are side
effects happening in slave_put_val()).

rtg

-- 
Tim Gardner tim.gardner at canonical.com




More information about the kernel-team mailing list