module-raop-sink: Fix volume calculation

The volume interval that RAOP devices understand is [-30,0],
where -30.0 equals min vol, and 0.0 equals max. vol.

The local system volume is represented as a cubic (volumetric)
value in the [0,1] interval.

So cube root system volume value, scale by 30 and
translate -30 to map to target output range.

The special value -144 denotes volume mute. Send a corresponding RTSP
message when mute is not already toggled on.
This commit is contained in:
Christian Glombek 2023-10-03 07:15:17 +02:00
parent 5d0e82be7e
commit c5cc364794

View file

@ -149,8 +149,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define DEFAULT_POSITION "[ FL FR ]" #define DEFAULT_POSITION "[ FL FR ]"
#define VOLUME_MAX 0.0 #define VOLUME_MAX 0.0
#define VOLUME_DEF -30.0 #define VOLUME_MIN -30.0
#define VOLUME_MIN -144.0 #define VOLUME_MUTE -144.0
#define MODULE_USAGE "( raop.ip=<ip address of host> ) " \ #define MODULE_USAGE "( raop.ip=<ip address of host> ) " \
"( raop.port=<remote port> ) " \ "( raop.port=<remote port> ) " \
@ -1723,6 +1723,10 @@ static void stream_props_changed(struct impl *impl, uint32_t id, const struct sp
{ {
bool mute; bool mute;
if (spa_pod_get_bool(&prop->value, &mute) == 0) { if (spa_pod_get_bool(&prop->value, &mute) == 0) {
if (!impl->mute) {
impl->volume = VOLUME_MUTE;
rtsp_send_volume(impl);
}
impl->mute = mute; impl->mute = mute;
} }
spa_pod_builder_prop(&b, SPA_PROP_softMute, 0); spa_pod_builder_prop(&b, SPA_PROP_softMute, 0);
@ -1744,7 +1748,7 @@ static void stream_props_changed(struct impl *impl, uint32_t id, const struct sp
soft_vols[i] = 1.0f; soft_vols[i] = 1.0f;
} }
volume /= n_vols; volume /= n_vols;
volume = SPA_CLAMPF(20.0 * log10(volume), VOLUME_MIN, VOLUME_MAX); volume = SPA_CLAMPF(cbrt(volume) * 30 - 30, VOLUME_MIN, VOLUME_MAX);
impl->volume = volume; impl->volume = volume;
rtsp_send_volume(impl); rtsp_send_volume(impl);