Linux Audio Sesssion Scripting

Post fully complete "how to" guides and tutorials here. This is a great place to get feedback on stuff you might put in the wiki.

Moderators: MattKingUSA, khz

studio32

Linux Audio Sesssion Scripting

Post by studio32 »

http://digitaldub.wordpress.com/2009/12 ... scripting/
Linux audio session scripting

2009/12/16

Here comes a little tutorial. It will lead beginners through the process of writing small scripts that open audio sessions with interconnected applications.
Some familiarity with Linux audio applications and simple use of the command line is assumed, if you lack these and you are still interested, work through the material behind the respective link and use google. Familiarity with shell scripting is not required. I recommend one of the pre-tweaked Linux audio distributions.
general concepts
One common difference between open source and proprietary software is the level of modularity. Commercial solutions more often offer one big application with many features, whereas in the Linux world applications tend to be smaller and more specialized.
Usually these small tools can easily inter-operate and communicate by means of open standards, to solve complex tasks together in modular systems. Much as in good old analog audio, where usually a few devices work together, interconnected by standardized audio and Midi signals via cables, or as with VST plugins for win/mac, that can be used within several hosts.
In the case of Linux audio software there are a number of standards for communication among programs.
Jack for instance does the audio routing between all inputs and outputs provided by the applications and the soundcard. Jack also provides transport synchronisation via Jack_Transport.
The case of Midi is a bit more involved, explained here.

BASH session scripts
This modularity is great, apart from one disadvantage: There is not yet one ‘load session’ and one ’save session’ button. This is what the LADCCH, LASH and LADI projects aim(ed) to accomplish. LADCCA is since long discontinued, LASH is the most-widely-but-not-too-widely adopted implementation, LADI is a rewrite of LASH.
Until the session management systems mature, scripts are an obvious option to accomplish the task of restoring a session. They save much time and lead to less errors, just by introducing an exactly reproducible procedure.
Ideally, you execute the script, wait a few seconds and continue to play/work, without having to adjust a single knob or fader to regain the previous state. Picture it as writing a new audio application, written in a scripting language.
Ideally, the only practical difference to the monolithic proprietary application is the lack of a single save button. Call it a feature — being able to decide in which apps to save changes after some tweaking can be an advantage.
I am saying ideally above, because this does not always work as easy as with the monolith. It is largely a matter of carefully selecting well behaving applications and plugins that fit your needs.
Depending on what you intend to do, all this might be a little more work than setting up a monolithic app. The upsides are more flexibility and most likely a unique sound. Once you have template scripts for basic tasks it takes little effort to create a new session.

the script I
The Bash scripting language is used for the examples. If Bash is new to you, this might be a good occasion to look into its documentation. If you don’t feel like working through all that, this tutorial will get you to write scripts for simple tasks. However, some background knowledge is helpful, especially when it comes to troubleshooting.
The first example is a script for starting Aeolus to be played using a Midi Keyboard.
Use an adequate text editor like gedit, vim, emacs, scite or the like to write the script. Do not use anything that does text formatting, such as OpenOffice or Abiword.
For the sake of simplicity I will omit most background information and stick to simple one-command-per-line scripts.
First create a session directory to put everything in, change to that directory and start a text editor.
Every bash script begins with the line #!/bin/bash, then the instructions follow.
A script for starting Aeolus.

#!/bin/bash
aeolus

Save that file using any name, e.g. aeolus.sh to your session directory and make it executable by executing
$ chmod u+x aeolus.sh
To execute the script, type
$./aeolus.sh
This just starts Aeolus, so next two kinds of connections need to be made — audio and Midi.

audio connections
The command line tools are jack_connect and jack_disconnect (The latter especially helpful against this nasty behavior of some apps to auto-connect to the soundcards on startup). jack_lsp lists all existing ports. Use the –help option to read all about usage.
The syntax is actually simple:

jack_connect <out_port> <in_port>

