ladi-website/index.html

937 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 10.2.0">
<meta name="keywords" content="LADI, JACK, jack-audio-connection-kit, session management">
<title>LADI Session Handler</title>
<style type="text/css">
/*
* AsciiDoc 'ladi' theme, based on 'volnitsky' theme for xhtml11 and html5 backends.
* Based on css from http://volnitsky.com, which was in turn based on default
* theme from AsciiDoc
*
* FIXME: The styling is still a bit rough in places.
*
*/
/* Default font. */
body {
font-family: Georgia,"Times New Roman",Times,serif;
font-size: 16pt;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Candara,Arial,sans-serif;
}
a.image { border-bottom: 0; }
#toc a {
border-bottom: 1px dotted #999999;
color: #3A3A4D !important;
text-decoration: none !important;
}
#toc a:hover {
border-bottom: 1px solid #6D4100;
color: #6D4100 !important;
text-decoration: none !important;
}
a { color: #666688; text-decoration: none; border-bottom: 1px dotted #666688; }
a:visited { color: #615FA0; border-bottom: 1px dotted #615FA0; }
a:hover { color: #6D4100; border-bottom: 1px solid #6D4100; }
em {
font-style: italic;
color: #444466;
}
strong {
font-weight: bold;
color: #444466;
}
h1, h2, h3, h4, h5, h6 {
color: #666688;
margin-bottom: 0.5em;
margin-right: 1em;
line-height: 1.3;
letter-spacing:+0.15em;
}
h1, h2, h3, h4, h5, h6 {
margin-left: 0em;
}
/* h1 { margin-left: 2em; } */
h2 { margin-left: 2em; }
/* h3 { margin-left: 4em; } */
/* h4 { margin-left: 5em; } */
/* h5 { margin-left: 6em; } */
/* h6 { margin-left: 7em; } */
h2 { border-bottom: 4px solid #ccd; }
h3 { border-bottom: 2px dotted #ccd; }
/* h2, h3 { border-bottom: 2px solid #ccd; } */
/* h2 { padding-top: 0.5em; } */
/* h3 { float: left; } */
/* h3 + * { clear: left; } */
div.banner {
background: #004455;
text-align: center;
color: #C6E9AF;
padding: 0;
margin: 0;
}
div.sectionbody {
margin-top: 0;
margin-left: 3em;
margin-right: 1em;
margin-bottom: 1em;
}
hr {
border: 1px solid #444466;
}
p {
margin-left: 0.5em;
margin-right: 0.5em;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
pre {
padding: 0;
margin: 0;
}
#author {
color: #444466;
font-weight: bold;
font-size: 1.1em;
}
#footer {
font-size: small;
border-top: 2px solid silver;
margin: 0;
}
#footer-text {
/* float: left; */
padding: 1em;
text-align: center;
}
#footer-badges {
float: right;
padding: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.5em;
margin-bottom: 2.5em;
}
#content { /* Block element content. */
margin: 2em;
}
/* Block element titles. */
div.title, caption.title {
color: #444466;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid silver;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid silver;
background: #f4f4f4;
padding: 0.5em;
}
div.quoteblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.verseblock > pre.content {
font-family: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #444466;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 2px solid silver;
}
div.exampleblock > div.content {
border-left: 2px solid silver;
padding: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: #444466;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
div.tableblock > table {
border: 3px solid #444466;
}
thead {
font-weight: bold;
color: #444466;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overridden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: #444466;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
@media print {
#footer-badges { display: none; }
}
#toctitle {
color: #666688;
font-size: 1.2em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 { margin-top: 0; margin-bottom: 0; }
div.toclevel1 { margin-top: 0.3em; margin-left: 0; font-size: 1.0em; }
div.toclevel2 { margin-top: 0.25em; margin-left: 2em; font-size: 0.9em; }
div.toclevel3 { margin-left: 4em; font-size: 0.8em; }
div.toclevel4 { margin-left: 6em; font-size: 0.8em; }
body {
margin: 0;
padding: 0;
}
.monospaced, tt, div.listingblock > div.content {
font-family: Consolas, "Andale Mono", "Courier New", monospace;
color: #004400;
background: #f4f4f4;
max-width: 80em;
line-height: 1.2em;
}
#header {
text-align: center;
margin: 2em;
}
#toc {
text-align: left;
margin-left: 3em;
max-width: 80%;
}
.paragraph p {
line-height: 1.5em;
/* margin: 1em; */
}
.paragraph p, li, dd, .content { max-width: 80em; }
.admonitionblock { max-width: 35em; }
div.sectionbody div.ulist > ul > li {
list-style-type: square;
color: #aaa;
}
div.sectionbody div.ulist > ul > li > * {
color: black;
/*font-size: 50%;*/
}
div.sectionbody div.ulist > ul > li div.ulist > ul > li {
color: #ccd ;
}
div.sectionbody div.ulist > ul > li div.ulist > ul > li > * {
color: black ;
}
em {
font-style: normal ! important;
font-weight: bold ! important;
color: #662222 ! important;
letter-spacing:+0.08em ! important;
}
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
/*
* html5 specific
*
* */
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #666688;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #444466;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #444466;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = { // Namespace.
/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////
/* Author: Mihai Bazon, September 2002
* http://students.infoiasi.ro/~mishoo
*
* Table Of Content generator
* Version: 0.4
*
* Feel free to use this script under the terms of the GNU General Public
* License, as long as you do not remove or alter this notice.
*/
/* modified by Troy D. Hanson, September 2006. License: GPL */
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
// toclevels = 1..4.
toc: function (toclevels) {
function getText(el) {
var text = "";
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
text += i.data;
else if (i.firstChild != null)
text += getText(i);
}
return text;
}
function TocEntry(el, text, toclevel) {
this.element = el;
this.text = text;
this.toclevel = toclevel;
}
function tocEntries(el, toclevels) {
var result = new Array;
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
// Function that scans the DOM tree for header elements (the DOM2
// nodeIterator API would be a better technique but not supported by all
// browsers).
var iterate = function (el) {
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
var mo = re.exec(i.tagName);
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
}
iterate(i);
}
}
}
iterate(el);
return result;
}
var toc = document.getElementById("toc");
if (!toc) {
return;
}
// Delete existing TOC entries in case we're reloading the TOC.
var tocEntriesToRemove = [];
var i;
for (i = 0; i < toc.childNodes.length; i++) {
var entry = toc.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div'
&& entry.getAttribute("class")
&& entry.getAttribute("class").match(/^toclevel/))
tocEntriesToRemove.push(entry);
}
for (i = 0; i < tocEntriesToRemove.length; i++) {
toc.removeChild(tocEntriesToRemove[i]);
}
// Rebuild TOC entries.
var entries = tocEntries(document.getElementById("content"), toclevels);
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.element.id == "")
entry.element.id = "_toc_" + i;
var a = document.createElement("a");
a.href = "#" + entry.element.id;
a.appendChild(document.createTextNode(entry.text));
var div = document.createElement("div");
div.appendChild(a);
div.className = "toclevel" + entry.toclevel;
toc.appendChild(div);
}
if (entries.length == 0)
toc.parentNode.removeChild(toc);
},
/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////
/* Based on footnote generation code from:
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
*/
footnotes: function () {
// Delete existing footnote entries in case we're reloading the footnodes.
var i;
var noteholder = document.getElementById("footnotes");
if (!noteholder) {
return;
}
var entriesToRemove = [];
for (i = 0; i < noteholder.childNodes.length; i++) {
var entry = noteholder.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
entriesToRemove.push(entry);
}
for (i = 0; i < entriesToRemove.length; i++) {
noteholder.removeChild(entriesToRemove[i]);
}
// Rebuild footnote entries.
var cont = document.getElementById("content");
var spans = cont.getElementsByTagName("span");
var refs = {};
var n = 0;
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnote") {
n++;
var note = spans[i].getAttribute("data-note");
if (!note) {
// Use [\s\S] in place of . so multi-line matches work.
// Because JavaScript has no s (dotall) regex flag.
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
spans[i].innerHTML =
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
spans[i].setAttribute("data-note", note);
}
noteholder.innerHTML +=
"<div class='footnote' id='_footnote_" + n + "'>" +
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
n + "</a>. " + note + "</div>";
var id =spans[i].getAttribute("id");
if (id != null) refs["#"+id] = n;
}
}
if (n == 0)
noteholder.parentNode.removeChild(noteholder);
else {
// Process footnoterefs.
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnoteref") {
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
href = href.match(/#.*/)[0]; // Because IE return full URL.
n = refs[href];
spans[i].innerHTML =
"[<a href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
}
}
}
},
install: function(toclevels) {
var timerId;
function reinstall() {
asciidoc.footnotes();
if (toclevels) {
asciidoc.toc(toclevels);
}
}
function reinstallAndRemoveTimer() {
clearInterval(timerId);
reinstall();
}
timerId = setInterval(reinstall, 500);
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
else
window.onload = reinstallAndRemoveTimer;
}
}
asciidoc.install();
/*]]>*/
</script>
<link rel="shortcut icon" type="image/x-icon" sizes="32x32" href="ladish-logo-32x32.ico" />
<link rel="icon" type="image/x-icon" sizes="32x32" href="ladish-logo-32x32.ico" />
<link rel="icon" type="image/x-icon" sizes="128x128" href="ladish-logo-128x128.png" />
<link rel="apple-touch-icon" type="image/x-icon" sizes="140x140" href="ladi-140x140.png" />
<link rel="apple-touch-icon" type="image/x-icon" sizes="128x128" href="ladish-logo-128x128.png" />
</head>
<body class="article">
<div class="banner">
<a href="https://ladish.org/">
<img src="ladish_dark.png" alt="LADI Session Handler" height="140" width="497" />
</a>
</div>
<div id="header">
<h1>LADISH</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>LADI Session Handler or simply ladish is a session management system
for <a href="https://jackaudio.org">JACK</a> applications on <a href="https://kernel.org/">GNU/Linux</a>.
Its aim is to allow you to have many different audio programs running
at once, to save their setup, close them down and then easily reload
the setup at some other time. ladish doesn't deal with any kind of
audio or MIDI data itself; it just runs programs, deals with
saving/loading (arbitrary) data and connects JACK ports together.</p></div>
<div class="paragraph"><p>The LADISH graphical interface (GTK+ based reference front end)
<span class="image">
<a class="image" href="https://lwn.net/Articles/533594/">
<img src="https://static.lwn.net/images/2013/audio-session/1-gladish-reteo.png" alt="gladish screenshot" width="100%">
</a>
</span></p></div>
<div class="paragraph"><p>The Claudia LADISH front end (Python + Qt based)
<span class="image">
<a class="image" href="https://lwn.net/Articles/533594/">
<img src="https://static.lwn.net/images/2013/audio-session/2-claudia.png" alt="Claudia screenshot" width="100%">
</a>
</span></p></div>
<div class="paragraph"><p>Features:</p></div>
<div class="ulist"><ul>
<li>
<p>
Save and restore sets of JACK (audio and MIDI) enabled
applications.
</p>
</li>
<li>
<p>
Subgraph management, the Studio &amp; Rooms concept.
Provide JACK clients with virtual hardware ports, so projects can
be transferred (or backups restored) between computers running
different hardware and backups.
Allows to decouple projects (loaded in a Room) from
hardware audio IO used in particular Studio.
A virtual jack-multicore cable connects room IO ports
to hardware IO ports.
</p>
</li>
<li>
<p>
Don&#8217;t require session handling library to be used. There is no need
of such library for restoring connections between JACK clients.
LADISH is able to manage JACK apps that don't link to liblash (or liblo).
This is known as L0 (level zero) in LADISH.
</p>
</li>
<li>
<p>
Seamless handling of apps that use ALSA sequencer ports.
This is achieved by use of a2jmidid and libalsapid.so.
The former creates jack-midi ports for the alsa sequencer ones.
The latter reports the alsa application process ID to ladishd,
so that ladishd can associate the a2jmidid-created ports with application.
</p>
</li>
<li>
<p>
Flow canvas based GUI. Positions of elements on the canvas are
saved/restored.
</p>
</li>
<li>
<p>
Allow clients to use external storage to save their state. This
includes storing internal state to non-filesystem place like memory
of a hardware synth. This also includes storing client internal
state (client project data) in a way that is not directly bound to
ladish project.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Among project future goals are:</p></div>
<div class="ulist"><ul>
<li>
<p>
Support for pipewire setups (in addition to JACK1 and JACK2)
</p>
</li>
<li>
<p>
List of available JACK applications.
</p>
</li>
<li>
<p>
Hierarchical and/or tag-based organization of projects.
</p>
</li>
<li>
<p>
Support for applications that create more than one jack client per process
</p>
</li>
<li>
<p>
Support for applications that create use more than one jack client process
</p>
</li>
<li>
<p>
<a href="https://ladish.org/nsm-proto.html">Non Session Manager protocol</a> support
</p>
</li>
<li>
<p>
<a href="https://new-session-manager.jackaudio.org/api/index.html">New Session Manager protocol</a> support
</p>
</li>
<li>
<p>
Collaborate with the X11 window manager so window properties like
window position, virtual desktop and screen (multimonitor) are
saved/restored.
</p>
</li>
<li>
<p>
Distributed studio - network connected computers. Netjack
configuration is part of the studio and thus is saved/restored.
Saving/restoring state in multi-machine network
</p>
</li>
<li>
<p>
Ability to move entire sessions between computers,
or post sessions on the Internet for download.
Import/export operations, as opposed to save/load. Save/load
operate in current system and may cause saving data outside of
project itself (external storage). Import/export uses/produces
"tarball" suitable for transferring session data over network to
other computer or storing it in a backup archive.
</p>
</li>
<li>
<p>
Session versioning via Git
</p>
</li>
</ul></div>
<div class="paragraph"><p>Tarballs:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="https://dl.ladish.org/ladish/">https://dl.ladish.org/ladish/</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>GIT repositories:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="https://gitea.ladish.org/LADI/ladish">Upstream development GIT repository</a><br>
Self-hosted upstream
</p>
</li>
<li>
<p>
<a href="https://github.com/LADI/ladish.git">Primary backup GIT repository at github.com</a><br>
Cloud hosted
</p>
</li>
<li>
<p>
<a href="https://repo.or.cz/ladish.git">Secondary backup GIT repository at repo.or.cz</a><br>
Cloud hosted
</p>
</li>
</ul></div>
<div class="paragraph"><p>LADI Session Handler was forked from the
<a href="https://lac.linuxaudio.org/2009/cdm/Thursday/02_Alasuutari/02.pdf">D-Bus-ified LASH project</a>.
Things that LADISH can do but LASH (D-Bus-ified or not) cannot:</p></div>
<div class="ulist"><ul>
<li>
<p>
Subgraph management, the Studio &amp; Rooms concept.
Allows to decouple projects (loaded in a Room) from
hardware audio IO used in particular Studio.
A virtual jack-multicore cable connects room IO ports
to hardware IO ports.
</p>
</li>
<li>
<p>
Don&#8217;t require session handling library to be used. There is no need
of such library for restoring connections between JACK clients.
LADISH is able to manage JACK apps that don't link to liblash (or liblo).
This is known as L0 (level zero) in LADISH.
</p>
</li>
<li>
<p>
Seamless handling of apps that use ALSA sequencer ports.
This is achieved by use of a2jmidid and libalsapid.so.
The former creates jack-midi ports for the alsa sequencer ones.
The latter reports the alsa application process ID to ladishd,
so that ladishd can associate the a2jmidid-created ports with application.
</p>
</li>
</ul></div>
<div class="paragraph"><p>See also:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="https://gitea.ladish.org/LADI/ladish">LADI/ladish at Gitea</a>
</p>
</li>
<li>
<p>
<a href="https://github.com/LADI/">LADI at GitHub</a>
</p>
</li>
<li>
<p>
<a href="https://jackdbus.ladish.org/">jackdbus</a>
</p>
</li>
<li>
<p>
<a href="https://lac.linuxaudio.org/2009/cdm/Thursday/02_Alasuutari/02.pdf">Juuso ALASUUTARI, LASH Audio Session Handler: Past, Present, and Future</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>For related discussions, you are invited to join
<a href="https://libera.chat/">Libera.Chat</a> channel #ladi</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
Last updated
2023-11-27 19:26:42 EET
</div>
</div>
</body>
</html>