[alsa-devel] alsactl adds volume controls?
Colin Guthrie
gmane at colin.guthr.ie
Fri Oct 8 17:49:43 CEST 2010
'Twas brillig, and Colin Guthrie at 08/10/10 16:29 did gyre and gimble:
> 'Twas brillig, and Colin Guthrie at 08/10/10 16:25 did gyre and gimble:
>> 'Twas brillig, and Clemens Ladisch at 08/10/10 15:42 did gyre and gimble:
>>> Colin Guthrie wrote:
>>>> Hmm, just thinking about this (as I don't know the volume control logic
>>>> particularly well in PA), the call snd_mixer_selem_set_playback_dB() is
>>>> used with a dir argument of +1.
>>>>
>>>> From what I understand, this would allow me to say "set the volume to
>>>> 50dB" and due to the +1 dir, it should select -46.499999 ( because -46.5
>>>> mutes it).
>>>>
>>>> In this case however, the value of -99999.999dB is ultimately selected
>>>> (aka 0).
>>>>
>>>> I'm wondering if the TLV fix actually affects how
>>>> snd_mixer_selem_set_playback_dB() call works with the dir argument.
>>>
>>> Uh, oh. snd_tlv_convert_from_dB() ignores the minimum-is-mute flag.
>>
>> Ahh good, I analysed that kinda correctly then :D
>>
>>> Please try this hack:
>>>
>>> --- alsa-lib/src/control/tlv.c
>>> +++ alsa-lib/src/control/tlv.c
>>> @@ -335,6 +335,9 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
>>> if (xdir > 0)
>>> v += (max - min) - 1;
>>> v = v / (max - min) + rangemin;
>>> + if (v == rangemin && xdir > 0 && (tlv[3] & 0x10000) &&
>>> + db_gain > SND_CTL_TLV_DB_GAIN_MUTE)
>>> + v++;
>>> *value = v;
>>> }
>>> return 0;
>>
>>
>> Didn't help sadly, but then looking at the code there it seems a little odd.
>>
>> Firstly I tried this (extended) patch - I'm not sure it's needed but
>> when the first one didn't work I tried to experiment a bit:
>>
>> --- a/src/control/tlv.c
>> +++ b/src/control/tlv.c
>> @@ -323,15 +323,20 @@ int snd_tlv_convert_from_dB(unsigned int *tlv,
>> long rangemin, long rangemax,
>> int min, max;
>> min = tlv[2];
>> max = tlv[3];
>> - if (db_gain <= min)
>> + if (db_gain <= min) {
>> *value = rangemin;
>> - else if (db_gain >= max)
>> + if (xdir > 0 && (tlv[3] & 0x10000) && db_gain >
>> SND_CTL_TLV_DB_GAIN_MUTE)
>> + *value = rangemin + 1;
>> + } else if (db_gain >= max)
>> *value = rangemax;
>> else {
>> long v = (db_gain - min) * (rangemax - rangemin);
>> if (xdir > 0)
>> v += (max - min) - 1;
>> v = v / (max - min) + rangemin;
>> + if (v == rangemin && xdir > 0 && (tlv[3] &
>> 0x10000) &&
>> + db_gain > SND_CTL_TLV_DB_GAIN_MUTE)
>> + v++;
>> *value = v;
>> }
>> return 0;
>>
>>
>> This also catches the case when I try to set the volume to e.g. -5000
>> (-50.00dB) as it is < min (which I presume is still -4650, but actually
>> didn't check) then it will be set to rangemin and no further checks are
>> done.
>>
>> What is odd about this tho', is that the flag for min is mute (0x10000)
>> is checked on tlv[3] which is also used here for the "max" value.
>>
>> Is the use of position 3 correct (both here and on the kernel side) or
>> perhaps the max line needs to be:
>>
>> max = (tlv[3] & 0xffff);
>>
>> instead? Either way it didn't help, but I thought the strangeness with
>> the tlv[3] value was worth pointing out.
>>
>> Many thanks for debugging this with me :)
>>
>> Col
>>
>> PS, happy to chat on IRC if you prefer - coling
>
> Ignore this mail... I applied the patch to the wrong tree and it put the
> hunks in a different place as the context was a 100% match...
>
> I'll retest with this applied correctly! Sorry :D
OK, applying the patch correctly helps a lot :D
This is now working perfectly thanks.
I've attached the final patch I used. I modified your one slightly to
correct case when passing in a value that is <= min (e.g. -5000dB on my
setup) to also fix that up. As I'm not 100% sure it's needed, I'll leave
it up to you to decide which patch to apply.
Many thanks once again.
Col
--
Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/
Day Job:
Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
Mageia Contributor [http://www.mageia.org/]
PulseAudio Hacker [http://www.pulseaudio.org/]
Trac Hacker [http://trac.edgewall.org/]
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 0103-tlv-Ensure-that-min-is-mute-flag-is-honored-in-snd_t.patch
Url: http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20101008/c6beb166/attachment.bat
More information about the Alsa-devel
mailing list