Installation instructions are inside the
that come with the tarballs.
This section is just a brief teaser showing a typical workflow.
Better read on before starting off, also check the usual
chino, Jack and Alsa-sequencer must be up and
running (unless not required by any application). We must not use the
-Xseq options of
chino will not work together with those.
We must point
chino to a preset, either by using
-p option or via configuration file. It's probably a
good idea to copy the system-wide configuratiuon file
<sysconfdir>/chino.conf to a per-user configuration
~/.chinorc, then enter the path to the preset that
we'll use most often.
Two ways exist to create a new session:
- by starting an empty session and adding applications via the runtime user interface, then saving;
- by editing a session definition file prototype (a
simple file format
chinouses to save sessions) with a text editor, then opening that file with
Now both in more detail:
$ chino -n opus3
will start an empty new session named
$ chino -n ~/sessions/opus3
Optionally, we can point to a template and/or a preset on the command line. The preset given will override the corresponding setting in the configuration file.
$ chino -n opus3 -t /home/eeyore/studio/opus2.sdef -p /home/eeyore/presets/opusN.sdef
This way the session
opus2will be copied from the preset
Now we can start with adding a method, then adding applications and methods to our liking, using keybindings from the runtime user interface. In between, entering
wwill save the session; a session definition file named
opus3.sdefgets written to the base directory.
To recover the session later on, we use the
-o(open) flag with the path to the session definition file as an argument.
$ chino -o ~/sessions/opus3.sdef
Session names may only contain uppercase and lowercase letters, numbers and underscores.
This is much like opening a session, as just described, with the only difference that we manually fill the session definition file, starting from a prototype. This is often faster than adding things one by one via the runtime UI.
$ chino -w
will write out a prototype session definition file
proto.sdefto the current directory.
Now we can edit this file. We must enter a name for the session and we may fill in some applications to start with and point to a preset and template.
To now create (open) the session, we just enter
$ chino -o proto.sdef
Then we may watch and pray until all applications are started and properly interconnected. For adding further applications (or for removing, restarting or [...]), we may then start the full runtime user interface.
When saving the first time, (the
<session_name>.sdefwill be written to the base directory. Since
proto.sdefstill works—it is just the same format—we may or may not consider it obsolete after its initial job.
That's about it when it comes to using
chino, keybindings of the
runtime user interface are self explaining.
M - add a method
A - add an application
X - remove an application
R - restart an application
. - localise application/method library
: - localise all used libraries
f - force sourcing of application/method library
l - list current session
d - check dependency tree
D - check dependency tree including optional depends
g - toggle session graph display
w - write changes to session definition file
a - redo audio connections
m - redo midi connections
s - store connection snapshot
r - restore connection snapshot
u - un-store connection snapshot
ctrl+c - quit
h - viev keybindings
The three snapshot-keybindings will only work if the
utility is installed, but they are in no way required to run
chino. They just might come in handy when we
ocasionally want to save some connections on top of those
that are part of the session.
chino. Users won't have to bother with most of this but it might be helpful for getting an idea of what the whole thing is is about.
Imagine starting one Jack audio application manually—the steps to be done will be something along the line of: starting the application, then establishing audio and Midi connections, maybe also some file copying/loading/saving to keep things together in an appropriate location.
chino internally divides everything
On the next level, tasks are used. A task is just a series
of steps that accomplishes something useful. This is a minor
simplification, since tasks often require some logic around the
steps, but that's not the point here.
Tasks may be vertical, calling a number of steps for one application, e.g. for adding an application to a session.
Tasks may be horizontal, calling one step for all applications, e.g. for establishing Midi connections for all applications.
Tasks may be both horizontal and vertical, e.g. for opening a session.
Some steps are just used internally, e.g. for writing the session graph, others are exposed to the user (public steps). We'll come back to public steps in the next section, for now there's just a list describing them:
- for assigning an application to an array and sourcing application libraries;
- for checking whether an application's file or directory is present, if applicable;
- for displaying a summary to the user;
- for copying and renaming the application file if the above check was negative;
- for starting the application, includes assigning of port variables;
- for establishing audio connections using the assigned port variables;
- for establishing Midi connections using the assigned port variables;
- for unassigning and killing an application when removed using the runtime user interface;
- for killing an application on quitting the session.
Methods are categories for applications that are to be handled in similar ways. Every application belongs to one method.
An application in this context can be (almost) anything: whether one or more (audio)-programs, audio/Midi hardware or netjack ports—many things can be crammed into an application.
While most applications within the default preset are named
after the real program's name, like
chino's terms is a combination of the
actual program (or soundcard or...) and a particular way to use it.
One could for instance have two applications called
Every method and application is defined by its library, a file in Bash syntax, containing some variables and functions.
For every public step, a method library must provide a
step function (not to be understood in the mathematical
sense). That function will be called by
chino whenever the step
is to be done for one of the method's applications.
It is then up to the method to determine what exactly to do for a step.
To give an example: the
hw (hardware) method from the default
preset does nothing for the copy-step, since audio and Midi
hardware will never need files copied.
An application's method thus largely determines what functions and variables are required in the application library—these can be very few for some methods, making it cheap to add support for more applications.
Two method types are hard-coded into
unique methods and channel methods.
For unique methods, application names are assigned to a consecutively filled array of variable length. Entries must be unique, thus the name.
For channel methods, application names are assigned to indices within a fixed-sized array, where indices may be left empty. Applications need not occur uniquely within a channel method. An obvious use case (though not the only possible) is using the index to connect an application to a certain audio or Midi channel, thus the name.
The size of method arrays is limited to 1000 (indices 0 – 999).
Methods may add a keybinding to the runtime user interface, for doing custom stuff of their choice.
Method and application names may only contain uppercase and lowercase letters, numbers and underscores. Application names must be unique within their method, method names' first two characters may only be letters and must be unique within their method type.
Every method has a method ID, which consists of its
name prefixed with
uq_ for unique methods and
ch_ for channel methods, e.g.
ch_instrument for a channel method named
Similarly, application IDs exist, consisting of the
application name and a prefix
<type> being either
uq, depending on the application's method's type,
<az> being the first two letters of the
application's method's name. To give an example from the default
preset: the application yoshimi, being a member of the
channel method synth, has the ID
The purpose of those naming rules is to make sure all methods and applications (within one preset) have unique IDs. The IDs will be used for naming files, directories, variables and functions; thus they must not mix up.
The program itself consists of a main script and some files that are sourced on demand. For documentation purposes, a dummy preset is included.
Installation will place the following files in your system:
- the main script
- a directory containing the remaining source files
- A directory containing the dummy preset, consisting of two
ch_dummy) and two applications (
- The system wide configuration file. To override, copy it to
~/.chinorcwhich will then take precedence.
One session has all its files below one base directory. Multiple sessions may share the same base directory.
Once populated, a session directory tree looks like this:
- Application subdirectories, one for each application,
containing the application files (synth patches, Ardour
session directories—whatever an application needs
to start). Those files or directories have fixed names,
files may have a suffix:
- for unique method applications;
- for channel method applications, with
<channel_number>being their array index + 1, always three digits long with leading zeros.
- An optional directory that may contain application libraries,
method libraries and a file called
- for application libraries;
- for method libraries;
- a file where all supported methods and applications
- A hidden directory where aj-snapshot's snapshots reside.
- A hidden directory where the dot files and svg's for the graph reside.
- The session definition file.
As shown in the previous section, method/application
libraries are part of the session. Thus
chino on its own will
be helpless, it always needs to be pointed to a special session,
called preset, from where it can source
libraries and copy files.
The only thing special, distinguishing a preset from any other sesssion,
is that a preset needs to be complete. That is, it must contain all files
that can possibly be required by the methods and applications
registered in its
listlib file, including a complete set of
libraries below the
A template can optionally be given, which is just any session derived from the preset used.
When opening a session, there are three places where
look for files: the current session, the template and the
First, the libraries are sourced, beginning with listlib.
Any library found in the session's local
takes precedence over the template session's one, last comes the
Next, all required but locally missing application files get copied from the template or preset, in that order of precedence again.
chino does not unsolicitedly copy libraries
from the preset to the local session, they will usually only be
present in the preset. To override this, to allow for customised application and
method behaviour on a per session base, single libraries
can easily be "localised" via the runtime user interface.
To not break behaviour for future sessions that use the current session as a template, libraries found local to the template will automatically get localised.
For making sessions self-contained, a keybinging allows to localise all used libraries. Self-contained sessions use themselves as a preset.
Some applications may not require any connections (e.g. gjackclock or a text editor). For all others that will be part of the connection graph, depends or provides must be given.
- Applications that require connections to be established, therefore relying on the presence of certain ports to connect to, will get one or more depend.
- Applications that allow connections to be established, therefore offering certain ports for others to connect to, will get one or more provide.
Instead of tying dependencies to specific applications, they are tied to port groups. An application may thus depend on port groups and provide for port groups.
A port group is merely a name given to a freely defined set of port variable names. Port group names must be unique within each of the the two connection types (audio and Midi), they may only consist of uppercase and lowercase letters, numbers and underscores.
The providing application assigns its real Jack or Alsa-seq port names to the defined port variables, the depending applications use those and their own ones to establish connections.
Dependencies are handled separately for the two connection types, thus an application may have any of the four: audio depends, Midi depends, audio provides and Midi provides.
While multiple applications may depend on the same port group, a port group can not be provided more than once, as this will lead to ambiguity. A providing channel method application running on multiple channels is not considered ambiguous.
chino is not as strict as to refuse starting applications
that violate a sane dependency tree, it'll just do three
things in response:
- not attempt to establish connections where providing port groups are missing or ambiguous;
- warn and suggest fixes upon request;
- stain the graph with some supposedly disturbing colors.
Prefixing a depend with a colon suppresses the latter two responses, i.e. making it an optional depend.
Just as applications, methods may also depend and provide. For the method's depends and provides, the method will handle assignment and connecting for its applications; for application's depends and provides, the application does this itself.
g in the runtime user interface, the
dependency graph is displayed using
xsvg is nice and simple, it seems not to be packaged for some
popular distributions. For that reason it can be easily
replaced with some other image-viewer, by editing a line in the
the graph explained
Every application gets a node drawn, with depends listed on the bottom and provides on the top, audio on the left and Midi on the right. Every method having any depends or provides will also get such a node, as well as a cluster around it containing all its application's nodes. The cluster's or node's background colour is determined by the method type.
Audio dependency connections are drawn as red solid lines, Midi dependency connections as yellow dashed lines.
Nodes with unsatisfied depends get dark blue solid borders, nodes ambiguously providing get light blue dashed borders.
To show an example from the default preset, here is a graph with one ambiguous provide and four unsatisfied depends:
STEREOwhich is not provided, and the method
ch_synthas well as the application
uqms_qmidiarpboth depend on
SEQwhich is ambiguously provided.
Now with dependencies fixed, by removing
Note that the connections drawn are quite dissimilar to those in applications like qjackctl or patchage:
- the graph just displays the session as it should be, not necessarily as it is;
- one connecting line in the session graph may represent any number of actual Jack/Alsa connections, regardless of direction.
It is very much up to the user's taste in what direction to define dependencies—it might be uncontroversial that a mixer application will depend on the Jack ports corresponding to the sound card, but when it comes to the order in which a sequencer, an arpeggiator and a synthesizer should depend on each other, opinions could vary.
For all public steps except unassign, a helper function exists. Helper functions may be called by the method librarys' step functions, to simplify accomplishing the step.
- Sources required application libraries.
- Checks for the existence of application files.
- Prints a line whenever the session summary is displayed to the user.
- Copies the application file or directory. If the application requires it, an additional move-function will be called to adapt the the application file to the new name, e.g. to change the session name in Ardour's XML files.
- After starting the application by calling a function from the
h_start()calls assign functions according to the dependencies. On each application start—for both, the application's method and the application—the following will be done:
- if any audio depend or provide exists, an assign function for audio is called;
- if any midi depend or provide exists, an assign function for Midi is called.
It is the method/application library that has to provide these functions, in accordance with their depends and provides.
Every assign function gets two multi-line arguments passed, containing the application's real input and output ports as named within Jack/Alsa-seq. Using grep or sed or whatever works best, those real port names can then be assigned to the appropriate variable names. (The real port names are retrieved via a diff of two
aconnectsnapshots taken before and after application startup, so they'll be independent of launch order.)
Calls one audio connect function for each of the method's and application's audio depends. If provided by a method or a channel method application, the connect function is called once for each occurrence.
If the port-variable names are suffixed with either nothing or
_Rfor mono, or with both
msaudioconnect()may be used inside the connect function for mono-stereo-agnostic audio connecting.
Calls one Midi connect function for each of the method's and application's Midi depends. If provided by a method or a channel method application, the connect function is called once for each occurrence.
Inside the connect functions,
ajmidiconnect()will connect Midi ports irrespective of type. For that to work, port-variable names must be suffixed with
_Afor Alsa-Midi and
_Jfor Jack-Midi. Using
jack_connectdirectly will likely break this feature.
- Kills an application.
During a step, methods may also register final functions and arguments for those. Whenever a task has finished a step for all applications it intends to operate on within one method, it calls registered final functions before moving on to the next method or step.
It may appear awkward to make a step public in the first place,
and then let the method call a standardised helper function that
could have been called centrally from within
chino. This is done
to give methods flexibility, in that they may decide how exactly
to accomplish a step.
In most cases it is desirable to just use the helper functions
in their usual way, it's mainly the
ch_senv methods in the default preset that do lot's
of custom stuff; to a lesser extent the uq_hw (hardware) method,
leaving out obsolete steps like file-copying and working around
the fact that
h_start() is inapplicable.
The remaining documentation consists of comments in the
method libraries and application libraries.
chino installs a
dummy preset that doesn't do much besides containing the
comments, for real-world applications there's the