alsa-Midi connections
aconnect works much the same way for Alsa-Midi as jack_connect for Jack-audio. aconnect -io will list all Alsa-Midi input and output ports. See the output of aconnect (without options) and man aconnect for the details.
Note that the port names used below are just examples, so simple copy pasting may not work. The listing tools will reveal the names on your machine. Assemble and test the commands in a terminal and complete the first example.

#!/bin/bash
aeolus &
sleep 2
jack_connect aeolus:out.R system:playback_1
jack_connect aeolus:out.L system:playback_2
aconnect USB\ Device:1 aeolus:0


The script explained:
After Aeolus is started, jack_connect is invoked twice for connecting the two audio outputs of Aeolus to the soundcard. aconnect connects an external USB Midi keyboard to Aeolus.
The backslash in the string USB\ Device:1 is an escape character. When interpreted on execution, the character following the escape character (here whitespace, wich happened to be part of the device name listed by aconnect) will loose its special function as a seperator. An other option would be to use quoting and write aconnect 'USB Device':1 aeolus:0
Read more about quoting here if you want.
The & symbol in the line aeolus & puts Aeolus in the background so that the terminal is ready for receiving more commands. Without it, the terminal would remain occupied and no further command would be executed as long as Aeolus is running.
The second command, sleep 2, interrupts execution for two seconds to give Aeolus’ ports a little time to come up before attempts are made to connect them.

Jack-midi-connections
aconnect only connects Alsa-Midi ports. Jack-Midi connections are done with the same tools as Jack audio connections.
In the case of Aeolus, supporting both Midi systems, the aconnect command can be substituted by jack_connect.
Unless you use ‘Raw’ as the Midi driver in Jack, using Jack-Midi is actually depreciated because of a longer Midi signal path. if you have the choice, use aconnect to connect any hardware Midi device to an app. Alsa Midi only apps are best interconnected by aconnect, Jack-Midi-only apps are connected via the Jack tools.
If all apps you are using happen to have Jack-Midi support you can perfectly use ‘Raw’ as the Midi driver to omit Alsa and do all connections with the Jack tools. For the backgrounds (re)read the explanation linked above.

#!/bin/bash
aeolus &
sleep 3
jack_connect aeolus:out.R system:playback_1
jack_connect aeolus:out.L system:playback_2
jack_connect system:midi_capture_3 aeolus:Midi/in

jack_snapshot
jack_snapshot is a command line tool to store and restore Jack connections.
Using jack_snapshot, the Aeolus startup script would look like this:

#!/bin/bash
aeolus &
sleep 3
jack_snapshot restore aeolus_snap

For this to work, the file named ‘aeolus_snap’ of cause needs to exist. To create it, start the applications, establish all required connections manually, then execute

jack_snapshot store aeolus_snap

the script II
Now an example for Seq24 synced with ardour. Seq24 is sending virtual Midi to yoshimi, Ardour is recording the audio output.
I will proceed in two steps. A first draft of the script starts all applications, maybe with some appropriate options. appname -h or appname --help will usually reveal the secrets.

#!/bin/bash
seq24 --manual_alsa_ports \
--priority \
--jack_transport &
sleep 2
yoshimi &
sleep 1
ardour &

Just for readability, the \ characters are used to break the line without actually breaking the line.
When this script is executed, ardour will let you create a new session. Select Jack-Sync and add tracks ore busses as required, then manually establish all Jack connections.
Do some editing in Seq24 and yoshimi and save the files to the session directory. Save and quit Ardour, then create a snapshot with jack_snapshot.
Extend the script accordingly, e.g.:
#!/bin/bash
seq24 –manual_alsa_ports \
–priority \
–jack_transport \
–file seq24.mid &
sleep 2
yoshimi -l yoshimi01.xmz &
sleep 2
jack_snapshot restore snapshotfile
sleep 1
ardour ardoursession/ardoursession.ardour &
The sleep time needed in between the applications can vary, depending on soft- and hardware. Start with plenty of time, since too short intervals might cause problems. Reducing these can be done as a later step of optimisation.
Connections from, to or within Ardour will be done by Ardour itself when loading a session. This is why all apps apart from Ardour are loaded first, jack_snapshot is then executed for the non-Ardour connections, Ardour follows after a delay.
Accordingly, when changing the session in a way that you need to store a new set of connections with jack_snapshot, save and quit ardour before taking the snapshot.
Attempting to restore existing Ardour connections with jack_snapshot can cause Ardour to crash with the somewhat misleading message: “critical: event pool out of memory – recompile with larger size!!”.

paths
For running the above script, the files loaded and the Ardour session file all need to be in the same directory together with the script. This is no general necessity, it just makes the script as simple as possible.
Something else might be more convenient. For instance a base directory holding several session scripts and separate subdirectories for each single app to keep its patches and configuration files all in one place.
With slight changes to the paths (the places to look for a files) the script could be adapted to that environment.

#!/bin/bash
seq24 --manual_alsa_ports \
--priority \
--jack_transport \
--file seq24/seq24.mid &
sleep 2
yoshimi -l yoshimi/yoshimi01.xmz &
sleep 2
jack_snapshot restore jsnap/snapshotfile
sleep 1
ardour ardour/ardoursession/ardoursession.ardour &

In all cases above, the paths given are relative paths. All files need to be either in the directory where the script is executed or in any (sub…)subdirectory. This is useful for porting the session to a different computer and it makes backups easy.
Instead of relative ones, absolute paths can be used — this might as well be useful in some setups. An absolute path gives the whole path from the root directory like /home/epikur/zynaddsubfx/bass.xmz. If all paths given in a script are given as absolute paths, the script can be located and executed in any directory.
For portability to other users than epikur, the hard coded “magic user” can be replaced by the envirenment variable ${HOME} like this: ${HOME}/yoshimi/bass.xmz
A possible use of an absolute path could be to point to an Ardour session that is stored on a data-partition separate from the session folder.

#!/bin/bash
seq24 --manual_alsa_ports \
--priority \
--jack_transport \
--file seq24/seq24.mid &
sleep 2
yoshimi -l yoshimi/yoshimi01.xmz &
sleep 2
jack_snapshot restore jsnap/snapshotfile
sleep 1
ardour /mount/audiodata/ardour/ardoursession/ardoursession.ardour &

kill script
It is handy to have a little kill script for terminating the session. An example:

#!/bin/bash
echo === attentione ===
echo "really quit? you have 3 seconds..."
sleep 3
echo "...killing session..."
killall seq24
sleep 1
killall yoshimi
sleep 1
killall ardour-2.8.4
echo "...session dead."

jack_snapshot script
another useful helper:

#!/bin/bash
jack_snapshot store snapshot

backup
After some effort is put into developement of scripts and sessions, backup your session directory:
tar -cvjf session session0910.tar.bz2
Copy the tarball to at least a second storage device, hardware tends to fail sometimes. Sure, the whole backup process can be automated as well, but that is another post of its own.

More info:
http://digitaldub.wordpress.com/2009/12 ... scripting/
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

Dear studio32,

not to be misunderstood, I very much embrace the whole idea of open source, free access to information and I am by far no friend of the copyright law. Nevertheless I regard the way you copy-pasted my blog post as nothing but impolite. My discomfort has no juridical base, just common sense.

First of all, you could have asked before.

You did not give any explicit credit, only two redundant links. Labelling the link at the bottom 'More info:' is inaccurate and misleading to the user, since the given link contains the same info, not more.

Posting a link to the blog, maybe together with a description, would have been totally sufficient and would meet the users needs in the same way if not better, since the formatting is a little degraded here.

An example (in dutch) showing how this can be done (just for the future:)
http://www.homerecording.be/forum/t16082.htm

