View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

SCJConnection

Home   How To   Code Pool   Public Library   Theory   Events
A Class to manage JACK connections from SuperCollider.
This is just an encapsulation of calls to the jack tools jack_connect, jack_disconnect and jack_lsp. Normally these come with JACK.

This class can be used in two ways:

1. You can make connections, using the class methods .connect and .disconnect

2. You can make an instance, which defines a connection, which can then be (dis)connected using the instance methods .connect and .disconnect

SCJConnection.connect( srcchan, deschan, src, des )

Connects srchan with deschan.
srcchan and deschan are arrays with source and destination channels. Their interpretation depends on the src and des arguments. If these are both nil, the numbers in the array are interpreted as indices in the class variable "allports" (see below). If src or des is \sc or \alsa they are interpreted as sc or alsa input or output channels. Otherwise, src or des can be strings of the jack program ports.

SCJConnection.disconnect( srcchan, deschan, src, des )

Disconnects srchan with deschan.
Arguments as in .connect.

SCJConnection.getconnections

Get a list of current jack connections (via jack_lsp).
List gets stored in class variable .connections

SCJConnection.getproperties

Get a list of properties of all jack ports (via jack_lsp).
List gets stored in class variable .properties

SCJConnection.getallports

Get a list of all jack ports (via jack_lsp).
List gets stored in class variable .allports


The above three methods get automatically called in the .initClass method.

jc = SCJConnection.new( srcchan, deschan, src, des )

Create an instance of a Jack Connection. Arguments as in the class method .connect and .disconnect.
The instance can then later be connected using the instance method .connect of .disconnect:

jc.connect


and

jc.disconnect



Other important class variables:

SCJConnection.prepend

the prepend to the program call for jack_connect, jack_disconnect, and jack_lsp.
Needed when the programs are not in the search path.

SCJConnection.alsadef

SCJConnection.scdef


The defaults for alsa and sc ports, when the src and des arguments are used. These are initialised in .initClass with standard values.


Save as Class file (SCJConnection.sc):
SCJConnection { classvar <>alsadef, <>scdef, <>prepend, <allports, <connections, <properties;
	var <srcchan, <deschan, <source, <destination;
	
	*initClass{
		alsadef = ["alsa_pcm:","capture_","playback_"];
		scdef = ["SuperCollider:","in_","out_"];
		prepend = "";
		this.getallports;
		this.getproperties;
		this.getconnections;
	}

	*getconnections{
		var pp, line1, line2;
		connections = ();
		pp = Pipe.new(prepend++"jack_lsp -c", "r");
		line1 = pp.getLine;							
		while({line1.notNil}, {
			line2 = pp.getLine;
			if ( line2.notNil,
				{
					if ( line2.containsStringAt(0, "   "),
						{
							connections.put( line1.asSymbol, line2.copyToEnd(3).asSymbol );
							line1 = pp.getLine; 
						},
						{
							line1 = line2;
						});
				},
				{ line1 = line2 });
		});	
		pp.close;
		^connections;
	}

	*getproperties{
	var pp,line1, line2, prop;
		properties = ();
		pp = Pipe.new(prepend++"jack_lsp -p", "r");
		line1 = pp.getLine;							
			while({line1.notNil}, {
			line2 = pp.getLine;
			if ( line2.notNil,
				{
					if ( line2.contains("properties"),
						{
							prop = line2.split($:).at(1).split($,);
							prop[0] = prop[0].copyToEnd(1);
							prop = prop.keep( prop.size -1 );
							properties.put( line1.asSymbol, prop );
							line1 = pp.getLine; 
						},
						{
							line1 = line2;
						});
				},
				{ line1 = line2 });
		});	
		pp.close;
		^properties;
	}

	*getallports{
		var pp,line,cnt;
		cnt = 0;
		allports = ();
		pp = Pipe.new(prepend++"jack_lsp", "r");
		line = pp.getLine;							
		while({line.notNil}, {
			allports.put( cnt, line.asSymbol );
			line = pp.getLine; 
			cnt = cnt + 1;
		});	
		pp.close;
		^allports;
	}

	*connect{ |srcch, desch, src, des|
		var command;
		if ( src.isNil or: des.isNil,
			{ 
				Task({ 
					srcch.do{ |it,i|
						command = prepend++"jack_connect" + allports.at(it) + allports.at( desch[i] );
						command.unixCmd;
						0.2.wait;
					};
					this.getconnections;
				}).play;
			},
			{
				if ( src == \alsa, { src=alsadef[0]++alsadef[1] });
				if ( src == \sc, { src=scdef[0]++scdef[1] });
				if ( des == \alsa, { des=alsadef[0]++alsadef[2] });
				if ( des == \sc, { des=scdef[0]++scdef[2] });
				Task({ srcch.do{ |it,i|
					command = prepend++"jack_connect" + src++it + des++desch[i];
					command.unixCmd;
					0.2.wait;};
					this.getconnections;
				}).play;
			});
	}
	
	*disconnect{ |srcch, desch, src, des|
		var command;
		if ( src.isNil or: des.isNil,
			{ 
				Task({ srcch.do{ |it,i|
					command = prepend++"jack_disconnect" + allports.at(it) + allports.at( desch[i] );
					command.unixCmd;
					0.2.wait;};
					this.getconnections;
				}).play;
			},
			{
				if ( src == \alsa, { src=alsadef[0]++alsadef[1] });
				if ( src == \sc, { src=scdef[0]++scdef[1] });
				if ( des == \alsa, { des=alsadef[0]++alsadef[2] });
				if ( des == \sc, { des=scdef[0]++scdef[2] });
				Task({srcch.do{ |it,i|
					command = prepend++"jack_disconnect" + src++it + des++desch[i];
					command.unixCmd;
					0.2.wait;};
					this.getconnections;
				}).play;
			});
	}

	*new { arg srcch, desch, src, des;
		^super.new.init(srcch, desch, src, des);
	}

	init { arg srcch, desch, src, des;
		source = src;
		destination = des;
		srcchan = srcch;
		deschan = desch;
	}

	connect{
		SCJConnection.connect( srcchan, deschan, source, destination );
	}

	disconnect{
		SCJConnection.disconnect( srcchan, deschan, source, destination );
	}
}


Link to this Page