View Issue Details

IDProjectCategoryView StatusLast Update
0002216ardourfeaturespublic2015-09-18 15:11
Reportercolinf Assigned Topaul  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionfixed 
Product VersionSVN/2.0-ongoing 
Summary0002216: Don't always reconnect unknown connections to "in 1"/"out 1"
DescriptionIf I open a session that had inputs (or outputs) connected to channel 3 or above of my 8-input sound card whilst using my laptop's on-board (stereo) sound, all those inputs end up connected to "in 1" (or "out 1"). I thought it'd be nice if at least the even-numbered inputs ended up connected to "in 2" (or "out 2") instead.
Additional InformationI hacked up a patch that tries to do this in a way that doesn't assume anything about the number of ins or outs, except that the number of them is probably a power of 2.

I've not really been able to test it very thoroughly, but I'll post it here anyway.

It's supposed to re-connect unconnectable connections to the corresponding port whose number is below the next power of two down. For example: if "in 8" can't be connected, it will then try "in 4", "in 2" and finally "in 1". Likewise, 7 => 3 => 1, 6 => 2 => 1, 5 => 1.
TagsNo tags attached.

Activities

2008-04-23 14:09

 

unknown-connections.patch (5,380 bytes)   
Index: libs/ardour/io.cc
===================================================================
--- libs/ardour/io.cc	(revision 3279)
+++ libs/ardour/io.cc	(working copy)
@@ -1782,6 +1782,67 @@
 	return ret;
 }
 
