[pulseaudio-discuss] An raop2 support

Hajime Fujita crisp.fujita at nifty.com
Thu Sep 19 20:47:40 PDT 2013


Hi Tanu,

Tanu Kaskinen wrote:
> On Wed, 2013-09-18 at 23:09 -0500, Hajime Fujita wrote:
>> Hi Tanu,
>>
>> Thank you so much for your advice.
>>
>> Tanu Kaskinen wrote:
>>> On Sun, 2013-09-15 at 00:24 -0500, Hajime Fujita wrote:
>>>> For those who are interested in raop2 experiments,
>>>>
>>>> As Matthias pointed out [1], current volume calculation is incorrect.
>>>> https://bugs.freedesktop.org/show_bug.cgi?id=42804#c43
>>>>
>>>> I have uploaded a patch which calculates volume in more reasonable way.
>>>> https://github.com/hfujita/pulseaudio-raop2/commit/69f3ce883dfb93eb7b24f98b9664e14071672475
>>>>
>>>> First I have to confess that this is the first time for me to deal with
>>>> the unit 'dB', so maybe I'm doing totally stupid. I'd be very happy if I
>>>> could have any suggestions from who is more experienced in this field.
>>>>
>>>> I started looking at pa_raop_client_set_volume() in
>>>> src/modules/raop/raop_client.c. It was using pa_sw_volume_to_dB to
>>>> calculate dB from a linear scale.
>>>
>>> Correction: pa_volume_t doesn't use a linear scale, it uses a cubic
>>> scale (see pa_sw_volume_from_linear() and pa_sw_volume_to_linear()).
>>
>> I see. I should have noticed some comments about cubic scale.
>> http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/src/pulse/volume.c#n251
>>
>>>
>>>> Then I learned from code reading that pa_sw_volume_to_dB essentially
>>>> calculates the following:
>>>>   20 * log10((v/MAXVOLUME)^3) = 60 * log10(v/MAXVOLUME)
>>>> This does not fit into the volume scale which RAOP is expecting, where
>>>> -30.0 db is a kind of minimum [2].
>>>>
>>>> [2]: http://git.zx2c4.com/Airtunes2/about/#id29
>>>>
>>>> Also I looked at packet dumps from iPad and guessed how it calculated dB
>>>> from a linear scale. It looked like iPad was using the following formula.
>>>>   db = 10 * log10(volume/MAXVOLUME/30)
>>>> So for the time being I decided to follow this way.
>>>
>>> The way to convert pa_volume_t to dB is to use pa_sw_volume_to_dB().
>>> Doing anything else means that the result is not dB, it's something
>>> different.
>>>
>>> The way to handle this is to ensure that the volume that is given to
>>> pa_raop_client_set_volume() is never outside the supported range. In
>>> module-raop-sink.c there's sink_set_volume_cb(), which calls
>>> pa_raop_client_set_volume(). In sink_set_volume_cb() there's this line:
>>>
>>>     pa_cvolume_set(&hw, s->sample_spec.channels, v);
>>>
>>> Before that line you should check what dB value v corresponds to, and if
>>> it's outside the supported range, then you should modify v to fall into
>>> the supported range. Any modification that you make to v will be
>>> compensated with software volume, so the modifications shouldn't affect
>>> the resulting volume at all, assuming that the RAOP device actually
>>> attenuates the signal by the dB amount that you send to it.
>>>
>>
>> According to your advice, I inserted an adjustment to v before
>> pa_cvolume_set. Here's the patch.
>> https://github.com/hfujita/pulseaudio-raop2/commit/c6337c0fef7710ee20b42ed3fb87ec12910ce35a
>>
>> Adjustment goes like this (pa_raop_client_adjust_volume()):
>>   adj(v) = v * (1 - minv/maxv) + minv;
>> where pa_sw_volume_to_dB(minv) = -30.0,
>> and pa_sw_volume_to_dB(maxv) = 0.0
>>
>> The idea is that when the original v is 0, adj(0) = minv. And when the
>> original v is maxv, adj(maxv) = maxv;
>>
>> Does this make sense?
> 
> The idea was to simply adjust v to -30 dB if the original v is less than
> that. There's no need to do any complicated calculations.

Do you mean something like
  v = max(minv, v); /* where minv corresponds to -30.0dB */ ?

If I do that, resulted volume will be almost muted in the range of 0% <=
v <= 31%, then suddenly goes up beyond 31%. (31% is where dB becomes -30.0)
I was afraid that this was not an intuitive behavior to users.

>> As you noted, this also affects the software volume, and in my
>> environment, the actual volume (volume heard from the speaker) may be
>> way too small.
> 
> What do you mean by way too small? The maximum volume will be the same
> as before, but the minimum volume will be quieter than before. With the
> original code you complained that you need to keep the volume at rather
> low levels, so extending the scale towards low volumes should help with
> this.

Well, this could be just my personal feeling. Since it was a bit loud
before (however it was almost the same volume level as iPad), this time
I felt it was way too small.

I wonder if it makes sense to 1) adjust v as
  adj(v) = v * (1 - minv/maxv) + minv;
and 2) use the original v for pa_cvolume_set(), then 3) use adj(v) for
setting the actual RAOP device volume.
Under this condition, the calculated software volume always becomes
100%, as in the current (mainline) raop module.


Thanks,
Hajime



More information about the pulseaudio-discuss mailing list