Well, maybe It's the parallels I am seeing to my former job at a the online release of some mayor yellow press house. Their primary goal was to accumulate as much cheap content as possible; they stole private pictures from myspace/facebook, copied from other newspapers, reused old material as long as possible, [...], just to pretend having content, for SEO reasons and to keep users clicking their site.

In a non-profit realm such as Linux audio all this makes no since. It is about the community serving the community with information in the best possible way, not about attracting people to one particular site. Please stop spamming your forum with duplicates.

Nevertheless, keep up the good work. :wink:

all the best,
laiis
User avatar
raboof
Established Member
Posts: 1855
Joined: Tue Apr 08, 2008 11:58 am
Location: Deventer, NL
Has thanked: 50 times
Been thanked: 74 times
Contact:

Re: Linux Audio Sesssion Scripting

Post by raboof »

http://planet.linuxmusicians.org also picked up this post because of the http://en.wordpress.com/tag/linux-audio/feed/ feed, but it currently only seems to show only a very small part of the description. Not sure if it's possible to fix that :/.
User avatar
autostatic
Established Member
Posts: 1994
Joined: Wed Dec 09, 2009 5:26 pm
Location: Beverwijk, The Netherlands
Has thanked: 32 times
Been thanked: 104 times
Contact:

Re: Linux Audio Sesssion Scripting

Post by autostatic »

Liked the article, for me it was pretty insightful and helpful. So thanks laiis! And btw, studio32=Jacks, as far as I know they are one and the same person.
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

raboof wrote:http://planet.linuxmusicians.org also picked up this post because of the http://en.wordpress.com/tag/linux-audio/feed/ feed, but it currently only seems to show only a very small part of the description. Not sure if it's possible to fix that :/.
Cool, I didn't know about the tag feeds, still new to wordpress. I certainly have no problem with that. On a planet it is obvious that the content is aggregated from somewhere else and the source is transparent. And I expect that formatting and especially links remain unchanged in this case.

For newbies some of the links are essential, I didn't bother to explain stuff that is well explained elsewhere.

Can't reach http://planet.linuxmusicians.org/ ATM, server not found. I'll try later.

thanks.
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

AutoStatic wrote: And btw, studio32=Jacks, as far as I know they are one and the same person.


:) funny, and thanks to studio32jacks for the promotion.
User avatar
raboof
Established Member
Posts: 1855
Joined: Tue Apr 08, 2008 11:58 am
Location: Deventer, NL
Has thanked: 50 times
Been thanked: 74 times
Contact:

Re: Linux Audio Sesssion Scripting

Post by raboof »

laiis wrote:I expect that formatting and especially links remain unchanged in this case.
Links, sure. Formatting, well, mostly.
Can't reach http://planet.linuxmusicians.org/ ATM, server not found. I'll try later.
Drat, of course it's http://planet.linuxmusicians.com , sorry :). There's also a link above.
studio32

Re: Linux Audio Sesssion Scripting

Post by studio32 »

@laiis, the info on your blog was so useful, I didn't want to loose it some day. That's why I posted it as whole here. But to make users also aware of the original post, I posted the link to it twice, so I thought about the fact that a blogger maybe wants to have visitors. I could have put also your name under it, but I was in a hurry, but I will do that next time.
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

@ studio32
okok, maybe slight overreaction in terms of wording on my side. :-}
AFAIK wordpress is a rather safe place. I do not intend to delete any of the posts, only improve them.

To keep the engines running, another tutorial, dealing with ghostess and DSSI:
http://digitaldub.wordpress.com/2009/12 ... -and-dssi/
jaycapela
Established Member
Posts: 20
Joined: Thu Aug 19, 2010 8:19 am

Re: Linux Audio Sesssion Scripting

Post by jaycapela »

After experiencing instability issues and sessions refusing to load in Ladish, I think I'm going to fallback to the scripted approach of session management. I have one question, though...

Is there a way to rename Jack clients via command-line? Qjackctl can rename clients but there's no cli tool included to accomplish this on a per-case basis, and jack_alias included in Jack2 only creates aliases of ports and can not modify client names.
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

jaycapela wrote:Is there a way to rename Jack clients via command-line? Qjackctl can rename clients but there's no cli tool included to accomplish this on a per-case basis, and jack_alias included in Jack2 only creates aliases of ports and can not modify client names.
Renaming ports in Qjackctl does not change the port names as seen by jack_lsp, so I assume it is a feature internal to Qjackctl. I have never heard of a command line tool to rename Jack ports or clients.
AFAIK the clients itself can modify their port names. Client names, once set by the application at startup, remain static.

What is it, you want to accomplish - or do you explicitely need to rename ports?
Just curious.
jaycapela
Established Member
Posts: 20
Joined: Thu Aug 19, 2010 8:19 am

Re: Linux Audio Sesssion Scripting

Post by jaycapela »

laiis wrote:
jaycapela wrote:Is there a way to rename Jack clients via command-line? Qjackctl can rename clients but there's no cli tool included to accomplish this on a per-case basis, and jack_alias included in Jack2 only creates aliases of ports and can not modify client names.
Renaming ports in Qjackctl does not change the port names as seen by jack_lsp, so I assume it is a feature internal to Qjackctl. I have never heard of a command line tool to rename Jack ports or clients.
AFAIK the clients itself can modify their port names. Client names, once set by the application at startup, remain static.

What is it, you want to accomplish - or do you explicitely need to rename ports?
Just curious.
Quite recently I imagined a hair-brained scheme to make template scripts for synth connection setups that involved more than one Jack application in a way that resembled Propellerhead's Reason Combinator patches... and perhaps wrap them tidy in an Xnest running a lightweight window manager. By allowing to have unique client names, I would be able to use these templates interchangeably between different session scripts and not have to manually route things all the time.

In general, enabling unique client names for all Jack applications would allow simple session scripts to be maintained independent of application launch order and would allow for unique elements to be easily added and subtracted. Essentially, I'm trying to bypass the weird numbering schemes of Alsa MIDI (i.e. 129:ardour or 131:seq24).
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

Xnest was new to me - it sounds very promising.
Automatically assigning applications to workspaces would
then be another great thing. It's just an idea that I have
since long ago, though I never did intensive research in
whether this is possible.

I don't know the Reason patches but maybe I can imagine a
little... it's about interconnecting applications in useful
standard ways.

For independence of application launch order, this might
do as a workaround:

Instead of starting an application directly, start it
through a function that takes a diff from jack_lsp before
and after startup, extracts the port names from it and
gives each of the new ports a jack_alias.

An example:
http://pastebin.com/GjRRT5Nc

The downside: every (type of) application needs its function.


Similar for Alsa-Midi (gives no alias, just a variable
containing the port name):

http://pastebin.com/9Hqp5RuG

This works here with amSynth, phasex and yoshimi.
User avatar
autostatic
Established Member
Posts: 1994
Joined: Wed Dec 09, 2009 5:26 pm
Location: Beverwijk, The Netherlands
Has thanked: 32 times
Been thanked: 104 times
Contact:

Re: Linux Audio Sesssion Scripting

Post by autostatic »

aconnect also takes client names as addresses so you don't need to work with port numbers. Or am I missing something?
User avatar
laiis
Established Member
Posts: 24
Joined: Tue Apr 08, 2008 11:41 am
Location: suriname
Contact:

Re: Linux Audio Sesssion Scripting

Post by laiis »

AutoStatic wrote:aconnect also takes client names as addresses so you don't need to work with port numbers. Or am I missing something?
Yes, you're right.
The reason I used port numbers is more a 'shortcoming' of yoshimi, which gives subsequent instances the same client names. When attempting to connect via aconnect using this client name, only the one launched first gets the connection done.
Post Reply