mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
acp: add volume base and step
Add a READONLY property flag to makr properties READONLY Set the base_volume and volume_step in the acp device Send the base volume and step as REAONLY properties. Use these in pulse layer.
This commit is contained in:
parent
f75dfde89c
commit
e030445e49
8 changed files with 40 additions and 11 deletions
|
|
@ -384,6 +384,12 @@ static void parse_props(struct global *g, const struct spa_pod *param, bool devi
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPA_PROP_volumeBase:
|
||||||
|
spa_pod_get_float(&prop->value, &g->node_info.base_volume);
|
||||||
|
break;
|
||||||
|
case SPA_PROP_volumeStep:
|
||||||
|
spa_pod_get_float(&prop->value, &g->node_info.volume_step);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1037,8 +1043,10 @@ static int set_mask(pa_context *c, struct global *g)
|
||||||
g->node_info.device_id = SPA_ID_INVALID;
|
g->node_info.device_id = SPA_ID_INVALID;
|
||||||
|
|
||||||
ginfo = &node_info;
|
ginfo = &node_info;
|
||||||
g->node_info.volume = 1.0;
|
g->node_info.volume = 1.0f;
|
||||||
g->node_info.mute = false;
|
g->node_info.mute = false;
|
||||||
|
g->node_info.base_volume = 1.0f;
|
||||||
|
g->node_info.volume_step = 1.0f / (PA_VOLUME_NORM+1);
|
||||||
} else if (strcmp(g->type, PW_TYPE_INTERFACE_Port) == 0) {
|
} else if (strcmp(g->type, PW_TYPE_INTERFACE_Port) == 0) {
|
||||||
if (g->props == NULL)
|
if (g->props == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,8 @@ struct global {
|
||||||
float channel_volumes[SPA_AUDIO_MAX_CHANNELS];
|
float channel_volumes[SPA_AUDIO_MAX_CHANNELS];
|
||||||
uint32_t device_id; /* id of device (card) */
|
uint32_t device_id; /* id of device (card) */
|
||||||
uint32_t profile_device_id; /* id in profile */
|
uint32_t profile_device_id; /* id in profile */
|
||||||
|
float base_volume;
|
||||||
|
float volume_step;
|
||||||
} node_info;
|
} node_info;
|
||||||
struct {
|
struct {
|
||||||
uint32_t node_id;
|
uint32_t node_id;
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,9 @@ static void sink_callback(pa_context *c, struct global *g, struct sink_data *d)
|
||||||
i.flags |= PA_SINK_HW_MUTE_CTRL;
|
i.flags |= PA_SINK_HW_MUTE_CTRL;
|
||||||
i.proplist = pa_proplist_new_dict(info->props);
|
i.proplist = pa_proplist_new_dict(info->props);
|
||||||
i.configured_latency = 0;
|
i.configured_latency = 0;
|
||||||
i.base_volume = PA_VOLUME_NORM;
|
i.base_volume = g->node_info.base_volume * PA_VOLUME_NORM;
|
||||||
|
i.n_volume_steps = g->node_info.volume_step * (PA_VOLUME_NORM+1);
|
||||||
i.state = node_state_to_sink(info->state);
|
i.state = node_state_to_sink(info->state);
|
||||||
i.n_volume_steps = PA_VOLUME_NORM+1;
|
|
||||||
i.card = g->node_info.device_id;
|
i.card = g->node_info.device_id;
|
||||||
i.n_ports = 0;
|
i.n_ports = 0;
|
||||||
i.ports = NULL;
|
i.ports = NULL;
|
||||||
|
|
@ -872,9 +872,9 @@ static void source_callback(pa_context *c, struct global *g, struct source_data
|
||||||
i.flags = flags;
|
i.flags = flags;
|
||||||
i.proplist = pa_proplist_new_dict(info->props);
|
i.proplist = pa_proplist_new_dict(info->props);
|
||||||
i.configured_latency = 0;
|
i.configured_latency = 0;
|
||||||
i.base_volume = PA_VOLUME_NORM;
|
i.base_volume = g->node_info.base_volume * PA_VOLUME_NORM;
|
||||||
|
i.n_volume_steps = g->node_info.volume_step * (PA_VOLUME_NORM+1);
|
||||||
i.state = node_state_to_source(info->state);
|
i.state = node_state_to_source(info->state);
|
||||||
i.n_volume_steps = PA_VOLUME_NORM+1;
|
|
||||||
i.card = g->node_info.device_id;
|
i.card = g->node_info.device_id;
|
||||||
i.n_ports = 0;
|
i.n_ports = 0;
|
||||||
i.ports = NULL;
|
i.ports = NULL;
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,15 @@ enum spa_prop {
|
||||||
SPA_PROP_START_Audio = 0x10000, /**< audio related properties */
|
SPA_PROP_START_Audio = 0x10000, /**< audio related properties */
|
||||||
SPA_PROP_waveType,
|
SPA_PROP_waveType,
|
||||||
SPA_PROP_frequency,
|
SPA_PROP_frequency,
|
||||||
SPA_PROP_volume,
|
SPA_PROP_volume, /**< a volume (Float), 0.0 silence, 1.0 normal */
|
||||||
SPA_PROP_mute,
|
SPA_PROP_mute, /**< mute (Bool) */
|
||||||
SPA_PROP_patternType,
|
SPA_PROP_patternType,
|
||||||
SPA_PROP_ditherType,
|
SPA_PROP_ditherType,
|
||||||
SPA_PROP_truncate,
|
SPA_PROP_truncate,
|
||||||
SPA_PROP_channelVolumes,
|
SPA_PROP_channelVolumes, /**< a volume array, one volume per
|
||||||
|
* channel (Array of Float) */
|
||||||
|
SPA_PROP_volumeBase, /**< a volume base (Float) */
|
||||||
|
SPA_PROP_volumeStep, /**< a volume step (Float) */
|
||||||
|
|
||||||
SPA_PROP_START_Video = 0x20000, /**< video related properties */
|
SPA_PROP_START_Video = 0x20000, /**< video related properties */
|
||||||
SPA_PROP_brightness,
|
SPA_PROP_brightness,
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,8 @@ struct spa_pod_fd {
|
||||||
struct spa_pod_prop {
|
struct spa_pod_prop {
|
||||||
uint32_t key; /**< key of property, list of valid keys depends on the
|
uint32_t key; /**< key of property, list of valid keys depends on the
|
||||||
* object type */
|
* object type */
|
||||||
#define SPA_POD_PROP_FLAG_HARDWARE (1u<<0) /**< property for some sort of hardware parameter */
|
#define SPA_POD_PROP_FLAG_READONLY (1u<<0) /**< is read-only */
|
||||||
|
#define SPA_POD_PROP_FLAG_HARDWARE (1u<<1) /**< some sort of hardware parameter */
|
||||||
uint32_t flags; /**< flags for property */
|
uint32_t flags; /**< flags for property */
|
||||||
struct spa_pod value;
|
struct spa_pod value;
|
||||||
/* value follows */
|
/* value follows */
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ static void init_device(pa_card *impl, pa_alsa_device *dev, pa_alsa_direction_t
|
||||||
dev->device.format.format_mask = m->sample_spec.format;
|
dev->device.format.format_mask = m->sample_spec.format;
|
||||||
dev->device.format.rate_mask = m->sample_spec.rate;
|
dev->device.format.rate_mask = m->sample_spec.rate;
|
||||||
dev->device.format.channels = m->channel_map.channels;
|
dev->device.format.channels = m->channel_map.channels;
|
||||||
pa_cvolume_set(&dev->real_volume, m->channel_map.channels, PA_VOLUME_NORM);
|
pa_cvolume_reset(&dev->real_volume, m->channel_map.channels);
|
||||||
for (i = 0; i < m->channel_map.channels; i++)
|
for (i = 0; i < m->channel_map.channels; i++)
|
||||||
dev->device.format.map[i]= m->channel_map.map[i];
|
dev->device.format.map[i]= m->channel_map.map[i];
|
||||||
dev->direction = direction;
|
dev->direction = direction;
|
||||||
|
|
@ -813,6 +813,8 @@ static void mixer_volume_init(pa_alsa_device *dev) {
|
||||||
dev->read_volume = NULL;
|
dev->read_volume = NULL;
|
||||||
dev->set_volume = NULL;
|
dev->set_volume = NULL;
|
||||||
pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
|
pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
|
||||||
|
dev->base_volume = PA_VOLUME_NORM;
|
||||||
|
dev->n_volume_steps = PA_VOLUME_NORM+1;
|
||||||
dev->device.flags &= ~ACP_DEVICE_HW_VOLUME;
|
dev->device.flags &= ~ACP_DEVICE_HW_VOLUME;
|
||||||
} else {
|
} else {
|
||||||
dev->read_volume = read_volume;
|
dev->read_volume = read_volume;
|
||||||
|
|
@ -846,6 +848,8 @@ static void mixer_volume_init(pa_alsa_device *dev) {
|
||||||
pa_log_info("Using hardware volume control. Hardware dB scale %s.",
|
pa_log_info("Using hardware volume control. Hardware dB scale %s.",
|
||||||
dev->mixer_path->has_dB ? "supported" : "not supported");
|
dev->mixer_path->has_dB ? "supported" : "not supported");
|
||||||
}
|
}
|
||||||
|
dev->device.base_volume = (float)dev->base_volume / PA_VOLUME_NORM;
|
||||||
|
dev->device.volume_step = 1.0f / dev->n_volume_steps;
|
||||||
|
|
||||||
if (!dev->mixer_path || !dev->mixer_path->has_mute) {
|
if (!dev->mixer_path || !dev->mixer_path->has_mute) {
|
||||||
dev->read_mute = NULL;
|
dev->read_mute = NULL;
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,9 @@ struct acp_device {
|
||||||
char **device_strings;
|
char **device_strings;
|
||||||
struct acp_format format;
|
struct acp_format format;
|
||||||
|
|
||||||
|
float base_volume;
|
||||||
|
float volume_step;
|
||||||
|
|
||||||
struct acp_port **ports;
|
struct acp_port **ports;
|
||||||
uint32_t n_ports;
|
uint32_t n_ports;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -354,15 +354,23 @@ static struct spa_pod *build_route(struct spa_pod_builder *b, uint32_t id,
|
||||||
|
|
||||||
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_props, 0);
|
spa_pod_builder_prop(b, SPA_PARAM_ROUTE_props, 0);
|
||||||
spa_pod_builder_push_object(b, &f[1], SPA_TYPE_OBJECT_Props, id);
|
spa_pod_builder_push_object(b, &f[1], SPA_TYPE_OBJECT_Props, id);
|
||||||
|
|
||||||
spa_pod_builder_prop(b, SPA_PROP_mute,
|
spa_pod_builder_prop(b, SPA_PROP_mute,
|
||||||
SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HW_MUTE) ?
|
SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HW_MUTE) ?
|
||||||
SPA_POD_PROP_FLAG_HARDWARE : 0);
|
SPA_POD_PROP_FLAG_HARDWARE : 0);
|
||||||
spa_pod_builder_bool(b, mute);
|
spa_pod_builder_bool(b, mute);
|
||||||
|
|
||||||
spa_pod_builder_prop(b, SPA_PROP_channelVolumes,
|
spa_pod_builder_prop(b, SPA_PROP_channelVolumes,
|
||||||
SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HW_VOLUME) ?
|
SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HW_VOLUME) ?
|
||||||
SPA_POD_PROP_FLAG_HARDWARE : 0);
|
SPA_POD_PROP_FLAG_HARDWARE : 0);
|
||||||
spa_pod_builder_array(b, sizeof(float), SPA_TYPE_Float,
|
spa_pod_builder_array(b, sizeof(float), SPA_TYPE_Float,
|
||||||
channels, volumes);
|
channels, volumes);
|
||||||
|
|
||||||
|
spa_pod_builder_prop(b, SPA_PROP_volumeBase, SPA_POD_PROP_FLAG_READONLY);
|
||||||
|
spa_pod_builder_float(b, dev->base_volume);
|
||||||
|
spa_pod_builder_prop(b, SPA_PROP_volumeStep, SPA_POD_PROP_FLAG_READONLY);
|
||||||
|
spa_pod_builder_float(b, dev->volume_step);
|
||||||
|
|
||||||
spa_pod_builder_pop(b, &f[1]);
|
spa_pod_builder_pop(b, &f[1]);
|
||||||
}
|
}
|
||||||
return spa_pod_builder_pop(b, &f[0]);
|
return spa_pod_builder_pop(b, &f[0]);
|
||||||
|
|
@ -653,7 +661,7 @@ static void on_volume_changed(void *data, struct acp_device *dev)
|
||||||
static void on_mute_changed(void *data, struct acp_device *dev)
|
static void on_mute_changed(void *data, struct acp_device *dev)
|
||||||
{
|
{
|
||||||
struct impl *this = data;
|
struct impl *this = data;
|
||||||
spa_log_debug(this->log, "device %s mute changed", dev->name);
|
spa_log_info(this->log, "device %s mute changed", dev->name);
|
||||||
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
this->info.change_mask |= SPA_DEVICE_CHANGE_MASK_PARAMS;
|
||||||
this->params[3].flags ^= SPA_PARAM_INFO_SERIAL;
|
this->params[3].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
emit_info(this, false);
|
emit_info(this, false);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue