diff --git a/spa/plugins/alsa/acp/acp.c b/spa/plugins/alsa/acp/acp.c index e227daa72..57a31d288 100644 --- a/spa/plugins/alsa/acp/acp.c +++ b/spa/plugins/alsa/acp/acp.c @@ -644,51 +644,53 @@ static void add_profiles(pa_card *impl) snprintf(name, sizeof(name), "api.acp.port.%s.min-volume", dp->name); if ((str = pa_proplist_gets(impl->proplist, name))) - spa_atof(str, &dp->volume_range[0]); + spa_atof(str, &dp->hard_volume_limit[0]); else - dp->volume_range[0] = impl->volume_range[0]; + dp->hard_volume_limit[0] = impl->hard_volume_limit[0]; snprintf(name, sizeof(name), "api.acp.port.%s.max-volume", dp->name); if ((str = pa_proplist_gets(impl->proplist, name))) - spa_atof(str, &dp->volume_range[1]); + spa_atof(str, &dp->hard_volume_limit[1]); else - dp->volume_range[1] = impl->volume_range[1]; + dp->hard_volume_limit[1] = impl->hard_volume_limit[1]; + dp->soft_volume_limit[0] = dp->hard_volume_limit[0]; + dp->soft_volume_limit[1] = dp->hard_volume_limit[1]; pa_proplist_setf(dp->proplist, "card.profile.port", "%u", dp->port.index); pa_proplist_as_dict(dp->proplist, &dp->port.props); pa_dynarray_append(&impl->out.ports, dp); } PA_DYNARRAY_FOREACH(dev, &impl->out.devices, idx) { - float vol_range[2] = { 0.0f, FLT_MAX }; + float vol_limit[2] = { 0.0f, FLT_MAX }; n_ports = 0; snprintf(name, sizeof(name), "api.acp.device.%s.min-volume", dev->device.name); if ((str = pa_proplist_gets(impl->proplist, name))) - spa_atof(str, &vol_range[0]); + spa_atof(str, &vol_limit[0]); else - vol_range[0] = impl->volume_range[0]; + vol_limit[0] = impl->hard_volume_limit[0]; snprintf(name, sizeof(name), "api.acp.device.%s.max-volume", dev->device.name); if ((str = pa_proplist_gets(impl->proplist, name))) - spa_atof(str, &vol_range[1]); + spa_atof(str, &vol_limit[1]); else - vol_range[1] = impl->volume_range[1]; + vol_limit[1] = impl->hard_volume_limit[1]; PA_HASHMAP_FOREACH(dp, dev->ports, state) { if (n_ports == 0) { - vol_range[0] = dp->volume_range[0]; - vol_range[1] = dp->volume_range[1]; + vol_limit[0] = dp->hard_volume_limit[0]; + vol_limit[1] = dp->hard_volume_limit[1]; } else { - vol_range[0] = fminf(vol_range[0], dp->volume_range[0]); - vol_range[1] = fmaxf(vol_range[1], dp->volume_range[1]); + vol_limit[0] = fminf(vol_limit[0], dp->hard_volume_limit[0]); + vol_limit[1] = fmaxf(vol_limit[1], dp->hard_volume_limit[1]); } pa_dynarray_append(&dev->port_array, dp); pa_dynarray_append(&dp->devices, dev); n_ports++; } if (n_ports == 0) { - pa_proplist_setf(dev->proplist, "channelmix.min-volume", "%f", vol_range[0]); - pa_proplist_setf(dev->proplist, "channelmix.max-volume", "%f", vol_range[1]); + pa_proplist_setf(dev->proplist, "channelmix.min-volume", "%f", vol_limit[0]); + pa_proplist_setf(dev->proplist, "channelmix.max-volume", "%f", vol_limit[1]); } pa_proplist_as_dict(dev->proplist, &dev->device.props); @@ -1990,8 +1992,8 @@ struct acp_card *acp_card_new(uint32_t index, const struct acp_dict *props) impl->ignore_dB = false; impl->rate = DEFAULT_RATE; impl->pro_channels = DEFAULT_CHANNELS; - impl->volume_range[0] = 0.0f; - impl->volume_range[1] = FLT_MAX; + impl->hard_volume_limit[0] = 0.0f; + impl->hard_volume_limit[1] = FLT_MAX; if (props) { if ((s = acp_dict_lookup(props, "api.alsa.use-ucm")) != NULL) @@ -2021,9 +2023,9 @@ struct acp_card *acp_card_new(uint32_t index, const struct acp_dict *props) if ((s = acp_dict_lookup(props, "api.acp.use-eld-channels")) != NULL) impl->use_eld_channels = spa_atob(s); if ((s = acp_dict_lookup(props, "api.acp.min-volume")) != NULL) - spa_atof(s, &impl->volume_range[0]); + spa_atof(s, &impl->hard_volume_limit[0]); if ((s = acp_dict_lookup(props, "api.acp.max-volume")) != NULL) - spa_atof(s, &impl->volume_range[1]); + spa_atof(s, &impl->hard_volume_limit[1]); } #if SND_LIB_VERSION < 0x10207 @@ -2344,17 +2346,19 @@ int acp_device_get_volume_limit(struct acp_device *dev, float *min, float *max) pa_alsa_device *d = (pa_alsa_device*)dev; pa_card *impl = d->card; pa_device_port *p; - float *volume_range; - - if ((p = d->active_port) != NULL) - volume_range = p->volume_range; - else - volume_range = impl->volume_range; + float *soft_volume_limit, *hard_volume_limit; + if ((p = d->active_port) != NULL) { + soft_volume_limit = p->soft_volume_limit; + hard_volume_limit = p->hard_volume_limit; + } else { + soft_volume_limit = impl->hard_volume_limit; + hard_volume_limit = impl->hard_volume_limit; + } if (min) - *min = volume_range[0]; + *min = fmaxf(soft_volume_limit[0], hard_volume_limit[0]); if (max) - *max = volume_range[1]; + *max = fminf(soft_volume_limit[1], hard_volume_limit[1]); return 0; } int acp_device_set_volume_limit(struct acp_device *dev, float min, float max) @@ -2362,15 +2366,18 @@ int acp_device_set_volume_limit(struct acp_device *dev, float min, float max) pa_alsa_device *d = (pa_alsa_device*)dev; pa_card *impl = d->card; pa_device_port *p; - float *volume_range; + float *soft_volume_limit, *hard_volume_limit; - if ((p = d->active_port) != NULL) - volume_range = p->volume_range; - else - volume_range = impl->volume_range; - - volume_range[0] = min; - volume_range[1] = max; + if ((p = d->active_port) != NULL) { + soft_volume_limit = p->soft_volume_limit; + hard_volume_limit = p->hard_volume_limit; + } + else { + soft_volume_limit = impl->hard_volume_limit; + hard_volume_limit = impl->hard_volume_limit; + } + soft_volume_limit[0] = fmaxf(min, hard_volume_limit[0]); + soft_volume_limit[1] = fminf(max, hard_volume_limit[1]); return 0; } @@ -2381,7 +2388,7 @@ int acp_device_set_volume(struct acp_device *dev, const float *volume, uint32_t uint32_t i; pa_cvolume v, old_volume; pa_device_port *p; - float *volume_range; + float *volume_limit; if (n_volume == 0) return -EINVAL; @@ -2389,14 +2396,14 @@ int acp_device_set_volume(struct acp_device *dev, const float *volume, uint32_t old_volume = d->real_volume; if ((p = d->active_port) != NULL) - volume_range = p->volume_range; + volume_limit = p->soft_volume_limit; else - volume_range = impl->volume_range; + volume_limit = impl->hard_volume_limit; v.channels = d->mapping->channel_map.channels; for (i = 0; i < v.channels; i++) v.values[i] = pa_sw_volume_from_linear( - SPA_CLAMPF(volume[i % n_volume], volume_range[0], volume_range[1])); + SPA_CLAMPF(volume[i % n_volume], volume_limit[0], volume_limit[1])); pa_log_info("Set %s volume: min:%d max:%d", d->set_volume ? "hardware" : "software", diff --git a/spa/plugins/alsa/acp/card.h b/spa/plugins/alsa/acp/card.h index 351637814..e57fa7396 100644 --- a/spa/plugins/alsa/acp/card.h +++ b/spa/plugins/alsa/acp/card.h @@ -52,7 +52,7 @@ struct pa_card { bool use_eld_channels; uint32_t rate; uint32_t pro_channels; - float volume_range[2]; + float hard_volume_limit[2]; pa_alsa_ucm_config ucm; pa_alsa_profile_set *profile_set; diff --git a/spa/plugins/alsa/acp/compat.c b/spa/plugins/alsa/acp/compat.c index 646046764..22cb3f329 100644 --- a/spa/plugins/alsa/acp/compat.c +++ b/spa/plugins/alsa/acp/compat.c @@ -142,8 +142,10 @@ pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, si p->port.direction = data->direction == PA_DIRECTION_OUTPUT ? ACP_DIRECTION_PLAYBACK : ACP_DIRECTION_CAPTURE; p->type = data->type; - p->volume_range[0] = 0.0f; - p->volume_range[1] = FLT_MAX; + p->hard_volume_limit[0] = 0.0f; + p->hard_volume_limit[1] = FLT_MAX; + p->soft_volume_limit[0] = p->hard_volume_limit[0]; + p->soft_volume_limit[1] = p->hard_volume_limit[1]; p->proplist = pa_proplist_new(); pa_proplist_sets(p->proplist, ACP_KEY_PORT_TYPE, str_port_type(data->type)); diff --git a/spa/plugins/alsa/acp/device-port.h b/spa/plugins/alsa/acp/device-port.h index b5aa6854b..5ee6c9b87 100644 --- a/spa/plugins/alsa/acp/device-port.h +++ b/spa/plugins/alsa/acp/device-port.h @@ -76,7 +76,8 @@ struct pa_device_port { pa_direction_t direction; int64_t latency_offset; - float volume_range[2]; + float hard_volume_limit[2]; + float soft_volume_limit[2]; pa_proplist *proplist; pa_hashmap *profiles;