mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
audioconvert: add volume and mute property
Expose volume and mute property in channelmix and use this in audioconvert.
This commit is contained in:
parent
842abad9e1
commit
f2e03077a8
2 changed files with 145 additions and 30 deletions
|
|
@ -34,20 +34,6 @@
|
||||||
|
|
||||||
#define NAME "audioconvert"
|
#define NAME "audioconvert"
|
||||||
|
|
||||||
#define PROP_DEFAULT_TRUNCATE false
|
|
||||||
#define PROP_DEFAULT_DITHER 0
|
|
||||||
|
|
||||||
struct props {
|
|
||||||
bool truncate;
|
|
||||||
uint32_t dither;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void props_reset(struct props *props)
|
|
||||||
{
|
|
||||||
props->truncate = PROP_DEFAULT_TRUNCATE;
|
|
||||||
props->dither = PROP_DEFAULT_DITHER;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct buffer {
|
struct buffer {
|
||||||
struct spa_list link;
|
struct spa_list link;
|
||||||
#define BUFFER_FLAG_OUT (1 << 0)
|
#define BUFFER_FLAG_OUT (1 << 0)
|
||||||
|
|
@ -75,8 +61,6 @@ struct impl {
|
||||||
|
|
||||||
struct spa_log *log;
|
struct spa_log *log;
|
||||||
|
|
||||||
struct props props;
|
|
||||||
|
|
||||||
const struct spa_node_callbacks *callbacks;
|
const struct spa_node_callbacks *callbacks;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
|
|
||||||
|
|
@ -402,10 +386,60 @@ static int setup_buffers(struct impl *this, enum spa_direction direction)
|
||||||
static int impl_node_enum_params(struct spa_node *node,
|
static int impl_node_enum_params(struct spa_node *node,
|
||||||
uint32_t id, uint32_t *index,
|
uint32_t id, uint32_t *index,
|
||||||
const struct spa_pod *filter,
|
const struct spa_pod *filter,
|
||||||
struct spa_pod **param,
|
struct spa_pod **result,
|
||||||
struct spa_pod_builder *builder)
|
struct spa_pod_builder *builder)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
struct impl *this;
|
||||||
|
struct spa_pod *param;
|
||||||
|
struct spa_pod_builder b = { 0 };
|
||||||
|
uint8_t buffer[1024];
|
||||||
|
|
||||||
|
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||||
|
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||||
|
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||||
|
|
||||||
|
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||||
|
|
||||||
|
next:
|
||||||
|
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case SPA_PARAM_Profile:
|
||||||
|
switch (*index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_ParamProfile, id,
|
||||||
|
SPA_PARAM_PROFILE_direction, &SPA_POD_Id(SPA_DIRECTION_INPUT),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_ParamProfile, id,
|
||||||
|
SPA_PARAM_PROFILE_direction, &SPA_POD_Id(SPA_DIRECTION_OUTPUT),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPA_PARAM_Props:
|
||||||
|
switch (*index) {
|
||||||
|
case 0:
|
||||||
|
return spa_node_enum_params(this->channelmix, id, index, filter, result, builder);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
(*index)++;
|
||||||
|
|
||||||
|
if (spa_pod_filter(builder, result, param, filter) < 0)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
|
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
|
||||||
|
|
@ -431,8 +465,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case SPA_DIRECTION_INPUT:
|
case SPA_DIRECTION_INPUT:
|
||||||
case SPA_DIRECTION_OUTPUT:
|
case SPA_DIRECTION_OUTPUT:
|
||||||
res = spa_node_set_param(this->fmt[direction],
|
res = spa_node_set_param(this->fmt[direction], id, flags, param);
|
||||||
id, flags, param);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
|
|
@ -440,6 +473,11 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPA_PARAM_Props:
|
||||||
|
{
|
||||||
|
res = spa_node_set_param(this->channelmix, id, flags, param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = -ENOTSUP;
|
res = -ENOTSUP;
|
||||||
break;
|
break;
|
||||||
|
|
@ -464,9 +502,11 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
|
||||||
setup_buffers(this, SPA_DIRECTION_INPUT);
|
setup_buffers(this, SPA_DIRECTION_INPUT);
|
||||||
this->started = true;
|
this->started = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPA_NODE_COMMAND_Pause:
|
case SPA_NODE_COMMAND_Pause:
|
||||||
this->started = false;
|
this->started = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
@ -942,8 +982,6 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_OUTPUT], SPA_TYPE_INTERFACE_Node, &iface);
|
spa_handle_get_interface(this->hnd_fmt[SPA_DIRECTION_OUTPUT], SPA_TYPE_INTERFACE_Node, &iface);
|
||||||
this->fmt[SPA_DIRECTION_OUTPUT] = iface;
|
this->fmt[SPA_DIRECTION_OUTPUT] = iface;
|
||||||
|
|
||||||
props_reset(&this->props);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -411,10 +411,91 @@ static int setup_convert(struct impl *this,
|
||||||
static int impl_node_enum_params(struct spa_node *node,
|
static int impl_node_enum_params(struct spa_node *node,
|
||||||
uint32_t id, uint32_t *index,
|
uint32_t id, uint32_t *index,
|
||||||
const struct spa_pod *filter,
|
const struct spa_pod *filter,
|
||||||
struct spa_pod **param,
|
struct spa_pod **result,
|
||||||
struct spa_pod_builder *builder)
|
struct spa_pod_builder *builder)
|
||||||
{
|
{
|
||||||
return -ENOTSUP;
|
struct impl *this;
|
||||||
|
struct spa_pod *param;
|
||||||
|
struct spa_pod_builder b = { 0 };
|
||||||
|
uint8_t buffer[1024];
|
||||||
|
|
||||||
|
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||||
|
spa_return_val_if_fail(index != NULL, -EINVAL);
|
||||||
|
spa_return_val_if_fail(builder != NULL, -EINVAL);
|
||||||
|
|
||||||
|
this = SPA_CONTAINER_OF(node, struct impl, node);
|
||||||
|
|
||||||
|
next:
|
||||||
|
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case SPA_PARAM_List:
|
||||||
|
{
|
||||||
|
uint32_t list[] = { SPA_PARAM_PropInfo,
|
||||||
|
SPA_PARAM_Props };
|
||||||
|
|
||||||
|
if (*index < SPA_N_ELEMENTS(list))
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_ParamList, id,
|
||||||
|
SPA_PARAM_LIST_id, &SPA_POD_Id(list[*index]),
|
||||||
|
0);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_PARAM_PropInfo:
|
||||||
|
{
|
||||||
|
struct props *p = &this->props;
|
||||||
|
|
||||||
|
switch (*index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, id,
|
||||||
|
SPA_PROP_INFO_id, &SPA_POD_Id(SPA_PROP_volume),
|
||||||
|
SPA_PROP_INFO_name, &SPA_POD_Stringc("Volume"),
|
||||||
|
SPA_PROP_INFO_type, &SPA_POD_CHOICE_RANGE_Float(p->volume, 0.0, 10.0),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_PropInfo, id,
|
||||||
|
SPA_PROP_INFO_id, &SPA_POD_Id(SPA_PROP_mute),
|
||||||
|
SPA_PROP_INFO_name, &SPA_POD_Stringc("Mute"),
|
||||||
|
SPA_PROP_INFO_type, &SPA_POD_Bool(p->mute),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_PARAM_Props:
|
||||||
|
{
|
||||||
|
struct props *p = &this->props;
|
||||||
|
|
||||||
|
switch (*index) {
|
||||||
|
case 0:
|
||||||
|
param = spa_pod_builder_object(&b,
|
||||||
|
SPA_TYPE_OBJECT_Props, id,
|
||||||
|
SPA_PROP_volume, &SPA_POD_Float(p->volume),
|
||||||
|
SPA_PROP_mute, &SPA_POD_Bool(p->mute),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*index)++;
|
||||||
|
|
||||||
|
if (spa_pod_filter(builder, result, param, filter) < 0)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_props(struct impl *this, const struct spa_pod *param)
|
static int apply_props(struct impl *this, const struct spa_pod *param)
|
||||||
|
|
@ -424,16 +505,12 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
|
||||||
struct props *p = &this->props;
|
struct props *p = &this->props;
|
||||||
|
|
||||||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||||
float volume;
|
|
||||||
bool mute;
|
|
||||||
switch (prop->key) {
|
switch (prop->key) {
|
||||||
case SPA_PROP_volume:
|
case SPA_PROP_volume:
|
||||||
volume = SPA_POD_VALUE(struct spa_pod_float, &prop->value);
|
p->volume = SPA_POD_VALUE(struct spa_pod_float, &prop->value);
|
||||||
p->volume = volume;
|
|
||||||
break;
|
break;
|
||||||
case SPA_PROP_mute:
|
case SPA_PROP_mute:
|
||||||
mute = SPA_POD_VALUE(struct spa_pod_bool, &prop->value);
|
p->mute = SPA_POD_VALUE(struct spa_pod_bool, &prop->value);
|
||||||
p->mute = mute;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue