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

Stefan Bader stefan.bader at canonical.com
Tue Apr 21 15:43:16 UTC 2009


Tim Gardner wrote:
> 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
> 
It seems to be a little hackery to save a temp. The intermediate value is 
propagated by slave_put_val and the master value is kept as before.

-- 

When all other means of communication fail, try words!






More information about the kernel-team mailing list