mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
audioconvert: add monitor.passthrough option
Add a monitor.passthrough option. This will pass all latency information directly between the port and its monitor ports. This is interesting when the adapter (and audioconvert) is used with a null-audio-sink that simply forwards the data to a real sink/souce. In that case, we want the sink/source latency to be passed unmodified. Set the monitor.passthrough on the pulseaudio null-sink because a passthrough virtual sink is the most likely use case for this. Add some monitor.passthrough default config where it makes sense. Fixes #3888
This commit is contained in:
parent
10830ab9f8
commit
ea524b158c
4 changed files with 46 additions and 26 deletions
|
|
@ -238,6 +238,7 @@ struct impl {
|
|||
unsigned int drained:1;
|
||||
unsigned int rate_adjust:1;
|
||||
unsigned int port_ignore_latency:1;
|
||||
unsigned int monitor_passthrough:1;
|
||||
|
||||
uint32_t scratch_size;
|
||||
uint32_t scratch_ports;
|
||||
|
|
@ -2250,8 +2251,6 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
case 0: case 1:
|
||||
{
|
||||
uint32_t idx = result.index;
|
||||
if (port->is_monitor)
|
||||
idx = idx ^ 1;
|
||||
param = spa_latency_build(&b, id, &port->latency[idx]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -2317,9 +2316,6 @@ static int port_set_latency(void *object,
|
|||
this, direction, port_id, latency);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
if (port->is_monitor)
|
||||
return 0;
|
||||
|
||||
if (latency == NULL) {
|
||||
info = SPA_LATENCY_INFO(other);
|
||||
have_latency = false;
|
||||
|
|
@ -2341,32 +2337,50 @@ static int port_set_latency(void *object,
|
|||
info.min_rate, info.max_rate,
|
||||
info.min_ns, info.max_ns);
|
||||
|
||||
spa_latency_info_combine_start(&info, other);
|
||||
for (i = 0; i < this->dir[direction].n_ports; i++) {
|
||||
oport = GET_PORT(this, direction, i);
|
||||
if (oport->is_monitor || !oport->have_latency)
|
||||
continue;
|
||||
spa_log_debug(this->log, "%p: combine %d", this, i);
|
||||
spa_latency_info_combine(&info, &oport->latency[other]);
|
||||
}
|
||||
spa_latency_info_combine_finish(&info);
|
||||
if (this->monitor_passthrough) {
|
||||
if (port->is_monitor)
|
||||
oport = GET_PORT(this, other, port_id-1);
|
||||
else if (this->monitor && direction == SPA_DIRECTION_INPUT)
|
||||
oport = GET_PORT(this, other, port_id+1);
|
||||
else
|
||||
return 0;
|
||||
|
||||
spa_log_debug(this->log, "%p: combined %s latency %f-%f %d-%d %"PRIu64"-%"PRIu64, this,
|
||||
info.direction == SPA_DIRECTION_INPUT ? "input" : "output",
|
||||
info.min_quantum, info.max_quantum,
|
||||
info.min_rate, info.max_rate,
|
||||
info.min_ns, info.max_ns);
|
||||
|
||||
for (i = 0; i < this->dir[other].n_ports; i++) {
|
||||
oport = GET_PORT(this, other, i);
|
||||
|
||||
spa_log_debug(this->log, "%p: change %d", this, i);
|
||||
if (spa_latency_info_compare(&info, &oport->latency[other]) != 0) {
|
||||
if (oport != NULL &&
|
||||
spa_latency_info_compare(&info, &oport->latency[other]) != 0) {
|
||||
oport->latency[other] = info;
|
||||
oport->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
oport->params[IDX_Latency].user++;
|
||||
emit_port_info(this, oport, false);
|
||||
}
|
||||
} else {
|
||||
spa_latency_info_combine_start(&info, other);
|
||||
for (i = 0; i < this->dir[direction].n_ports; i++) {
|
||||
oport = GET_PORT(this, direction, i);
|
||||
if ((oport->is_monitor) || !oport->have_latency)
|
||||
continue;
|
||||
spa_log_debug(this->log, "%p: combine %d", this, i);
|
||||
spa_latency_info_combine(&info, &oport->latency[other]);
|
||||
}
|
||||
spa_latency_info_combine_finish(&info);
|
||||
|
||||
spa_log_debug(this->log, "%p: combined %s latency %f-%f %d-%d %"PRIu64"-%"PRIu64, this,
|
||||
info.direction == SPA_DIRECTION_INPUT ? "input" : "output",
|
||||
info.min_quantum, info.max_quantum,
|
||||
info.min_rate, info.max_rate,
|
||||
info.min_ns, info.max_ns);
|
||||
|
||||
for (i = 0; i < this->dir[other].n_ports; i++) {
|
||||
oport = GET_PORT(this, other, i);
|
||||
if (oport->is_monitor)
|
||||
continue;
|
||||
spa_log_debug(this->log, "%p: change %d", this, i);
|
||||
if (spa_latency_info_compare(&info, &oport->latency[other]) != 0) {
|
||||
oport->latency[other] = info;
|
||||
oport->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
oport->params[IDX_Latency].user++;
|
||||
emit_port_info(this, oport, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (emit) {
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
|
|
@ -2391,7 +2405,7 @@ static int port_set_tag(void *object,
|
|||
this, direction, port_id, tag);
|
||||
|
||||
port = GET_PORT(this, direction, port_id);
|
||||
if (port->is_monitor)
|
||||
if (port->is_monitor && !this->monitor_passthrough)
|
||||
return 0;
|
||||
|
||||
if (tag != NULL) {
|
||||
|
|
@ -3448,6 +3462,8 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
}
|
||||
else if (spa_streq(k, SPA_KEY_PORT_IGNORE_LATENCY))
|
||||
this->port_ignore_latency = spa_atob(s);
|
||||
else if (spa_streq(k, "monitor.passthrough"))
|
||||
this->monitor_passthrough = spa_atob(s);
|
||||
else
|
||||
audioconvert_set_param(this, k, s);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue