mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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,10 +2337,26 @@ static int port_set_latency(void *object,
 | 
			
		|||
			info.min_rate, info.max_rate,
 | 
			
		||||
			info.min_ns, info.max_ns);
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
			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]);
 | 
			
		||||
| 
						 | 
				
			
			@ -2359,7 +2371,8 @@ static int port_set_latency(void *object,
 | 
			
		|||
 | 
			
		||||
		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;
 | 
			
		||||
| 
						 | 
				
			
			@ -2368,6 +2381,7 @@ static int port_set_latency(void *object,
 | 
			
		|||
				emit_port_info(this, oport, false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (emit) {
 | 
			
		||||
		port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
		port->params[IDX_Latency].user++;
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -389,6 +389,7 @@ context.objects = [
 | 
			
		|||
    #        node.description = "Microphone"
 | 
			
		||||
    #        media.class      = "Audio/Source/Virtual"
 | 
			
		||||
    #        audio.position   = "FL,FR"
 | 
			
		||||
    #        monitor.passthrough = true
 | 
			
		||||
    #        adapter.auto-port-config = {
 | 
			
		||||
    #            mode = dsp
 | 
			
		||||
    #            monitor = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -259,6 +259,7 @@ context.objects = [
 | 
			
		|||
    #        node.description = "Microphone"
 | 
			
		||||
    #        media.class      = "Audio/Source/Virtual"
 | 
			
		||||
    #        audio.position   = "FL,FR"
 | 
			
		||||
    #        monitor.passthrough = true
 | 
			
		||||
    #    }
 | 
			
		||||
    #}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -196,6 +196,8 @@ static int module_null_sink_prepare(struct module * const module)
 | 
			
		|||
 | 
			
		||||
	if (pw_properties_get(props, "monitor.channel-volumes") == NULL)
 | 
			
		||||
		pw_properties_set(props, "monitor.channel-volumes", "true");
 | 
			
		||||
	if (pw_properties_get(props, "monitor.passthrough") == NULL)
 | 
			
		||||
		pw_properties_set(props, "monitor.passthrough", "true");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue