[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