+Connection *
+IO::find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name) {
+
+	Connection* c = _session.connection_by_name (desired_name);
+
+	if (!c) {
+	int connection_number, i, n, p, mask;
+	string possible_name;
+
+		error << string_compose(_("Unknown connection \"%1\" listed for %2 of %3"), desired_name, connection_type_name, _name)
+		      << endmsg;
+
+		// find numeric suffix of desired name
+		connection_number = 0;
+		p = 1;
+		i = desired_name.length();
+		while (n = desired_name[--i], isdigit(n) && i) {
+			connection_number += (n-'0') * p;
+			p *= 10;
+		}
+		
+
+		// make 0-based
+		connection_number--;
+		// cerr << "desired_name = " << desired_name << ", connection_number = " << connection_number << endl;
+
+		// find highest set bit
+		mask = 1;
+		while ((mask <= connection_number) && (mask <<= 1)) {
+		}
+		
+		// "wrap" connection number into largest possible power of 2 
+		// that works...
+		while (mask && !c) {
+			if (connection_number & mask) {
+				connection_number &= ~mask;
+				
+				stringstream s;
+				s << connection_number + 1;
+				possible_name = default_name + " " + s.str();
+				// cerr << "trying " << possible_name << endl;
+					
+				c = _session.connection_by_name (possible_name);
+			}
+			mask >>= 1;
+		}
+		if (c) {
+			info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+			     << endmsg;
+		} else {
+			error << string_compose(_("No %1 connections available as a replacement"), connection_type_name)
+			      << endmsg;
+		}
+
+	}
+
+	return c;
+
+
+}
+
 int
 IO::create_ports (const XMLNode& node)
 {
@@ -1791,19 +1852,10 @@
 
 	if ((prop = node.property ("input-connection")) != 0) {
 
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_inputs = c->nports();
@@ -1814,19 +1866,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("out"), _("output"));
 
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_outputs = c->nports ();
@@ -1857,19 +1900,10 @@
 	const XMLProperty* prop;
 
 	if ((prop = node.property ("input-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			} else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_input_connection (*c, this);
@@ -1882,19 +1916,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("out"), _("output"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_output_connection (*c, this);
Index: libs/ardour/ardour/io.h
===================================================================
--- libs/ardour/ardour/io.h	(revision 3279)
+++ libs/ardour/ardour/io.h	(working copy)
@@ -395,6 +395,7 @@
 
 	int create_ports (const XMLNode&);
 	int make_connections (const XMLNode&);
+	Connection *find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name);
 
 	void setup_peak_meters ();
 	void meter ();
unknown-connections.patch (5,380 bytes)   

2008-04-24 16:16

 

unknown-connections-stereo.patch (5,874 bytes)   
Index: libs/ardour/io.cc
===================================================================
--- libs/ardour/io.cc	(revision 3279)
+++ libs/ardour/io.cc	(working copy)
@@ -1782,6 +1782,83 @@
 	return ret;
 }
 
+Connection *
+IO::find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name) {
+
+	Connection* c = _session.connection_by_name (desired_name);
+
+	if (!c) {
+	int connection_number, i, n, p, mask;
+	string possible_name;
+	bool stereo = false;
+
+		error << string_compose(_("Unknown connection \"%1\" listed for %2 of %3"), desired_name, connection_type_name, _name)
+		      << endmsg;
+
+		// find numeric suffix of desired name
+		connection_number = 0;
+		p = 1;
+		i = desired_name.length();
+		while (n = desired_name[--i], isdigit(n) && i) {
+			connection_number += (n-'0') * p;
+			p *= 10;
+		}
+		if (i && n == '+') {
+			// see if it's a stereo connection e.g. "in 3+4"
+			int left_connection_number = 0;
+			p = 1;
+			info << "assuming port " << desired_name << " is stereo" << endmsg;
+			while (n = desired_name[--i], isdigit(n) && i) {
+				left_connection_number += (n-'0') * p;
+				p *= 10;
+			}
+			if (left_connection_number > 0 && left_connection_number + 1 == connection_number) {
+				connection_number--;
+				stereo = true;
+			}
+		}
+
+		// make 0-based
+		connection_number--;
+		// cerr << "desired_name = " << desired_name << ", connection_number = " << connection_number << endl;
+
+		// find highest set bit
+		mask = 1;
+		while ((mask <= connection_number) && (mask <<= 1)) {
+		}
+		
+		// "wrap" connection number into largest possible power of 2 
+		// that works...
+		while (mask && !c) {
+			if (connection_number & mask) {
+				connection_number &= ~mask;
+				
+				stringstream s;
+				s << default_name << " " << connection_number + 1;
+				if (stereo) {
+					s << "+" << connection_number + 2;
+				}
+				
+				possible_name = s.str();
+				c = _session.connection_by_name (possible_name);
+			}
+			mask >>= 1;
+		}
+		if (c) {
+			info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+			     << endmsg;
+		} else {
+			error << string_compose(_("No %1 connections available as a replacement"), connection_type_name)
+			      << endmsg;
+		}
+
+	}
+
+	return c;
+
+
+}
+
 int
 IO::create_ports (const XMLNode& node)
 {
@@ -1791,19 +1868,10 @@
 
 	if ((prop = node.property ("input-connection")) != 0) {
 
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_inputs = c->nports();
@@ -1814,19 +1882,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("out"), _("output"));
 
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_outputs = c->nports ();
@@ -1857,19 +1916,10 @@
 	const XMLProperty* prop;
 
 	if ((prop = node.property ("input-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			} else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_input_connection (*c, this);
@@ -1882,19 +1932,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("out"), _("output"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_output_connection (*c, this);
Index: libs/ardour/ardour/io.h
===================================================================
--- libs/ardour/ardour/io.h	(revision 3279)
+++ libs/ardour/ardour/io.h	(working copy)
@@ -395,6 +395,7 @@
 
 	int create_ports (const XMLNode&);
 	int make_connections (const XMLNode&);
+	Connection *find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name);
 
 	void setup_peak_meters ();
 	void meter ();

colinf

2008-04-24 16:17

updater   ~0004899

And here's a version that tries to reconnect e.g. "in 3+4" to "in 1+2" as well.

paul

2008-04-27 21:19

administrator   ~0004910

patch applied to 2.0-ongoing last week. thanks!

2008-05-01 19:04

 

unknown-connections-stereo-3302.patch (6,214 bytes)   
Index: libs/ardour/io.cc
===================================================================
--- libs/ardour/io.cc	(revision 3302)
+++ libs/ardour/io.cc	(working copy)
@@ -1782,6 +1782,91 @@
 	return ret;
 }
 
+Connection *
+IO::find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name) {
+static const string digits = "0123456789";
+
+	Connection* c = _session.connection_by_name (desired_name);
+
+	if (!c) {
+	int connection_number, mask;
+	string possible_name;
+	bool stereo = false;
+	size_t last_non_digit_pos;
+
+		error << string_compose(_("Unknown connection \"%1\" listed for %2 of %3"), desired_name, connection_type_name, _name)
+		      << endmsg;
+
+		// find numeric suffix of desired name
+		connection_number = 0;
+		
+		last_non_digit_pos = desired_name.find_last_not_of(digits);
+		if (last_non_digit_pos != string::npos) {
+			stringstream s;
+			s << desired_name.substr(last_non_digit_pos);
+			s >> connection_number;
+		    
+		}
+	
+		// see if it's a stereo connection e.g. "in 3+4"
+		if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
+			int left_connection_number = 0;
+
+			size_t left_last_non_digit_pos;
+			left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
+			if (left_last_non_digit_pos != string::npos) {
+				stringstream s;
+				s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
+				s >> left_connection_number;
+
+				if (left_connection_number > 0 && left_connection_number + 1 == connection_number) {
+					connection_number--;
+					stereo = true;
+				}
+			}
+		}
+
+		// make 0-based
+		if (connection_number)
+			connection_number--;
+
+		cerr << "desired_name = " << desired_name << ", connection_number = " << connection_number << endl;
+		// find highest set bit
+		mask = 1;
+		while ((mask <= connection_number) && (mask <<= 1)) {
+		}
+		
+		// "wrap" connection number into largest possible power of 2 
+		// that works...
+		while (mask && !c) {
+			if (connection_number & mask) {
+				connection_number &= ~mask;
+				
+				stringstream s;
+				s << default_name << " " << connection_number + 1;
+				if (stereo) {
+					s << "+" << connection_number + 2;
+				}
+				
+				possible_name = s.str();
+				c = _session.connection_by_name (possible_name);
+			}
+			mask >>= 1;
+		}
+		if (c) {
+			info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), desired_name, possible_name)
+			     << endmsg;
+		} else {
+			error << string_compose(_("No %1 connections available as a replacement"), connection_type_name)
+			      << endmsg;
+		}
+
+	}
+
+	return c;
+
+}
+
 int
 IO::create_ports (const XMLNode& node)
 {
@@ -1791,19 +1876,10 @@
 
 	if ((prop = node.property ("input-connection")) != 0) {
 
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_inputs = c->nports();
@@ -1814,19 +1890,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection(prop->value(), _("out"), _("output"));
 
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		num_outputs = c->nports ();
@@ -1857,19 +1924,10 @@
 	const XMLProperty* prop;
 
 	if ((prop = node.property ("input-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("in"), _("input"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("in 1"))) == 0) {
-				error << _("No input connections available as a replacement")
-				      << endmsg;
-				return -1;
-			} else {
-				info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_input_connection (*c, this);
@@ -1882,19 +1940,10 @@
 	}
 	
 	if ((prop = node.property ("output-connection")) != 0) {
-		Connection* c = _session.connection_by_name (prop->value());
+		Connection* c = find_possible_connection (prop->value(), _("out"), _("output"));
 		
 		if (c == 0) {
-			error << string_compose(_("Unknown connection \"%1\" listed for output of %2"), prop->value(), _name) << endmsg;
-
-			if ((c = _session.connection_by_name (_("out 1"))) == 0) {
-				error << _("No output connections available as a replacement")
-				      << endmsg;
-				return -1;
-			}  else {
-				info << string_compose (_("Connection %1 was not available - \"out 1\" used instead"), prop->value())
-				     << endmsg;
-			}
+			return -1;
 		} 
 
 		use_output_connection (*c, this);
Index: libs/ardour/ardour/io.h
===================================================================
--- libs/ardour/ardour/io.h	(revision 3302)
+++ libs/ardour/ardour/io.h	(working copy)
@@ -395,6 +395,7 @@
 
 	int create_ports (const XMLNode&);
 	int make_connections (const XMLNode&);
+	Connection *find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name);
 
 	void setup_peak_meters ();
 	void meter ();

colinf

2008-05-01 19:06

updater   ~0004913

Last edited: 2008-05-01 19:15

Here's an improved version (unknown-connections-stereo-3302.patch), with better-named variables and using more of the good things that std::string gives us.

2008-05-14 14:54

 

unknown-connections-stereo-3347.patch (2,685 bytes)   
Index: libs/ardour/io.cc
===================================================================
--- libs/ardour/io.cc	(revision 3347)
+++ libs/ardour/io.cc	(working copy)
@@ -1784,44 +1784,53 @@
 
 Connection *
 IO::find_possible_connection(const string &desired_name, const string &default_name, const string &connection_type_name) {
+static const string digits = "0123456789";
 
 	Connection* c = _session.connection_by_name (desired_name);
 
 	if (!c) {
-	int connection_number, i, n, p, mask;
+	int connection_number, mask;
 	string possible_name;
 	bool stereo = false;
+	size_t last_non_digit_pos;
 
 		error << string_compose(_("Unknown connection \"%1\" listed for %2 of %3"), desired_name, connection_type_name, _name)
 		      << endmsg;
 
 		// find numeric suffix of desired name
 		connection_number = 0;
-		p = 1;
-		i = desired_name.length();
-		while (n = desired_name[--i], isdigit(n) && i) {
-			connection_number += (n-'0') * p;
-			p *= 10;
+		
+		last_non_digit_pos = desired_name.find_last_not_of(digits);
+		if (last_non_digit_pos != string::npos) {
+			stringstream s;
+			s << desired_name.substr(last_non_digit_pos);
+			s >> connection_number;
+		    
 		}
-		if (i && n == '+') {
-			// see if it's a stereo connection e.g. "in 3+4"
+	
+		// see if it's a stereo connection e.g. "in 3+4"
+		if (last_non_digit_pos > 1 && desired_name[last_non_digit_pos] == '+') {
 			int left_connection_number = 0;
-			p = 1;
-			info << "assuming port " << desired_name << " is stereo" << endmsg;
-			while (n = desired_name[--i], isdigit(n) && i) {
-				left_connection_number += (n-'0') * p;
-				p *= 10;
+
+			size_t left_last_non_digit_pos;
+			left_last_non_digit_pos = desired_name.find_last_not_of(digits, last_non_digit_pos-1);
+			if (left_last_non_digit_pos != string::npos) {
+				stringstream s;
+				s << desired_name.substr(left_last_non_digit_pos, last_non_digit_pos-1);
+				s >> left_connection_number;
+
+				if (left_connection_number > 0 && left_connection_number + 1 == connection_number) {
+					connection_number--;
+					stereo = true;
+				}
 			}
-			if (left_connection_number > 0 && left_connection_number + 1 == connection_number) {
-				connection_number--;
-				stereo = true;
-			}
 		}
 
 		// make 0-based
-		connection_number--;
-		// cerr << "desired_name = " << desired_name << ", connection_number = " << connection_number << endl;
+		if (connection_number)
+			connection_number--;
 
+		cerr << "desired_name = " << desired_name << ", connection_number = " << connection_number << endl;
 		// find highest set bit
 		mask = 1;
 		while ((mask <= connection_number) && (mask <<= 1)) {
@@ -1856,7 +1865,6 @@
 
 	return c;
 
-
 }
 
 int

colinf

2008-05-14 15:01

updater   ~0004926

Looks like the older version got merged: attached a patch (unknown-connections-stereo-3347.patch, against svn 3347) to update that to the newer version.

paul

2008-05-14 23:14

administrator   ~0004927

final patch applied & committed.

colinf

2015-09-18 15:11

updater   ~0017251

Closing old issues: these have long since been fixed.

Issue History

Date Modified Username Field Change
2008-04-23 14:09 colinf New Issue
2008-04-23 14:09 colinf File Added: unknown-connections.patch
2008-04-24 16:16 colinf File Added: unknown-connections-stereo.patch
2008-04-24 16:17 colinf Note Added: 0004899
2008-04-27 21:19 paul Note Added: 0004910
2008-05-01 19:04 colinf File Added: unknown-connections-stereo-3302.patch
2008-05-01 19:06 colinf Note Added: 0004913
2008-05-01 19:15 colinf Note Edited: 0004913
2008-05-14 14:54 colinf File Added: unknown-connections-stereo-3347.patch
2008-05-14 15:01 colinf Note Added: 0004926
2008-05-14 23:14 paul Status new => resolved
2008-05-14 23:14 paul Resolution open => fixed
2008-05-14 23:14 paul Assigned To => paul
2008-05-14 23:14 paul Note Added: 0004927
2015-09-18 15:11 colinf Note Added: 0017251
2015-09-18 15:11 colinf Status resolved => closed