channelmix: use the right channelmap

For merger setup (consuming a source) we want to expose the channelmap
of the remixed signal (to the application/sink).
For splitter setup (providing data) we want to expose the channelmap
of the original source (before remixing to sink).

Hide the merge channel props because they contain the channelmap before
mising and we want to expose the remixed signal in merger mode.

This fixes some weird volume issues when an input stream is linked
to a source and is remixing, like when a stereo stream is captured
from a mono source.
This commit is contained in:
Wim Taymans 2022-02-22 18:20:07 +01:00
parent 0b7da17083
commit ac25d126de
2 changed files with 13 additions and 2 deletions

View file

@ -145,6 +145,7 @@ struct impl {
struct spa_cpu *cpu; struct spa_cpu *cpu;
uint32_t quantum_limit; uint32_t quantum_limit;
enum spa_direction direction;
struct spa_io_position *io_position; struct spa_io_position *io_position;
struct spa_hook_list hooks; struct spa_hook_list hooks;
@ -360,7 +361,7 @@ static int setup_convert(struct impl *this,
if ((res = channelmix_init(&this->mix)) < 0) if ((res = channelmix_init(&this->mix)) < 0)
return res; return res;
remap_volumes(this, src_info); remap_volumes(this, this->direction == SPA_DIRECTION_INPUT ? src_info : dst_info);
set_volume(this); set_volume(this);
emit_props_changed(this); emit_props_changed(this);
@ -714,7 +715,7 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
} }
} }
if (changed) { if (changed) {
struct port *port = GET_IN_PORT(this, 0); struct port *port = GET_PORT(this, this->direction, 0);
if (have_soft_volume) if (have_soft_volume)
p->have_soft_volume = true; p->have_soft_volume = true;
else if (have_channel_volume) else if (have_channel_volume)
@ -1579,6 +1580,12 @@ impl_init(const struct spa_handle_factory *factory,
this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s)); this->props.n_channels = parse_position(this->props.channel_map, s, strlen(s));
else if (spa_streq(k, "clock.quantum-limit")) else if (spa_streq(k, "clock.quantum-limit"))
spa_atou32(s, &this->quantum_limit, 0); spa_atou32(s, &this->quantum_limit, 0);
else if (spa_streq(k, "factory.mode")) {
if (spa_streq(s, "merge"))
this->direction = SPA_DIRECTION_OUTPUT;
else
this->direction = SPA_DIRECTION_INPUT;
}
else else
channelmix_set_param(this, k, s); channelmix_set_param(this, k, s);

View file

@ -386,10 +386,13 @@ static int impl_node_enum_params(void *object, int seq,
case SPA_PARAM_Props: case SPA_PARAM_Props:
{ {
#if 0
struct props *p = &this->props; struct props *p = &this->props;
struct spa_pod_frame f[2]; struct spa_pod_frame f[2];
#endif
switch (result.index) { switch (result.index) {
#if 0
case 0: case 0:
spa_pod_builder_push_object(&b, &f[0], spa_pod_builder_push_object(&b, &f[0],
SPA_TYPE_OBJECT_Props, id); SPA_TYPE_OBJECT_Props, id);
@ -422,6 +425,7 @@ static int impl_node_enum_params(void *object, int seq,
spa_pod_builder_pop(&b, &f[1]); spa_pod_builder_pop(&b, &f[1]);
param = spa_pod_builder_pop(&b, &f[0]); param = spa_pod_builder_pop(&b, &f[0]);
break; break;
#endif
default: default:
return 0; return 0;
} }