Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1928 lines
90KB

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <meta name="generator" content="Asciidoctor 2.0.17">
  8. <meta name="author" content="Jonathan Moore Liles, Nils Hilbricht">
  9. <title>New Session Manager - API</title>
  10. <style>
  11. /*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
  12. /* Uncomment the following line when using as a custom stylesheet */
  13. /* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
  14. html{font-family:sans-serif;-webkit-text-size-adjust:100%}
  15. a{background:none}
  16. a:focus{outline:thin dotted}
  17. a:active,a:hover{outline:0}
  18. h1{font-size:2em;margin:.67em 0}
  19. b,strong{font-weight:bold}
  20. abbr{font-size:.9em}
  21. abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
  22. dfn{font-style:italic}
  23. hr{height:0}
  24. mark{background:#ff0;color:#000}
  25. code,kbd,pre,samp{font-family:monospace;font-size:1em}
  26. pre{white-space:pre-wrap}
  27. q{quotes:"\201C" "\201D" "\2018" "\2019"}
  28. small{font-size:80%}
  29. sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
  30. sup{top:-.5em}
  31. sub{bottom:-.25em}
  32. img{border:0}
  33. svg:not(:root){overflow:hidden}
  34. figure{margin:0}
  35. audio,video{display:inline-block}
  36. audio:not([controls]){display:none;height:0}
  37. fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
  38. legend{border:0;padding:0}
  39. button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
  40. button,input{line-height:normal}
  41. button,select{text-transform:none}
  42. button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
  43. button[disabled],html input[disabled]{cursor:default}
  44. input[type=checkbox],input[type=radio]{padding:0}
  45. button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
  46. textarea{overflow:auto;vertical-align:top}
  47. table{border-collapse:collapse;border-spacing:0}
  48. *,::before,::after{box-sizing:border-box}
  49. html,body{font-size:100%}
  50. body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
  51. a:hover{cursor:pointer}
  52. img,object,embed{max-width:100%;height:auto}
  53. object,embed{height:100%}
  54. img{-ms-interpolation-mode:bicubic}
  55. .left{float:left!important}
  56. .right{float:right!important}
  57. .text-left{text-align:left!important}
  58. .text-right{text-align:right!important}
  59. .text-center{text-align:center!important}
  60. .text-justify{text-align:justify!important}
  61. .hide{display:none}
  62. img,object,svg{display:inline-block;vertical-align:middle}
  63. textarea{height:auto;min-height:50px}
  64. select{width:100%}
  65. .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
  66. div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
  67. a{color:#2156a5;text-decoration:underline;line-height:inherit}
  68. a:hover,a:focus{color:#1d4b8f}
  69. a img{border:0}
  70. p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
  71. p aside{font-size:.875em;line-height:1.35;font-style:italic}
  72. h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
  73. h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
  74. h1{font-size:2.125em}
  75. h2{font-size:1.6875em}
  76. h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
  77. h4,h5{font-size:1.125em}
  78. h6{font-size:1em}
  79. hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
  80. em,i{font-style:italic;line-height:inherit}
  81. strong,b{font-weight:bold;line-height:inherit}
  82. small{font-size:60%;line-height:inherit}
  83. code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
  84. ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
  85. ul,ol{margin-left:1.5em}
  86. ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
  87. ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
  88. ul.square{list-style-type:square}
  89. ul.circle{list-style-type:circle}
  90. ul.disc{list-style-type:disc}
  91. ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
  92. dl dt{margin-bottom:.3125em;font-weight:bold}
  93. dl dd{margin-bottom:1.25em}
  94. blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
  95. blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
  96. @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
  97. h1{font-size:2.75em}
  98. h2{font-size:2.3125em}
  99. h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
  100. h4{font-size:1.4375em}}
  101. table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
  102. table thead,table tfoot{background:#f7f8f7}
  103. table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
  104. table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
  105. table tr.even,table tr.alt{background:#f8f8f7}
  106. table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
  107. h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
  108. h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
  109. .center{margin-left:auto;margin-right:auto}
  110. .stretch{width:100%}
  111. .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
  112. .clearfix::after,.float-group::after{clear:both}
  113. :not(pre).nobreak{word-wrap:normal}
  114. :not(pre).nowrap{white-space:nowrap}
  115. :not(pre).pre-wrap{white-space:pre-wrap}
  116. :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
  117. pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
  118. pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
  119. pre>code{display:block}
  120. pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
  121. em em{font-style:normal}
  122. strong strong{font-weight:400}
  123. .keyseq{color:rgba(51,51,51,.8)}
  124. kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
  125. .keyseq kbd:first-child{margin-left:0}
  126. .keyseq kbd:last-child{margin-right:0}
  127. .menuseq,.menuref{color:#000}
  128. .menuseq b:not(.caret),.menuref{font-weight:inherit}
  129. .menuseq{word-spacing:-.02em}
  130. .menuseq b.caret{font-size:1.25em;line-height:.8}
  131. .menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
  132. b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
  133. b.button::before{content:"[";padding:0 3px 0 2px}
  134. b.button::after{content:"]";padding:0 2px 0 3px}
  135. p a>code:hover{color:rgba(0,0,0,.9)}
  136. #header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
  137. #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
  138. #header::after,#content::after,#footnotes::after,#footer::after{clear:both}
  139. #content{margin-top:1.25em}
  140. #content::before{content:none}
  141. #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
  142. #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
  143. #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
  144. #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
  145. #header .details span:first-child{margin-left:-.125em}
  146. #header .details span.email a{color:rgba(0,0,0,.85)}
  147. #header .details br{display:none}
  148. #header .details br+span::before{content:"\00a0\2013\00a0"}
  149. #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
  150. #header .details br+span#revremark::before{content:"\00a0|\00a0"}
  151. #header #revnumber{text-transform:capitalize}
  152. #header #revnumber::after{content:"\00a0"}
  153. #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
  154. #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
  155. #toc>ul{margin-left:.125em}
  156. #toc ul.sectlevel0>li>a{font-style:italic}
  157. #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
  158. #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
  159. #toc li{line-height:1.3334;margin-top:.3334em}
  160. #toc a{text-decoration:none}
  161. #toc a:active{text-decoration:underline}
  162. #toctitle{color:#7a2518;font-size:1.2em}
  163. @media screen and (min-width:768px){#toctitle{font-size:1.375em}
  164. body.toc2{padding-left:15em;padding-right:0}
  165. #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
  166. #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
  167. #toc.toc2>ul{font-size:.9em;margin-bottom:0}
  168. #toc.toc2 ul ul{margin-left:0;padding-left:1em}
  169. #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
  170. body.toc2.toc-right{padding-left:0;padding-right:15em}
  171. body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
  172. @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
  173. #toc.toc2{width:20em}
  174. #toc.toc2 #toctitle{font-size:1.375em}
  175. #toc.toc2>ul{font-size:.95em}
  176. #toc.toc2 ul ul{padding-left:1.25em}
  177. body.toc2.toc-right{padding-left:0;padding-right:20em}}
  178. #content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
  179. #content #toc>:first-child{margin-top:0}
  180. #content #toc>:last-child{margin-bottom:0}
  181. #footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
  182. #footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
  183. #content{margin-bottom:.625em}
  184. .sect1{padding-bottom:.625em}
  185. @media screen and (min-width:768px){#content{margin-bottom:1.25em}
  186. .sect1{padding-bottom:1.25em}}
  187. .sect1:last-child{padding-bottom:0}
  188. .sect1+.sect1{border-top:1px solid #e7e7e9}
  189. #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
  190. #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
  191. #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
  192. #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
  193. #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
  194. details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
  195. details{margin-left:1.25rem}
  196. details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
  197. details>summary::-webkit-details-marker{display:none}
  198. details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
  199. details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
  200. details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
  201. .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
  202. table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
  203. .paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
  204. .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
  205. .admonitionblock>table td.icon{text-align:center;width:80px}
  206. .admonitionblock>table td.icon img{max-width:none}
  207. .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
  208. .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
  209. .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
  210. .exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
  211. .exampleblock>.content>:first-child{margin-top:0}
  212. .exampleblock>.content>:last-child{margin-bottom:0}
  213. .sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
  214. .sidebarblock>:first-child{margin-top:0}
  215. .sidebarblock>:last-child{margin-bottom:0}
  216. .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
  217. .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
  218. .literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
  219. @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
  220. @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
  221. .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
  222. .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
  223. .listingblock>.content{position:relative}
  224. .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
  225. .listingblock:hover code[data-lang]::before{display:block}
  226. .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
  227. .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
  228. .listingblock pre.highlightjs{padding:0}
  229. .listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
  230. .listingblock pre.prettyprint{border-width:0}
  231. .prettyprint{background:#f7f7f8}
  232. pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
  233. pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
  234. pre.prettyprint li code[data-lang]::before{opacity:1}
  235. pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
  236. table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
  237. table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
  238. table.linenotable td.code{padding-left:.75em}
  239. table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
  240. pre.pygments span.linenos{display:inline-block;margin-right:.75em}
  241. .quoteblock{margin:0 1em 1.25em 1.5em;display:table}
  242. .quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
  243. .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
  244. .quoteblock blockquote{margin:0;padding:0;border:0}
  245. .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
  246. .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
  247. .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
  248. .verseblock{margin:0 1em 1.25em}
  249. .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
  250. .verseblock pre strong{font-weight:400}
  251. .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
  252. .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
  253. .quoteblock .attribution br,.verseblock .attribution br{display:none}
  254. .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
  255. .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
  256. .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
  257. .quoteblock.abstract{margin:0 1em 1.25em;display:block}
  258. .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
  259. .quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
  260. .quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
  261. .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
  262. .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
  263. p.tableblock:last-child{margin-bottom:0}
  264. td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
  265. td.tableblock>.content>:last-child{margin-bottom:-1.25em}
  266. table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
  267. table.grid-all>*>tr>*{border-width:1px}
  268. table.grid-cols>*>tr>*{border-width:0 1px}
  269. table.grid-rows>*>tr>*{border-width:1px 0}
  270. table.frame-all{border-width:1px}
  271. table.frame-ends{border-width:1px 0}
  272. table.frame-sides{border-width:0 1px}
  273. table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
  274. table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
  275. table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
  276. table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
  277. table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
  278. th.halign-left,td.halign-left{text-align:left}
  279. th.halign-right,td.halign-right{text-align:right}
  280. th.halign-center,td.halign-center{text-align:center}
  281. th.valign-top,td.valign-top{vertical-align:top}
  282. th.valign-bottom,td.valign-bottom{vertical-align:bottom}
  283. th.valign-middle,td.valign-middle{vertical-align:middle}
  284. table thead th,table tfoot th{font-weight:bold}
  285. tbody tr th{background:#f7f8f7}
  286. tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
  287. p.tableblock>code:only-child{background:none;padding:0}
  288. p.tableblock{font-size:1em}
  289. ol{margin-left:1.75em}
  290. ul li ol{margin-left:1.5em}
  291. dl dd{margin-left:1.125em}
  292. dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
  293. li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
  294. ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
  295. ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
  296. ul.unstyled,ol.unstyled{margin-left:0}
  297. li>p:empty:only-child::before{content:"";display:inline-block}
  298. ul.checklist>li>p:first-child{margin-left:-1em}
  299. ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
  300. ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
  301. ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
  302. ul.inline>li{margin-left:1.25em}
  303. .unstyled dl dt{font-weight:400;font-style:normal}
  304. ol.arabic{list-style-type:decimal}
  305. ol.decimal{list-style-type:decimal-leading-zero}
  306. ol.loweralpha{list-style-type:lower-alpha}
  307. ol.upperalpha{list-style-type:upper-alpha}
  308. ol.lowerroman{list-style-type:lower-roman}
  309. ol.upperroman{list-style-type:upper-roman}
  310. ol.lowergreek{list-style-type:lower-greek}
  311. .hdlist>table,.colist>table{border:0;background:none}
  312. .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
  313. td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
  314. td.hdlist1{font-weight:bold;padding-bottom:1.25em}
  315. td.hdlist2{word-wrap:anywhere}
  316. .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
  317. .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
  318. .colist td:not([class]):first-child img{max-width:none}
  319. .colist td:not([class]):last-child{padding:.25em 0}
  320. .thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
  321. .imageblock.left{margin:.25em .625em 1.25em 0}
  322. .imageblock.right{margin:.25em 0 1.25em .625em}
  323. .imageblock>.title{margin-bottom:0}
  324. .imageblock.thumb,.imageblock.th{border-width:6px}
  325. .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
  326. .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
  327. .image.left{margin-right:.625em}
  328. .image.right{margin-left:.625em}
  329. a.image{text-decoration:none;display:inline-block}
  330. a.image object{pointer-events:none}
  331. sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
  332. sup.footnote a,sup.footnoteref a{text-decoration:none}
  333. sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
  334. #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
  335. #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
  336. #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
  337. #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
  338. #footnotes .footnote:last-of-type{margin-bottom:0}
  339. #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
  340. div.unbreakable{page-break-inside:avoid}
  341. .big{font-size:larger}
  342. .small{font-size:smaller}
  343. .underline{text-decoration:underline}
  344. .overline{text-decoration:overline}
  345. .line-through{text-decoration:line-through}
  346. .aqua{color:#00bfbf}
  347. .aqua-background{background:#00fafa}
  348. .black{color:#000}
  349. .black-background{background:#000}
  350. .blue{color:#0000bf}
  351. .blue-background{background:#0000fa}
  352. .fuchsia{color:#bf00bf}
  353. .fuchsia-background{background:#fa00fa}
  354. .gray{color:#606060}
  355. .gray-background{background:#7d7d7d}
  356. .green{color:#006000}
  357. .green-background{background:#007d00}
  358. .lime{color:#00bf00}
  359. .lime-background{background:#00fa00}
  360. .maroon{color:#600000}
  361. .maroon-background{background:#7d0000}
  362. .navy{color:#000060}
  363. .navy-background{background:#00007d}
  364. .olive{color:#606000}
  365. .olive-background{background:#7d7d00}
  366. .purple{color:#600060}
  367. .purple-background{background:#7d007d}
  368. .red{color:#bf0000}
  369. .red-background{background:#fa0000}
  370. .silver{color:#909090}
  371. .silver-background{background:#bcbcbc}
  372. .teal{color:#006060}
  373. .teal-background{background:#007d7d}
  374. .white{color:#bfbfbf}
  375. .white-background{background:#fafafa}
  376. .yellow{color:#bfbf00}
  377. .yellow-background{background:#fafa00}
  378. span.icon>.fa{cursor:default}
  379. a span.icon>.fa{cursor:inherit}
  380. .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
  381. .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
  382. .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
  383. .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
  384. .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
  385. .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
  386. .conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
  387. .conum[data-value] *{color:#fff!important}
  388. .conum[data-value]+b{display:none}
  389. .conum[data-value]::after{content:attr(data-value)}
  390. pre .conum[data-value]{position:relative;top:-.125em}
  391. b.conum *{color:inherit!important}
  392. .conum:not([data-value]):empty{display:none}
  393. dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
  394. h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
  395. p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
  396. p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
  397. p{margin-bottom:1.25rem}
  398. .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
  399. .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
  400. .print-only{display:none!important}
  401. @page{margin:1.25cm .75cm}
  402. @media print{*{box-shadow:none!important;text-shadow:none!important}
  403. html{font-size:80%}
  404. a{color:inherit!important;text-decoration:underline!important}
  405. a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
  406. a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
  407. abbr[title]{border-bottom:1px dotted}
  408. abbr[title]::after{content:" (" attr(title) ")"}
  409. pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
  410. thead{display:table-header-group}
  411. svg{max-width:100%}
  412. p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
  413. h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
  414. #header,#content,#footnotes,#footer{max-width:none}
  415. #toc,.sidebarblock,.exampleblock>.content{background:none!important}
  416. #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
  417. body.book #header{text-align:center}
  418. body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
  419. body.book #header .details{border:0!important;display:block;padding:0!important}
  420. body.book #header .details span:first-child{margin-left:0!important}
  421. body.book #header .details br{display:block}
  422. body.book #header .details br+span::before{content:none!important}
  423. body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
  424. body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
  425. .listingblock code[data-lang]::before{display:block}
  426. #footer{padding:0 .9375em}
  427. .hide-on-print{display:none!important}
  428. .print-only{display:block!important}
  429. .hide-for-print{display:none!important}
  430. .show-for-print{display:inherit!important}}
  431. @media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
  432. .sect1{padding:0!important}
  433. .sect1+.sect1{border:0}
  434. #footer{background:none}
  435. #footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
  436. @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
  437. </style>
  438. </head>
  439. <body class="article">
  440. <div id="header">
  441. <h1>New Session Manager - API</h1>
  442. <div class="details">
  443. <span id="author" class="author">Jonathan Moore Liles, Nils Hilbricht</span><br>
  444. <span id="revnumber">version API 1.1.2</span>
  445. <br><span id="revremark">License CC-By-SA v2.5</span>
  446. </div>
  447. <div id="toc" class="toc">
  448. <div id="toctitle">Table of Contents</div>
  449. <ul class="sectlevel1">
  450. <li><a href="#_client_behavior_under_session_management">1. Client Behavior Under Session Management</a>
  451. <ul class="sectlevel2">
  452. <li><a href="#_file_menu">1.1. File Menu</a>
  453. <ul class="sectlevel3">
  454. <li><a href="#_new">1.1.1. New</a></li>
  455. <li><a href="#_open">1.1.2. Open</a></li>
  456. <li><a href="#_save">1.1.3. Save</a></li>
  457. <li><a href="#_save_as">1.1.4. Save As</a></li>
  458. <li><a href="#_close_as_distinguished_from_quit_or_exit">1.1.5. Close (as distinguished from Quit or Exit)</a></li>
  459. <li><a href="#_quit_or_exit">1.1.6. Quit or Exit</a></li>
  460. </ul>
  461. </li>
  462. <li><a href="#_data_storage">1.2. Data Storage</a>
  463. <ul class="sectlevel3">
  464. <li><a href="#_internal_files">1.2.1. Internal Files</a></li>
  465. <li><a href="#_external_files">1.2.2. External Files</a></li>
  466. <li><a href="#_session_root_and_session_directories">1.2.3. Session Root and Session Directories</a>
  467. <ul class="sectlevel4">
  468. <li><a href="#_subdirectories_hierarchical_structure">1.2.3.1. Subdirectories / Hierarchical Structure</a></li>
  469. <li><a href="#_write_protection_for_session_templates">1.2.3.2. Write-Protection for Session Templates</a></li>
  470. <li><a href="#_lockfiles">1.2.3.3. Lockfiles</a></li>
  471. <li><a href="#_daemon_discovery">1.2.3.4. Daemon Discovery</a></li>
  472. </ul>
  473. </li>
  474. </ul>
  475. </li>
  476. </ul>
  477. </li>
  478. <li><a href="#_nsm_osc_protocol">2. NSM OSC Protocol</a>
  479. <ul class="sectlevel2">
  480. <li><a href="#_establishing_a_connection">2.1. Establishing a Connection</a>
  481. <ul class="sectlevel3">
  482. <li><a href="#_announce">2.1.1. Announce</a></li>
  483. <li><a href="#_response">2.1.2. Response</a></li>
  484. </ul>
  485. </li>
  486. <li><a href="#_server_to_client_control_messages">2.2. Server to Client Control Messages</a>
  487. <ul class="sectlevel3">
  488. <li><a href="#_quit">2.2.1. Quit</a></li>
  489. <li><a href="#server-to-client-control-messages-open">2.2.2. Open</a>
  490. <ul class="sectlevel4">
  491. <li><a href="#_response_2">2.2.2.1. Response</a></li>
  492. </ul>
  493. </li>
  494. <li><a href="#_save_2">2.2.3. Save</a>
  495. <ul class="sectlevel4">
  496. <li><a href="#_response_3">2.2.3.1. Response</a></li>
  497. </ul>
  498. </li>
  499. </ul>
  500. </li>
  501. <li><a href="#_server_to_client_informational_messages">2.3. Server to Client Informational Messages</a>
  502. <ul class="sectlevel3">
  503. <li><a href="#_session_is_loaded">2.3.1. Session is Loaded</a></li>
  504. <li><a href="#_show_optional_gui">2.3.2. Show Optional Gui</a></li>
  505. </ul>
  506. </li>
  507. <li><a href="#_client_to_server_informational_messages">2.4. Client to Server Informational Messages</a>
  508. <ul class="sectlevel3">
  509. <li><a href="#_optional_gui">2.4.1. Optional GUI</a></li>
  510. <li><a href="#_progress">2.4.2. Progress</a></li>
  511. <li><a href="#_dirtiness">2.4.3. Dirtiness</a></li>
  512. <li><a href="#_status_messsages">2.4.4. Status Messsages</a></li>
  513. </ul>
  514. </li>
  515. <li><a href="#_error_code_definitions">2.5. Error Code Definitions</a></li>
  516. <li><a href="#_client_to_server_control">2.6. Client to Server Control</a></li>
  517. <li><a href="#_server_control_api">2.7. Server Control API</a>
  518. <ul class="sectlevel3">
  519. <li><a href="#_client_to_client_communication">2.7.1. Client to Client Communication</a></li>
  520. </ul>
  521. </li>
  522. </ul>
  523. </li>
  524. <li><a href="#_api_versions_and_behaviour_changes">3. API Versions and Behaviour Changes</a>
  525. <ul class="sectlevel2">
  526. <li><a href="#_guidelines">3.1. Guidelines</a></li>
  527. <li><a href="#_changes_in_api_version_1_1_0">3.2. Changes in API Version 1.1.0</a></li>
  528. <li><a href="#_changes_in_api_version_1_1_1">3.3. Changes in API Version 1.1.1</a></li>
  529. <li><a href="#_changes_in_api_version_1_1_2">3.4. Changes in API Version 1.1.2</a></li>
  530. </ul>
  531. </li>
  532. </ul>
  533. </div>
  534. </div>
  535. <div id="content">
  536. <div id="preamble">
  537. <div class="sectionbody">
  538. <div class="admonitionblock important">
  539. <table>
  540. <tr>
  541. <td class="icon">
  542. <div class="title">Important</div>
  543. </td>
  544. <td class="content">
  545. "New Session Manager" is a community version of the
  546. <a href="http://non.tuxfamily.org/nsm/API.html">"Non Session Manager" by Jonathan Moore Liles</a>, who also
  547. wrote the majority of this API document, especially the API itself. <strong>The API is the same</strong>. Any
  548. technical changes or differences in behaviour are described in <a href="#_api_versions_and_behaviour_changes">API Versions and Behaviour Changes</a>.
  549. All other changes to this document can be reviewed by accessing the git log. This document is
  550. licensed under CC-By-Sa v2.5. See <a href="https://github.com/jackaudio/new-session-manager/tree/master/docs/src/api">LICENSE</a>
  551. </td>
  552. </tr>
  553. </table>
  554. </div>
  555. <div class="admonitionblock important">
  556. <table>
  557. <tr>
  558. <td class="icon">
  559. <div class="title">Important</div>
  560. </td>
  561. <td class="content">
  562. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
  563. NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
  564. described in <a href="https://tools.ietf.org/html/rfc2119">RFC 2119</a>.
  565. </td>
  566. </tr>
  567. </table>
  568. </div>
  569. <div class="paragraph">
  570. <p>The "New Session Manager"-API is used by many music and audio programs in Linux distributions
  571. to allow any number of independent programs to be managed together as part of a logical session
  572. (i.e. a song). Thus, operations such as loading and saving are synchronized.</p>
  573. </div>
  574. <div class="paragraph">
  575. <p>The API comprises a simple Open Sound Control (OSC) based protocol, along with some behavioral
  576. guidelines, which can easily be implemented by various applications.</p>
  577. </div>
  578. <div class="paragraph">
  579. <p>This project contains a program called <code>nsmd</code> which is an implementation of the server side of
  580. the NSM API. <code>nsmd</code> can be controlled by direct OSC messages, or (more commonly) a GUI:
  581. Included in this package is the <code>nsm-legacy-gui</code>, which gets symlinked to "non-session-manager`.
  582. Another GUI is "Agordejo". Other applications exist that (partially) support the NSM API and are able
  583. to load clients, but they do not use the New-Session-Manager (or Non-Session-Manager) implementation
  584. and are therefore out of scope for this document.</p>
  585. </div>
  586. <div class="paragraph">
  587. <p>However, the same server-side API can also be implemented by other programs (such as Carla),
  588. although consistency and robustness will likely suffer if non-NSM compliant clients are allowed to
  589. participate in a session.</p>
  590. </div>
  591. <div class="paragraph">
  592. <p>There is no direct dependency for client implementations, as long as they
  593. can send and receive OSC.
  594. Some clients use <code>liblo</code> (the OSC library), which becomes a dependency if you choose to implement
  595. NSM-support with the provided header file <code>nsm.h</code> (<code>extras/nsm.h/nsm.h</code> in the git repository).
  596. Some clients use the provided single-file python library <code>pynsm</code> (<code>extras/pynsm/nsmclient.py</code> in the git repository)
  597. which has no dependencies outside the Python3 standard library.</p>
  598. </div>
  599. <div class="paragraph">
  600. <p>The aim of this project is to thoroughly define the behavior required of clients. Often the
  601. difficulty with other session-management approaches has been not in implementing code-support for
  602. them, but in not defining rules and behaviour clearly enough.</p>
  603. </div>
  604. <div class="paragraph">
  605. <p>As written above unambiguous rules are created by using RFC 2119 in this document. For the good of
  606. the user, these rules are meant to be followed and are non-negotiable. If an application does not
  607. conform to this specification it should be considered broken. Consistency across applications under
  608. session management is very important for a good user experience.</p>
  609. </div>
  610. </div>
  611. </div>
  612. <div class="sect1">
  613. <h2 id="_client_behavior_under_session_management">1. Client Behavior Under Session Management</h2>
  614. <div class="sectionbody">
  615. <div class="paragraph">
  616. <p>Most graphical applications make available to the user a common set of file operations, typically
  617. presented under a File or Project menu.</p>
  618. </div>
  619. <div class="paragraph">
  620. <p>These are: New, Open, Save, Save As, Close and Quit or Exit.</p>
  621. </div>
  622. <div class="paragraph">
  623. <p>The following sub-sections describe how these options should behave when the application is part of
  624. an NSM session. These rules only apply when session management is active, that is, after the
  625. <code>announce</code> handshake described in the <a href="#_nsm_osc_protocol">NSM OSC Protocol</a> section. In order to provide a
  626. consistent and predictable user experience, it is critically important for applications to adhere
  627. to these guidelines.</p>
  628. </div>
  629. <div class="sect2">
  630. <h3 id="_file_menu">1.1. File Menu</h3>
  631. <div class="sect3">
  632. <h4 id="_new">1.1.1. New</h4>
  633. <div class="paragraph">
  634. <p>This option MAY empty/reset the current file or project (possibly after user confirmation).
  635. It MUST NOT allow the user to create a new project/file in another location.</p>
  636. </div>
  637. </div>
  638. <div class="sect3">
  639. <h4 id="_open">1.1.2. Open</h4>
  640. <div class="paragraph">
  641. <p>This option MUST be disabled.</p>
  642. </div>
  643. <div class="paragraph">
  644. <p>The application MAY elect to implement an option called "Import into Session", which creates a
  645. copy of a file/project which is then saved at the session path provided by NSM.</p>
  646. </div>
  647. </div>
  648. <div class="sect3">
  649. <h4 id="_save">1.1.3. Save</h4>
  650. <div class="paragraph">
  651. <p>This option should behave as normal, saving the current file/project as established by the NSM
  652. <code>open</code> message.</p>
  653. </div>
  654. <div class="paragraph">
  655. <p>This option MUST NOT present the user with a choice of where to save the file.</p>
  656. </div>
  657. </div>
  658. <div class="sect3">
  659. <h4 id="_save_as">1.1.4. Save As</h4>
  660. <div class="paragraph">
  661. <p>This option MUST be disabled.</p>
  662. </div>
  663. <div class="paragraph">
  664. <p>The application MAY elect to implement an option called 'Export from Session', which
  665. creates a copy of the current file/project which is then saved in a user-specified location outside
  666. of the session path provided by NSM.</p>
  667. </div>
  668. </div>
  669. <div class="sect3">
  670. <h4 id="_close_as_distinguished_from_quit_or_exit">1.1.5. Close (as distinguished from Quit or Exit)</h4>
  671. <div class="paragraph">
  672. <p>This option MUST be disabled unless its meaning is to disconnect the application from session
  673. management.</p>
  674. </div>
  675. </div>
  676. <div class="sect3">
  677. <h4 id="_quit_or_exit">1.1.6. Quit or Exit</h4>
  678. <div class="paragraph">
  679. <p>This option MAY behave as normal (possibly asking the user to confirm exiting), or MAY do nothing
  680. to only allow quit from the session-manager control.
  681. When the client supports :optional-gui: this option SHOULD be replaced with hiding the client&#8217;s GUI
  682. so a quit by window manager hides.</p>
  683. </div>
  684. </div>
  685. </div>
  686. <div class="sect2">
  687. <h3 id="_data_storage">1.2. Data Storage</h3>
  688. <div class="sect3">
  689. <h4 id="_internal_files">1.2.1. Internal Files</h4>
  690. <div class="paragraph">
  691. <p>All project specific data created by a client MUST be stored in the per-client storage area
  692. provided by NSM. This includes all recorded audio and MIDI files, snapshots, etc. Only global
  693. configuration items, exports, and renders of the project may be stored elsewhere (wherever the user
  694. specifies).</p>
  695. </div>
  696. </div>
  697. <div class="sect3">
  698. <h4 id="_external_files">1.2.2. External Files</h4>
  699. <div class="paragraph">
  700. <p>Files required by the project but external to it (typically read-only data such as audio samples)
  701. SHOULD be referenced by creating a symbolic link within the assigned session area, and then
  702. referring to the symlink. This allows sessions to be archived and transported simply (e.g. with
  703. "tar -h") by tools that have no knowledge of the project formats of the various clients in the
  704. session. The symlinks thus created should, at the very least, be named after the files they refer
  705. to. Some unique component may be required to prevent collisions.</p>
  706. </div>
  707. </div>
  708. <div class="sect3">
  709. <h4 id="_session_root_and_session_directories">1.2.3. Session Root and Session Directories</h4>
  710. <div class="paragraph">
  711. <p>Client programs MUST NOT handle the following themselves. This section is background-information.</p>
  712. </div>
  713. <div class="paragraph">
  714. <p>NSM follows the <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG Base Directory Specifications</a></p>
  715. </div>
  716. <div class="paragraph">
  717. <p>All existing and new sessions are directories below the session-root, which defaults to
  718. <code>$XDG_DATA_HOME/nsm/</code>, which usually results in <code>$HOME/.local/share/nsm/</code>.</p>
  719. </div>
  720. <div class="paragraph">
  721. <p>Each session directory contains a file <code>session.nsm</code> with one client per line <code>name:executable:UID\n</code>
  722. For example:</p>
  723. </div>
  724. <div class="listingblock">
  725. <div class="content">
  726. <pre class="highlight"><code>JACKPatch:jackpatch:nBEIQ
  727. jack_mixer:jack_mixer:nTXHV
  728. Carla-Rack:carla-rack:nFAOD</code></pre>
  729. </div>
  730. </div>
  731. <div class="paragraph">
  732. <p><code>nsmd</code> loads and saves this file, client names are their self-reported names.
  733. The file format is final and frozen. Additions or changes SHALL NOT be made.</p>
  734. </div>
  735. <div class="sect4">
  736. <h5 id="_subdirectories_hierarchical_structure">1.2.3.1. Subdirectories / Hierarchical Structure</h5>
  737. <div class="paragraph">
  738. <p>Subdirectories MAY be made to organize sessions into meaningful structures, such as album/track or
  739. composer/genre/piece. For example: <code>Johann Sebastian Bach/Kantaten/Wie schön leuchtet der Morgenstern</code>.
  740. Which results in the same directory structure on disk. Session names can contain any characters that
  741. are supported by the underlying file system, usually UTF-8.</p>
  742. </div>
  743. <div class="paragraph">
  744. <p>Subdirectories are created by either <code>nsmd</code> itself or by the users themselves, through their file
  745. manager or a GUI (while the session is not open).</p>
  746. </div>
  747. <div class="paragraph">
  748. <p>The project_name from <code>/nsm/server/new s:project_name</code> accepts the format <code>a/b/c/d</code>.</p>
  749. </div>
  750. <div class="paragraph">
  751. <p>Any session itself MUST be a "leaf" in this directory tree. A session MUST NOT contain further
  752. session subdirectories: any directory that contains a file <code>session.nsm</code> is the final
  753. element in the hierarchy.</p>
  754. </div>
  755. </div>
  756. <div class="sect4">
  757. <h5 id="_write_protection_for_session_templates">1.2.3.2. Write-Protection for Session Templates</h5>
  758. <div class="paragraph">
  759. <p>Write protection for a whole session directory can either happen by "accident" (files from
  760. another user, a network mount etc.) or on purpose, to protect a session template against accidental
  761. changes. The latter is possible with a recursive <code>chown</code>, <code>chmod</code> or <code>chattr -R +i session-dir</code>.</p>
  762. </div>
  763. <div class="paragraph">
  764. <p>nsmd itself just checks if <code>session.nsm</code> is read-only. In this case it will not send the save
  765. command to it&#8217;s session clients. This does not prevent hypothetical problems when the user
  766. triggers a clients internal save command in a write protected directory. Clients SHOULD handle
  767. their write protected save files themselves.</p>
  768. </div>
  769. <div class="paragraph">
  770. <p>Advanced contraptions, like overlay filesystems or copy-on-write hardlinks to create read-only
  771. sessions without the clients noticing, are out of scope for nsm.</p>
  772. </div>
  773. </div>
  774. <div class="sect4">
  775. <h5 id="_lockfiles">1.2.3.3. Lockfiles</h5>
  776. <div class="paragraph">
  777. <p>Because multiple <code>nsmd</code> can run at the same time we need to prevent accidental write-access to the
  778. same session by different nsm-daemons, and subsequently GUIs.</p>
  779. </div>
  780. <div class="paragraph">
  781. <p>Therefore each currently open session creates a lockfile under <code>$XDG_RUNTIME_DIR/nsm/</code> (usually
  782. <code>/run/user/XXXX/nsm/</code>) that tells <code>nsmd</code> to not open such a locked session. This directory gets
  783. cleaned by the operating system, preventing sessions to stay locked after e.g. a power failure.</p>
  784. </div>
  785. <div class="paragraph">
  786. <p>The lockfile is named after the simple session name combined with a numeric ID for the session
  787. root. It is possible that two <code>nsmd</code> opened two different session roots, both with the same simple
  788. session name, e.g. "my song". Lockfiles are able to distinguish between those and will not prevent
  789. access in this scenario. The numeric ID is a djb2 hash modulo (%) 65521 of the session root directory
  790. (see <code>src/file.cpp</code> function <code>simple_hash()</code>).</p>
  791. </div>
  792. <div class="paragraph">
  793. <p>The lockfile contains, on separate lines:</p>
  794. </div>
  795. <div class="ulist">
  796. <ul>
  797. <li>
  798. <p>The absolute path to the session, including the root-dir, which could be overriden by <code>nsmd --session-root</code>, allowing two sessions of the same basic name in different roots.</p>
  799. </li>
  800. <li>
  801. <p>the OSC URL of the server that runs this session, the same as <code>$NSM_URL</code>.</p>
  802. </li>
  803. <li>
  804. <p>the PID of <code>nsmd</code></p>
  805. </li>
  806. </ul>
  807. </div>
  808. <div class="paragraph">
  809. <p>Example:</p>
  810. </div>
  811. <div class="listingblock">
  812. <div class="content">
  813. <pre class="highlight"><code>/home/johann/.local/share/nsm/cantatas/easter1751
  814. osc.udp://myuser.localdomain:11287/
  815. 3022</code></pre>
  816. </div>
  817. </div>
  818. </div>
  819. <div class="sect4">
  820. <h5 id="_daemon_discovery">1.2.3.4. Daemon Discovery</h5>
  821. <div class="paragraph">
  822. <p>Each running <code>nsmd</code>, per user, creates a state file under <code>$XDG_RUNTIME_DIR/nsm/d/</code> (usually
  823. <code>/run/user/XXXX/nsm/d/</code>) that can be used to look up running daemons, even if no session is loaded.
  824. The name of the file is <code>nsmd</code> PID and the files contain their daemons osc.udp URL that is
  825. compatible with the --nsm-url parameter of the GUI.</p>
  826. </div>
  827. <div class="paragraph">
  828. <p>This enables you to e.g. start nsmd at boot with a random free port. Server-control programs such
  829. as GUIs can then use this to look for running servers without requiring the user to look up and
  830. input an osc URL manually as command line parameter.</p>
  831. </div>
  832. </div>
  833. </div>
  834. </div>
  835. </div>
  836. </div>
  837. <div class="sect1">
  838. <h2 id="_nsm_osc_protocol">2. NSM OSC Protocol</h2>
  839. <div class="sectionbody">
  840. <div class="paragraph">
  841. <p>All message parameters are REQUIRED. All messages MUST be sent from the same socket as the <code>announce</code>
  842. message, using the <code>lo_send_from</code> method of liblo or its equivalent, as the server uses the return
  843. addresses to distinguish between clients.</p>
  844. </div>
  845. <div class="paragraph">
  846. <p>Clients MUST create thier OSC servers using the same protocol (UDP,TCP) as found in <code>NSM_URL</code>.
  847. <code>nsmd</code> itself is using UDP only.</p>
  848. </div>
  849. <div class="sect2">
  850. <h3 id="_establishing_a_connection">2.1. Establishing a Connection</h3>
  851. <div class="sect3">
  852. <h4 id="_announce">2.1.1. Announce</h4>
  853. <div class="paragraph">
  854. <p>At launch, the client MUST check the environment for the value of <code>NSM_URL</code>. If present, the client
  855. MUST send the following message to the provided address as soon as it is ready to respond to the
  856. <code>/nsm/client/open</code> event:</p>
  857. </div>
  858. <div class="listingblock">
  859. <div class="content">
  860. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/server/announce s:application_name s:capabilities s:executable_name i:api_version_major i:api_version_minor i:pid</code></pre>
  861. </div>
  862. </div>
  863. <div class="paragraph">
  864. <p>If <code>NSM_URL</code> is undefined, invalid, or unreachable, then the client should proceed assuming that
  865. session management is unavailable.</p>
  866. </div>
  867. <div class="paragraph">
  868. <p><code>api_version_major</code> and <code>api_version_minor</code> must be the two parts of the version number of the NSM API
  869. as defined by this document.</p>
  870. </div>
  871. <div class="paragraph">
  872. <p>Note that if the application intends to register JACK clients, <code>application_name</code> MUST be the same as
  873. the name that would normally be passed to <code>jack_client_open</code>. For example, Non-Mixer sends
  874. "Non-Mixer" as its <code>application_name</code>. Applications MUST NOT register their JACK clients until
  875. receiving an <code>open</code> message; the <code>open</code> message will provide a unique client name prefix suitable for
  876. passing to JACK. This is probably the most complex requirement of the NSM API, but it isn&#8217;t
  877. difficult to implement, especially if the application simply wishes to delay its initialization
  878. process briefly while awaiting the <code>announce</code> reply and subsequent <code>open</code> message.</p>
  879. </div>
  880. <div class="paragraph">
  881. <p><code>capabilities</code> MUST be a string containing a colon separated list of the special capabilities the
  882. client possesses. e.g. <code>:dirty:switch:progress:</code></p>
  883. </div>
  884. <div class="paragraph">
  885. <p><code>executable_name</code> MUST be the executable name that the program was launched with. For C programs,
  886. this is simply the value of <code>argv[0]</code>. Note that hardcoding the name of the program here is not the
  887. same as using, as the user may have launched the program from a script with a different name using
  888. exec, or have created a symlink to the program. Getting the correct value in scripting languages
  889. like Python can be more challenging.</p>
  890. </div>
  891. <table class="tableblock frame-all grid-all stripes-even stretch">
  892. <caption class="title">Table 1. Available Client Capabilities</caption>
  893. <colgroup>
  894. <col style="width: 50%;">
  895. <col style="width: 50%;">
  896. </colgroup>
  897. <thead>
  898. <tr>
  899. <th class="tableblock halign-left valign-top">Name</th>
  900. <th class="tableblock halign-left valign-top">Description</th>
  901. </tr>
  902. </thead>
  903. <tbody>
  904. <tr>
  905. <td class="tableblock halign-left valign-top"><p class="tableblock">switch</p></td>
  906. <td class="tableblock halign-left valign-top"><p class="tableblock">client is capable of responding to multiple <code>open</code> messages without restarting</p></td>
  907. </tr>
  908. <tr>
  909. <td class="tableblock halign-left valign-top"><p class="tableblock">dirty</p></td>
  910. <td class="tableblock halign-left valign-top"><p class="tableblock">client knows when it has unsaved changes</p></td>
  911. </tr>
  912. <tr>
  913. <td class="tableblock halign-left valign-top"><p class="tableblock">progress</p></td>
  914. <td class="tableblock halign-left valign-top"><p class="tableblock">client can send progress updates during time-consuming operations</p></td>
  915. </tr>
  916. <tr>
  917. <td class="tableblock halign-left valign-top"><p class="tableblock">message</p></td>
  918. <td class="tableblock halign-left valign-top"><p class="tableblock">client can send textual status updates</p></td>
  919. </tr>
  920. <tr>
  921. <td class="tableblock halign-left valign-top"><p class="tableblock">optional-gui</p></td>
  922. <td class="tableblock halign-left valign-top"><p class="tableblock">client has an optional GUI</p></td>
  923. </tr>
  924. </tbody>
  925. </table>
  926. </div>
  927. <div class="sect3">
  928. <h4 id="_response">2.1.2. Response</h4>
  929. <div class="paragraph">
  930. <p>The server will respond to the client&#8217;s announce message with the following message:</p>
  931. </div>
  932. <div class="listingblock">
  933. <div class="content">
  934. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/reply "/nsm/server/announce" s:message s:name_of_session_manager s:capabilities</code></pre>
  935. </div>
  936. </div>
  937. <div class="paragraph">
  938. <p><code>message</code> is a welcome message.</p>
  939. </div>
  940. <div class="paragraph">
  941. <p>The value of <code>name_of_session_manager</code> will depend on the implementation of the NSM server. It
  942. might say "New Session Manager", or it might say "Non Session Manager" etc. This is for display to
  943. the user.</p>
  944. </div>
  945. <div class="paragraph">
  946. <p><code>capabilities</code> will be a string containing a colon separated list of special server capabilities.</p>
  947. </div>
  948. <div class="paragraph">
  949. <p>Presently, the server <code>capabilities</code> are:</p>
  950. </div>
  951. <table class="tableblock frame-all grid-all stripes-even stretch">
  952. <caption class="title">Table 2. Available Server Capabilities</caption>
  953. <colgroup>
  954. <col style="width: 50%;">
  955. <col style="width: 50%;">
  956. </colgroup>
  957. <thead>
  958. <tr>
  959. <th class="tableblock halign-left valign-top">Name</th>
  960. <th class="tableblock halign-left valign-top">Description</th>
  961. </tr>
  962. </thead>
  963. <tbody>
  964. <tr>
  965. <td class="tableblock halign-left valign-top"><p class="tableblock">server-control</p></td>
  966. <td class="tableblock halign-left valign-top"><p class="tableblock">client-to-server control</p></td>
  967. </tr>
  968. <tr>
  969. <td class="tableblock halign-left valign-top"><p class="tableblock">broadcast</p></td>
  970. <td class="tableblock halign-left valign-top"><p class="tableblock">server responds to /nsm/server/broadcast message</p></td>
  971. </tr>
  972. <tr>
  973. <td class="tableblock halign-left valign-top"><p class="tableblock">optional-gui</p></td>
  974. <td class="tableblock halign-left valign-top"><p class="tableblock">server responds to optional-gui messages. This capability is always present and MUST be supported by any server implementation.</p></td>
  975. </tr>
  976. </tbody>
  977. </table>
  978. <div class="paragraph">
  979. <p>A client should not consider itself to be under session management until it receives this response.
  980. For example, the Non applications activate their "SM" blinkers at this time.</p>
  981. </div>
  982. <div class="paragraph">
  983. <p>If there is an error, a reply of the following form will be sent to the client:</p>
  984. </div>
  985. <div class="listingblock">
  986. <div class="content">
  987. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/error "/nsm/server/announce" i:error_code s:error_message</code></pre>
  988. </div>
  989. </div>
  990. <div class="paragraph">
  991. <p>The following table defines possible values of <code>error_code</code>:</p>
  992. </div>
  993. <table class="tableblock frame-all grid-all stripes-even stretch">
  994. <caption class="title">Table 3. Response codes</caption>
  995. <colgroup>
  996. <col style="width: 50%;">
  997. <col style="width: 50%;">
  998. </colgroup>
  999. <thead>
  1000. <tr>
  1001. <th class="tableblock halign-left valign-top">Code</th>
  1002. <th class="tableblock halign-left valign-top">Meaning</th>
  1003. </tr>
  1004. </thead>
  1005. <tbody>
  1006. <tr>
  1007. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_GENERAL</p></td>
  1008. <td class="tableblock halign-left valign-top"><p class="tableblock">General Error</p></td>
  1009. </tr>
  1010. <tr>
  1011. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_INCOMPATIBLE_API</p></td>
  1012. <td class="tableblock halign-left valign-top"><p class="tableblock">Incompatible API version</p></td>
  1013. </tr>
  1014. <tr>
  1015. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_BLACKLISTED</p></td>
  1016. <td class="tableblock halign-left valign-top"><p class="tableblock">Client has been blacklisted.</p></td>
  1017. </tr>
  1018. </tbody>
  1019. </table>
  1020. </div>
  1021. </div>
  1022. <div class="sect2">
  1023. <h3 id="_server_to_client_control_messages">2.2. Server to Client Control Messages</h3>
  1024. <div class="paragraph">
  1025. <p>Compliant clients MUST accept the client control messages described in this section. All client
  1026. control messages REQUIRE a response. Responses MUST be delivered back to the sender (<code>nsmd</code>) from the
  1027. same socket used by the client in its <code>announce</code> message (by using <code>lo_send_from</code>) AFTER the action has
  1028. been completed or if an error is encountered. The required response is described in the subsection
  1029. for each message.</p>
  1030. </div>
  1031. <div class="paragraph">
  1032. <p>If there is an error and the action cannot be completed, then <code>error_code</code> MUST be set to a valid
  1033. error code (see <a href="#_error_code_definitions">Error Code Definitions</a>) and <code>message</code> to a string describing the problem
  1034. (suitable for display to the user).</p>
  1035. </div>
  1036. <div class="paragraph">
  1037. <p>The reply can take one of the following two forms, where path MUST be the <code>path</code> of the message being
  1038. replied to (e.g. "nsm/client/save":</p>
  1039. </div>
  1040. <div class="listingblock">
  1041. <div class="content">
  1042. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/reply s:path s:message</code></pre>
  1043. </div>
  1044. </div>
  1045. <div class="listingblock">
  1046. <div class="content">
  1047. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/error s:path i:error_code s:message</code></pre>
  1048. </div>
  1049. </div>
  1050. <div class="sect3">
  1051. <h4 id="_quit">2.2.1. Quit</h4>
  1052. <div class="paragraph">
  1053. <p>There is no message for this. Clients will receive the Unix SIGTERM signal and MUST close cleanly
  1054. IMMEDIATELY, without displaying any kind of dialog to the user and regardless of whether or not
  1055. unsaved changes would be lost. When a session is closed the application will receive this signal
  1056. soon after having responded to a <code>save</code> message.</p>
  1057. </div>
  1058. </div>
  1059. <div class="sect3">
  1060. <h4 id="server-to-client-control-messages-open">2.2.2. Open</h4>
  1061. <div class="listingblock">
  1062. <div class="content">
  1063. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/open s:path_to_instance_specific_project s:display_name s:client_id</code></pre>
  1064. </div>
  1065. </div>
  1066. <div class="paragraph">
  1067. <p><code>path_to_instance_specific_project</code> is a path name in the form client_name.ID, assigned to the
  1068. client for storing its project data. The client MUST choose one of the four strategies below to
  1069. save, so that every file in the session can be traced back to a client and, vice versa, a client
  1070. name.ID can be used to look up all its files. (For example to clean up the session dir)</p>
  1071. </div>
  1072. <div class="ulist">
  1073. <ul>
  1074. <li>
  1075. <p>The client has no state and does not save at all</p>
  1076. <div class="ulist">
  1077. <ul>
  1078. <li>
  1079. <p>and it MUST NOT misuse e.g. ~/.config to save session specific information e.g. synth-instrument settings</p>
  1080. </li>
  1081. </ul>
  1082. </div>
  1083. </li>
  1084. <li>
  1085. <p>The client may use the path client_name.ID directly, resulting in a file client_name.ID in the session directory</p>
  1086. </li>
  1087. <li>
  1088. <p>The client may append its native file extension (e.g. <code>.json</code>) to the path client_name.ID</p>
  1089. </li>
  1090. <li>
  1091. <p>The client may use the path as directory, creating arbitrary files below, for example recorded .wav.</p>
  1092. <div class="ulist">
  1093. <ul>
  1094. <li>
  1095. <p>and it MUST NOT use the client ID below this point. This way the data stays transferable by hand to another client instance (in another session).</p>
  1096. </li>
  1097. <li>
  1098. <p>best case practice is to always use the same file names, for example <code>client_name.ID/savefile.json</code></p>
  1099. </li>
  1100. </ul>
  1101. </div>
  1102. </li>
  1103. </ul>
  1104. </div>
  1105. <div class="paragraph">
  1106. <p>If a project exists at the path, the client MUST immediately open it.</p>
  1107. </div>
  1108. <div class="paragraph">
  1109. <p>If a project does not exist at the path, then the client MUST immediately create and open a new one
  1110. at the specified path or, for clients which hold all their state in memory, store the path for
  1111. later use when responding to the <code>save</code> message.</p>
  1112. </div>
  1113. <div class="paragraph">
  1114. <p>No file or directory will be created at the specified path by the server. It is up to the client to
  1115. create what it needs.</p>
  1116. </div>
  1117. <div class="paragraph">
  1118. <p>For clients which HAVE NOT specified the <code>:switch:</code> capability, the <code>open</code> message will only be
  1119. delivered once, immediately following the <code>announce</code> response.</p>
  1120. </div>
  1121. <div class="paragraph">
  1122. <p>For clients which HAVE specified the <code>:switch:</code> capability, the client MUST immediately switch to the
  1123. specified project or create a new one if it doesn&#8217;t exist.</p>
  1124. </div>
  1125. <div class="paragraph">
  1126. <p>Clients which are incapable of switching projects or are prone to crashing upon switching MUST NOT
  1127. include <code>:switch:</code> in their capability string.</p>
  1128. </div>
  1129. <div class="paragraph">
  1130. <p>If the user the is allowed to run two or more instances of the application simultaneously
  1131. then such an application MUST PRE-PEND the provided <code>client_id</code> string, followed by "/", to any
  1132. names it registers with common subsystems (e.g. JACK client names). This ensures that multiple
  1133. instances of the same application can be restored in any order without scrambling the JACK
  1134. connections or causing other conflicts.</p>
  1135. </div>
  1136. <div class="paragraph">
  1137. <p>The provided <code>client_id</code> will be a concatenation of the value of <code>application_name</code> sent by the
  1138. client in its <code>announce</code> message and a unique identifier.</p>
  1139. </div>
  1140. <div class="paragraph">
  1141. <p>Therefore, applications which create single JACK clients can use the value of <code>client_id</code> directly
  1142. as their JACK client name.</p>
  1143. </div>
  1144. <div class="paragraph">
  1145. <p>Applications which register multiple JACK clients (e.g. Carla or Non-Mixer) MUST PRE-PEND
  1146. <code>client_id</code> value, followed by "/", to the client names they register with JACK and the application
  1147. determined part MUST be unique for that (JACK) client.</p>
  1148. </div>
  1149. <div class="paragraph">
  1150. <p>For example, Carla is a plugin-host that loads each plugin as JACK client.
  1151. Suitable JACK client names are: <code>carla-jack-multi.nBAF/ZynAddSubFx</code> or <code>carla-jack-multi.nBAF/Helm</code>
  1152. Please note that ZynAddSubFx and Helm are <strong>not ports</strong> but clients. Each of them can have any number
  1153. of audio and midi ports below them.</p>
  1154. </div>
  1155. <div class="paragraph">
  1156. <p>Note that this means that the application MUST NOT register with JACK (or any
  1157. other subsystem requiring unique names) until it receives an <code>open</code> message from NSM. Likewise,
  1158. applications with the <code>:switch:</code> capability should close their JACK clients and re-create them with
  1159. using the new <code>client_id</code> (renaming JACK-clients is not possible, only ports).</p>
  1160. </div>
  1161. <div class="paragraph">
  1162. <p>A response is REQUIRED as soon as the open operation has been completed. Ongoing progress MAY be
  1163. indicated by sending messages to <code>/nsm/client/progress</code>.</p>
  1164. </div>
  1165. <div class="sect4">
  1166. <h5 id="_response_2">2.2.2.1. Response</h5>
  1167. <div class="paragraph">
  1168. <p>The client MUST respond to the 'open' message with:</p>
  1169. </div>
  1170. <div class="listingblock">
  1171. <div class="content">
  1172. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/reply "/nsm/client/open" s:message</code></pre>
  1173. </div>
  1174. </div>
  1175. <div class="paragraph">
  1176. <p>Or</p>
  1177. </div>
  1178. <div class="listingblock">
  1179. <div class="content">
  1180. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/error "/nsm/client/open" i:error_code s:message</code></pre>
  1181. </div>
  1182. </div>
  1183. <table class="tableblock frame-all grid-all stripes-even stretch">
  1184. <caption class="title">Table 4. Response codes</caption>
  1185. <colgroup>
  1186. <col style="width: 50%;">
  1187. <col style="width: 50%;">
  1188. </colgroup>
  1189. <thead>
  1190. <tr>
  1191. <th class="tableblock halign-left valign-top">Code</th>
  1192. <th class="tableblock halign-left valign-top">Meaning</th>
  1193. </tr>
  1194. </thead>
  1195. <tbody>
  1196. <tr>
  1197. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR</p></td>
  1198. <td class="tableblock halign-left valign-top"><p class="tableblock">General Error</p></td>
  1199. </tr>
  1200. <tr>
  1201. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_BAD_PROJECT</p></td>
  1202. <td class="tableblock halign-left valign-top"><p class="tableblock">An existing project file was found to be corrupt</p></td>
  1203. </tr>
  1204. <tr>
  1205. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_CREATE_FAILED</p></td>
  1206. <td class="tableblock halign-left valign-top"><p class="tableblock">A new project could not be created</p></td>
  1207. </tr>
  1208. <tr>
  1209. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_UNSAVED_CHANGES</p></td>
  1210. <td class="tableblock halign-left valign-top"><p class="tableblock">Unsaved changes would be lost</p></td>
  1211. </tr>
  1212. <tr>
  1213. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NOT_NOW</p></td>
  1214. <td class="tableblock halign-left valign-top"><p class="tableblock">Operation cannot be completed at this time</p></td>
  1215. </tr>
  1216. </tbody>
  1217. </table>
  1218. </div>
  1219. </div>
  1220. <div class="sect3">
  1221. <h4 id="_save_2">2.2.3. Save</h4>
  1222. <div class="listingblock">
  1223. <div class="content">
  1224. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/save</code></pre>
  1225. </div>
  1226. </div>
  1227. <div class="paragraph">
  1228. <p>This message will only be delivered after a previous <code>open</code> message, and may be sent any number of
  1229. times within the course of a session (including zero, if the user aborts the session).</p>
  1230. </div>
  1231. <div class="sect4">
  1232. <h5 id="_response_3">2.2.3.1. Response</h5>
  1233. <div class="listingblock">
  1234. <div class="content">
  1235. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/reply "/nsm/client/save" s:message</code></pre>
  1236. </div>
  1237. </div>
  1238. <div class="paragraph">
  1239. <p>Or</p>
  1240. </div>
  1241. <div class="listingblock">
  1242. <div class="content">
  1243. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/error "/nsm/client/save" i:error_code s:message</code></pre>
  1244. </div>
  1245. </div>
  1246. <table class="tableblock frame-all grid-all stripes-even stretch">
  1247. <caption class="title">Table 5. Response codes</caption>
  1248. <colgroup>
  1249. <col style="width: 50%;">
  1250. <col style="width: 50%;">
  1251. </colgroup>
  1252. <thead>
  1253. <tr>
  1254. <th class="tableblock halign-left valign-top">Code</th>
  1255. <th class="tableblock halign-left valign-top">Meaning</th>
  1256. </tr>
  1257. </thead>
  1258. <tbody>
  1259. <tr>
  1260. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR</p></td>
  1261. <td class="tableblock halign-left valign-top"><p class="tableblock">General Error</p></td>
  1262. </tr>
  1263. <tr>
  1264. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_SAVE_FAILED</p></td>
  1265. <td class="tableblock halign-left valign-top"><p class="tableblock">Project could not be saved</p></td>
  1266. </tr>
  1267. <tr>
  1268. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NOT_NOW</p></td>
  1269. <td class="tableblock halign-left valign-top"><p class="tableblock">Operation cannot be completed at this time</p></td>
  1270. </tr>
  1271. </tbody>
  1272. </table>
  1273. </div>
  1274. </div>
  1275. </div>
  1276. <div class="sect2">
  1277. <h3 id="_server_to_client_informational_messages">2.3. Server to Client Informational Messages</h3>
  1278. <div class="sect3">
  1279. <h4 id="_session_is_loaded">2.3.1. Session is Loaded</h4>
  1280. <div class="paragraph">
  1281. <p>Accepting this message is optional. The intent is to signal to clients which may have some
  1282. interdependence (say, peer to peer OSC connections) that the session is fully loaded and all their
  1283. peers are available. Most clients will not need to act on this message. This message has no meaning
  1284. when a session is being built or run; only when it is initially loaded. Clients who intend to act
  1285. on this message MUST NOT do so by delaying initialization waiting for it.</p>
  1286. </div>
  1287. <div class="listingblock">
  1288. <div class="content">
  1289. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/session_is_loaded</code></pre>
  1290. </div>
  1291. </div>
  1292. <div class="paragraph">
  1293. <p>This message does not require a response.</p>
  1294. </div>
  1295. </div>
  1296. <div class="sect3">
  1297. <h4 id="_show_optional_gui">2.3.2. Show Optional Gui</h4>
  1298. <div class="paragraph">
  1299. <p>If the client has specified the <code>optional-gui</code> capability, then it may receive this message from the
  1300. server when the user wishes to change the visibility state of the GUI. It doesn&#8217;t matter if the
  1301. optional GUI is integrated with the program or if it is a separate program \(as is the case with
  1302. SooperLooper\). When the GUI is hidden, there should be no window mapped and if the GUI is a
  1303. separate program, it should be killed.</p>
  1304. </div>
  1305. <div class="listingblock">
  1306. <div class="content">
  1307. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/show_optional_gui</code></pre>
  1308. </div>
  1309. </div>
  1310. <div class="listingblock">
  1311. <div class="content">
  1312. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/hide_optional_gui</code></pre>
  1313. </div>
  1314. </div>
  1315. <div class="paragraph">
  1316. <p>This message does not require a response.</p>
  1317. </div>
  1318. </div>
  1319. </div>
  1320. <div class="sect2">
  1321. <h3 id="_client_to_server_informational_messages">2.4. Client to Server Informational Messages</h3>
  1322. <div class="sect3">
  1323. <h4 id="_optional_gui">2.4.1. Optional GUI</h4>
  1324. <div class="paragraph">
  1325. <p>If the client has specified the <code>optional-gui</code> capability, then it MUST send this message whenever
  1326. the state of visibility of the optional GUI has changed. It also MUST send this message after its
  1327. announce message to indicate the initial visibility state of the optional GUI.</p>
  1328. </div>
  1329. <div class="paragraph">
  1330. <p>The client SHOULD always start hidden, if not saved as visible. That implies the first load, after
  1331. adding to the session, SHOULD always be hidden.</p>
  1332. </div>
  1333. <div class="paragraph">
  1334. <p>It is the responsibility of the client to remember the visibility state of its GUI across session
  1335. loads.</p>
  1336. </div>
  1337. <div class="listingblock">
  1338. <div class="content">
  1339. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/gui_is_hidden</code></pre>
  1340. </div>
  1341. </div>
  1342. <div class="listingblock">
  1343. <div class="content">
  1344. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/gui_is_shown</code></pre>
  1345. </div>
  1346. </div>
  1347. <div class="paragraph">
  1348. <p>No response will be delivered.</p>
  1349. </div>
  1350. </div>
  1351. <div class="sect3">
  1352. <h4 id="_progress">2.4.2. Progress</h4>
  1353. <div class="listingblock">
  1354. <div class="content">
  1355. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/progress f:progress</code></pre>
  1356. </div>
  1357. </div>
  1358. <div class="paragraph">
  1359. <p>For potentially time-consuming operations, such as <code>save</code> and <code>open</code>, progress updates may be
  1360. indicated throughout the duration by sending a floating point value between 0.0 and 1.0, 1.0
  1361. indicating completion, to the NSM server.</p>
  1362. </div>
  1363. <div class="paragraph">
  1364. <p>The server will not send a response to these messages, but will relay the information to the user.</p>
  1365. </div>
  1366. <div class="paragraph">
  1367. <p>Note that even when using the <code>progress</code> feature, the final response to the <code>save</code> or <code>open</code>
  1368. message is still REQUIRED.</p>
  1369. </div>
  1370. <div class="paragraph">
  1371. <p>Clients which intend to send progress messages MUST include <code>:progress:</code> in their <code>announce</code>
  1372. capability string.</p>
  1373. </div>
  1374. </div>
  1375. <div class="sect3">
  1376. <h4 id="_dirtiness">2.4.3. Dirtiness</h4>
  1377. <div class="listingblock">
  1378. <div class="content">
  1379. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/is_dirty</code></pre>
  1380. </div>
  1381. </div>
  1382. <div class="listingblock">
  1383. <div class="content">
  1384. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/is_clean</code></pre>
  1385. </div>
  1386. </div>
  1387. <div class="paragraph">
  1388. <p>Some clients may be able to inform the server when they have unsaved changes pending. Such clients
  1389. may optionally send <code>is_dirty</code> and <code>is_clean</code> messages.</p>
  1390. </div>
  1391. <div class="paragraph">
  1392. <p>Clients which have and use this capability MUST include <code>:dirty:</code> in their <code>announce</code> capability string.</p>
  1393. </div>
  1394. </div>
  1395. <div class="sect3">
  1396. <h4 id="_status_messsages">2.4.4. Status Messsages</h4>
  1397. <div class="listingblock">
  1398. <div class="content">
  1399. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/client/message i:priority s:message</code></pre>
  1400. </div>
  1401. </div>
  1402. <div class="paragraph">
  1403. <p>Clients may send miscellaneous status updates to the server for possible display to the user. This
  1404. may simply be chatter that is normally written to the console. <code>priority</code> MUST be a number from 0
  1405. to 3, 3 being the most important.</p>
  1406. </div>
  1407. <div class="paragraph">
  1408. <p>Clients which have and use this capability MUST include <code>:message:</code> in their <code>announce</code> capability
  1409. string.</p>
  1410. </div>
  1411. </div>
  1412. </div>
  1413. <div class="sect2">
  1414. <h3 id="_error_code_definitions">2.5. Error Code Definitions</h3>
  1415. <table class="tableblock frame-all grid-all stripes-even stretch">
  1416. <caption class="title">Table 6. Error Code Definitions</caption>
  1417. <colgroup>
  1418. <col style="width: 50%;">
  1419. <col style="width: 50%;">
  1420. </colgroup>
  1421. <thead>
  1422. <tr>
  1423. <th class="tableblock halign-left valign-top">Symbolic Name</th>
  1424. <th class="tableblock halign-left valign-top">Integer Value</th>
  1425. </tr>
  1426. </thead>
  1427. <tbody>
  1428. <tr>
  1429. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_GENERAL</p></td>
  1430. <td class="tableblock halign-left valign-top"><p class="tableblock">-1</p></td>
  1431. </tr>
  1432. <tr>
  1433. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_INCOMPATIBLE_API</p></td>
  1434. <td class="tableblock halign-left valign-top"><p class="tableblock">-2</p></td>
  1435. </tr>
  1436. <tr>
  1437. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_BLACKLISTED</p></td>
  1438. <td class="tableblock halign-left valign-top"><p class="tableblock">-3</p></td>
  1439. </tr>
  1440. <tr>
  1441. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_LAUNCH_FAILED</p></td>
  1442. <td class="tableblock halign-left valign-top"><p class="tableblock">-4</p></td>
  1443. </tr>
  1444. <tr>
  1445. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NO_SUCH_FILE</p></td>
  1446. <td class="tableblock halign-left valign-top"><p class="tableblock">-5</p></td>
  1447. </tr>
  1448. <tr>
  1449. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NO_SESSION_OPEN</p></td>
  1450. <td class="tableblock halign-left valign-top"><p class="tableblock">-6</p></td>
  1451. </tr>
  1452. <tr>
  1453. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_UNSAVED_CHANGES</p></td>
  1454. <td class="tableblock halign-left valign-top"><p class="tableblock">-7</p></td>
  1455. </tr>
  1456. <tr>
  1457. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NOT_NOW</p></td>
  1458. <td class="tableblock halign-left valign-top"><p class="tableblock">-8</p></td>
  1459. </tr>
  1460. <tr>
  1461. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_BAD_PROJECT</p></td>
  1462. <td class="tableblock halign-left valign-top"><p class="tableblock">-9</p></td>
  1463. </tr>
  1464. <tr>
  1465. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_CREATE_FAILED</p></td>
  1466. <td class="tableblock halign-left valign-top"><p class="tableblock">-10</p></td>
  1467. </tr>
  1468. </tbody>
  1469. </table>
  1470. </div>
  1471. <div class="sect2">
  1472. <h3 id="_client_to_server_control">2.6. Client to Server Control</h3>
  1473. <div class="paragraph">
  1474. <p>If the server publishes the <code>:server-control:</code> capability, then clients can also initiate action by
  1475. the server. For example, a client might implement a 'Save All' option which sends a
  1476. <code>/nsm/server/save</code> message to the server, rather than requiring the user to switch to the session
  1477. management interface to effect the save.</p>
  1478. </div>
  1479. </div>
  1480. <div class="sect2">
  1481. <h3 id="_server_control_api">2.7. Server Control API</h3>
  1482. <div class="paragraph">
  1483. <p>The session manager not only manages clients via OSC, but it is itself controlled via OSC messages.
  1484. The server responds to the following messages.</p>
  1485. </div>
  1486. <div class="paragraph">
  1487. <p>All of the following messages will be responded to, at the sender&#8217;s address, with one of the two
  1488. following messages:</p>
  1489. </div>
  1490. <div class="listingblock">
  1491. <div class="content">
  1492. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/reply s:path s:message</code></pre>
  1493. </div>
  1494. </div>
  1495. <div class="listingblock">
  1496. <div class="content">
  1497. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/error s:path i:error_code s:message</code></pre>
  1498. </div>
  1499. </div>
  1500. <div class="paragraph">
  1501. <p>The first parameter of the reply is the path to the message being replied to. The <code>/error</code> reply
  1502. includes an integer error code (non-zero indicates error). <code>message</code> will be a description of the
  1503. error.</p>
  1504. </div>
  1505. <div class="paragraph">
  1506. <p>The possible errors are:</p>
  1507. </div>
  1508. <table class="tableblock frame-all grid-all stripes-even stretch">
  1509. <caption class="title">Table 7. Responses</caption>
  1510. <colgroup>
  1511. <col style="width: 50%;">
  1512. <col style="width: 50%;">
  1513. </colgroup>
  1514. <thead>
  1515. <tr>
  1516. <th class="tableblock halign-left valign-top">Code</th>
  1517. <th class="tableblock halign-left valign-top">Meaning</th>
  1518. </tr>
  1519. </thead>
  1520. <tbody>
  1521. <tr>
  1522. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_GENERAL</p></td>
  1523. <td class="tableblock halign-left valign-top"><p class="tableblock">General Error</p></td>
  1524. </tr>
  1525. <tr>
  1526. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_LAUNCH_FAILED</p></td>
  1527. <td class="tableblock halign-left valign-top"><p class="tableblock">Launch failed</p></td>
  1528. </tr>
  1529. <tr>
  1530. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NO_SUCH_FILE</p></td>
  1531. <td class="tableblock halign-left valign-top"><p class="tableblock">No such file</p></td>
  1532. </tr>
  1533. <tr>
  1534. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_NO_SESSION</p></td>
  1535. <td class="tableblock halign-left valign-top"><p class="tableblock">No session is open</p></td>
  1536. </tr>
  1537. <tr>
  1538. <td class="tableblock halign-left valign-top"><p class="tableblock">ERR_UNSAVED_CHANGES</p></td>
  1539. <td class="tableblock halign-left valign-top"><p class="tableblock">Unsaved changes would be lost</p></td>
  1540. </tr>
  1541. </tbody>
  1542. </table>
  1543. <div class="ulist">
  1544. <ul>
  1545. <li>
  1546. <p><code>/nsm/server/add s:executable_name</code></p>
  1547. <div class="ulist">
  1548. <ul>
  1549. <li>
  1550. <p>Adds a client to the current session.</p>
  1551. </li>
  1552. </ul>
  1553. </div>
  1554. </li>
  1555. <li>
  1556. <p><code>/nsm/server/save</code></p>
  1557. <div class="ulist">
  1558. <ul>
  1559. <li>
  1560. <p>Saves the current session.</p>
  1561. </li>
  1562. </ul>
  1563. </div>
  1564. </li>
  1565. <li>
  1566. <p><code>/nsm/server/open s:project_name</code></p>
  1567. <div class="ulist">
  1568. <ul>
  1569. <li>
  1570. <p>Saves the current session and loads a new session.</p>
  1571. </li>
  1572. </ul>
  1573. </div>
  1574. </li>
  1575. <li>
  1576. <p><code>/nsm/server/new s:project_name</code></p>
  1577. <div class="ulist">
  1578. <ul>
  1579. <li>
  1580. <p>Saves the current session and creates a new session.</p>
  1581. </li>
  1582. </ul>
  1583. </div>
  1584. </li>
  1585. <li>
  1586. <p><code>/nsm/server/duplicate s:new_project</code></p>
  1587. <div class="ulist">
  1588. <ul>
  1589. <li>
  1590. <p>Saves and closes the current session, makes a copy, and opens it.</p>
  1591. </li>
  1592. </ul>
  1593. </div>
  1594. </li>
  1595. <li>
  1596. <p><code>/nsm/server/close</code></p>
  1597. <div class="ulist">
  1598. <ul>
  1599. <li>
  1600. <p>Saves and closes the current session.</p>
  1601. </li>
  1602. </ul>
  1603. </div>
  1604. </li>
  1605. <li>
  1606. <p><code>/nsm/server/abort</code></p>
  1607. <div class="ulist">
  1608. <ul>
  1609. <li>
  1610. <p>Closes the current session WITHOUT SAVING</p>
  1611. </li>
  1612. </ul>
  1613. </div>
  1614. </li>
  1615. <li>
  1616. <p><code>/nsm/server/quit</code></p>
  1617. <div class="ulist">
  1618. <ul>
  1619. <li>
  1620. <p>Saves and closes the current session and terminates the server.</p>
  1621. </li>
  1622. </ul>
  1623. </div>
  1624. </li>
  1625. <li>
  1626. <p><code>/nsm/server/list</code></p>
  1627. <div class="ulist">
  1628. <ul>
  1629. <li>
  1630. <p>Lists available projects. One <code>/reply</code> message will be sent for each existing project.</p>
  1631. </li>
  1632. <li>
  1633. <p>Afer listing the last session one final <code>/reply</code> with <code>/nsm/server/list, ""</code> will be send. That is an empty string.</p>
  1634. </li>
  1635. </ul>
  1636. </div>
  1637. </li>
  1638. </ul>
  1639. </div>
  1640. <div class="sect3">
  1641. <h4 id="_client_to_client_communication">2.7.1. Client to Client Communication</h4>
  1642. <div class="paragraph">
  1643. <p>If the server includes <code>:broadcast:</code> in its capability string, then clients may send broadcast
  1644. messages to each other through the NSM server. Clients may send messages to the server at the path
  1645. <code>/nsm/server/broadcast</code>.</p>
  1646. </div>
  1647. <div class="paragraph">
  1648. <p>The format of this message is as follows:</p>
  1649. </div>
  1650. <div class="listingblock">
  1651. <div class="content">
  1652. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/server/broadcast s:path [arguments...]</code></pre>
  1653. </div>
  1654. </div>
  1655. <div class="paragraph">
  1656. <p>The message will then be relayed to all clients in the session at the path <code>path</code> (with the
  1657. arguments shifted by one).</p>
  1658. </div>
  1659. <div class="paragraph">
  1660. <p>For example the message:</p>
  1661. </div>
  1662. <div class="listingblock">
  1663. <div class="content">
  1664. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/nsm/server/broadcast /tempomap/update "0,120,4/4:12351234,240,4/4"</code></pre>
  1665. </div>
  1666. </div>
  1667. <div class="paragraph">
  1668. <p>Would broadcast the following message to all clients in the session (except for the sender), some
  1669. of which might respond to the message by updating their own tempo maps.</p>
  1670. </div>
  1671. <div class="listingblock">
  1672. <div class="content">
  1673. <pre class="highlight nowrap"><code class="language-OSC" data-lang="OSC">/tempomap/update "0,120,4/4:12351234,240,4/4"</code></pre>
  1674. </div>
  1675. </div>
  1676. <div class="paragraph">
  1677. <p>The Non programs use this feature to establish peer to peer OSC communication by symbolic names
  1678. (client IDs) without having to remember the OSC URLs of peers across sessions.</p>
  1679. </div>
  1680. </div>
  1681. </div>
  1682. </div>
  1683. </div>
  1684. <div class="sect1">
  1685. <h2 id="_api_versions_and_behaviour_changes">3. API Versions and Behaviour Changes</h2>
  1686. <div class="sectionbody">
  1687. <div class="paragraph">
  1688. <p>Here we will document all technical changes or differences in behaviour together with their API and
  1689. project version numbers. The term "original" refers to Non Session Manager and "new" refers to New
  1690. Session Manager.</p>
  1691. </div>
  1692. <div class="paragraph">
  1693. <p>Version numbers follow <a href="https://semver.org/spec/v2.0.0.html">Semantic Versioning 2.0.0</a></p>
  1694. </div>
  1695. <div class="listingblock">
  1696. <div class="title">Semantic Versioning Scheme</div>
  1697. <div class="content">
  1698. <pre class="highlight"><code>Given a version number MAJOR.MINOR.PATCH, increment the:
  1699. MAJOR version when you make incompatible API changes,
  1700. MINOR version when you add functionality in a backwards compatible manner, and
  1701. PATCH version when you make backwards compatible bug fixes.</code></pre>
  1702. </div>
  1703. </div>
  1704. <table class="tableblock frame-all grid-all stripes-even stretch">
  1705. <caption class="title">Table 8. NSM Version Numbers</caption>
  1706. <colgroup>
  1707. <col style="width: 50%;">
  1708. <col style="width: 50%;">
  1709. </colgroup>
  1710. <thead>
  1711. <tr>
  1712. <th class="tableblock halign-left valign-top">Subject</th>
  1713. <th class="tableblock halign-left valign-top">Version</th>
  1714. </tr>
  1715. </thead>
  1716. <tbody>
  1717. <tr>
  1718. <td class="tableblock halign-left valign-top"><p class="tableblock">Non Session Manager at moment of fork</p></td>
  1719. <td class="tableblock halign-left valign-top"><p class="tableblock">1.2 (June 2020)</p></td>
  1720. </tr>
  1721. <tr>
  1722. <td class="tableblock halign-left valign-top"><p class="tableblock">Non Session Manager API</p></td>
  1723. <td class="tableblock halign-left valign-top"><p class="tableblock">1.0 <a href="https://github.com/original-male/non/blob/master/session-manager/src/nsmd.C">NON nsmd.C</a></p></td>
  1724. </tr>
  1725. <tr>
  1726. <td class="tableblock halign-left valign-top"><p class="tableblock">Original API Document</p></td>
  1727. <td class="tableblock halign-left valign-top"><p class="tableblock">1.0 <a href="http://non.tuxfamily.org/nsm/API.html">non.tuxfamily.org/nsm/API.html</a></p></td>
  1728. </tr>
  1729. <tr>
  1730. <td class="tableblock halign-left valign-top"><p class="tableblock">New Session Manager</p></td>
  1731. <td class="tableblock halign-left valign-top"><p class="tableblock">1.6.0</p></td>
  1732. </tr>
  1733. <tr>
  1734. <td class="tableblock halign-left valign-top"><p class="tableblock">New Session Manager API</p></td>
  1735. <td class="tableblock halign-left valign-top"><p class="tableblock">1.1.2 <a href="https://github.com/jackaudio/new-session-manager/blob/master/src/nsmd.cpp">NEW nsmd.cpp</a></p></td>
  1736. </tr>
  1737. <tr>
  1738. <td class="tableblock halign-left valign-top"><p class="tableblock">New API Document</p></td>
  1739. <td class="tableblock halign-left valign-top"><p class="tableblock">1.5.0 <a href="#">Here</a></p></td>
  1740. </tr>
  1741. </tbody>
  1742. </table>
  1743. <div class="sect2">
  1744. <h3 id="_guidelines">3.1. Guidelines</h3>
  1745. <div class="paragraph">
  1746. <p>The most important factor in decision making is to keep client compatibility at 100%.
  1747. No client will ever receive an unrequested OSC message except those in API 1.0.0.</p>
  1748. </div>
  1749. <div class="paragraph">
  1750. <p>Messages that drastically change existing <code>/nsm/client/</code> or <code>/nsm/server</code> behaviour require an
  1751. inrecement to <code>API_VERSION_MAJOR</code>, which we want to avoid.</p>
  1752. </div>
  1753. <div class="paragraph">
  1754. <p><code>nsmd</code> checks if the clients <code>API_VERSION_MAJOR</code> is greater than its own and refuses the client
  1755. with <code>ERR_INCOMPATIBLE_API</code>.</p>
  1756. </div>
  1757. <div class="paragraph">
  1758. <p>All changes (that concern client/server behaviour) that increment <code>API_VERSION_MINOR</code> will be
  1759. request-only or gated by new capabilities (e.g. <code>:optional-gui:</code>). <code>nsmd</code> will not send any
  1760. messages if a capability was not sent by the client in <a href="#_announce"><code>announce</code></a>. This includes
  1761. mostly optional features about requesting extra information.</p>
  1762. </div>
  1763. <div class="paragraph">
  1764. <p>New actions for server-control, for example a hypothetical <code>/nsm/server/save_as</code>, which would be
  1765. triggered by the client and would only be <strong>answered</strong> by the server ("no unrequested message") will
  1766. increment <code>API_VERSION_MINOR</code>.</p>
  1767. </div>
  1768. <div class="paragraph">
  1769. <p>All changes that increment <code>API_VERSION_PATCH</code> will not have any effect on behaviour, except to
  1770. fix clear problems, where "problem" is defined by having a different effect than described in this
  1771. document, which includes technical problems such as crashes.</p>
  1772. </div>
  1773. <div class="paragraph">
  1774. <p>All messages regarding GUI-communication that start with <code>/nsm/gui/&#8230;&#8203;</code> were undocumented in API
  1775. 1.0.0 and only used by <code>non-session-manager</code> / <code>nsm-legacy-gui</code>. Until properly documented in this
  1776. document this part of the API is considered unstable and may change at any time without notice.
  1777. However, when changing already existing messages and behaviour it MAY increment <code>API_VERSION_MINOR</code>
  1778. or <code>API_VERSION_PATCH</code>. In that case it will appear in the list below.</p>
  1779. </div>
  1780. <div class="paragraph">
  1781. <p>Last factor of compatibility is that any unknown message sent to <code>nsmd</code> will just print a warning
  1782. message to stdout, but will otherwise be ignored. This secures a stable server, even when a client
  1783. misbehaves and sends too-new messages outside of announced :capabilites:</p>
  1784. </div>
  1785. </div>
  1786. <div class="sect2">
  1787. <h3 id="_changes_in_api_version_1_1_0">3.2. Changes in API Version 1.1.0</h3>
  1788. <div class="paragraph">
  1789. <p>Rewritten API document without code changes to adapt to existing code or existing client behaviour:</p>
  1790. </div>
  1791. <div class="ulist">
  1792. <ul>
  1793. <li>
  1794. <p>Changed versioning scheme to Semantic Versioning with three positions Major.Minor.Patch</p>
  1795. </li>
  1796. <li>
  1797. <p><a href="#_quit_or_exit">Quit or Exit</a> SHOULD hide instead of exiting when :optional-gui: is supported and MAY not
  1798. act on the quit through menu otherwise.</p>
  1799. </li>
  1800. <li>
  1801. <p><a href="#server-to-client-control-messages-open">Open</a>: Make clear that there are only certain
  1802. possibilities for save paths. We added MUST because the rule was just implied before.</p>
  1803. </li>
  1804. <li>
  1805. <p><a href="#server-to-client-control-messages-open">Open</a>: Make clear that the delimiter for
  1806. multi-jack clients is "/".</p>
  1807. </li>
  1808. <li>
  1809. <p><a href="#_optional_gui">Optional GUI</a> SHOULD start hidden, always after a fresh add to the session. After that saving
  1810. the visibility state may override it for next time.</p>
  1811. </li>
  1812. <li>
  1813. <p><a href="#_progress">Progress</a> MUST be announced in :capabilities: . Before there was a lower case "should",
  1814. which means nothing. Parallel-examples in the specs cleary say that supporting optional features must be announced first.</p>
  1815. <div class="ulist">
  1816. <ul>
  1817. <li>
  1818. <p>Same for <a href="#_dirtiness">Dirtiness</a> and <a href="#_status_messsages">Status Messsages</a>.</p>
  1819. </li>
  1820. </ul>
  1821. </div>
  1822. </li>
  1823. <li>
  1824. <p><a href="#_status_messsages">Status Messsages</a> have priority numbers between 0 and 3, so they MUST send that.
  1825. It was never an arbitrary value.</p>
  1826. </li>
  1827. </ul>
  1828. </div>
  1829. <div class="paragraph">
  1830. <p>Code changes:</p>
  1831. </div>
  1832. <div class="ulist">
  1833. <ul>
  1834. <li>
  1835. <p><a href="#_server_control_api">Server Control API</a>: <code>/nsm/server/list</code> chain of single OSC messages, one for each session,
  1836. is now finalized with sending and empty string "" as session name. Previously this was just
  1837. a symbolically irrelevant console message <code>"Done."</code></p>
  1838. </li>
  1839. <li>
  1840. <p>Replies to <code>/nsm/server/save</code> etc. will now be sent back to the sender and not falsely to the last
  1841. client who replied to <code>/nsm/client/save</code>. This alone would only require API_VERSION_PATCH
  1842. increment, but we are already incrementing minor.</p>
  1843. </li>
  1844. <li>
  1845. <p><a href="#_server_control_api">Server Control API</a>: <code>/nsm/server/add</code> was replying with an undocumented error code on success.
  1846. Instead, as this document always specificed, it now sends <code>"/reply", path, "Launched."</code>.
  1847. Again, this would have been just API_VERSION_PATCH on its own.</p>
  1848. </li>
  1849. </ul>
  1850. </div>
  1851. <div class="paragraph">
  1852. <p>Undocumented (Unstable) <code>/nsm/gui</code> protocol</p>
  1853. </div>
  1854. <div class="ulist">
  1855. <ul>
  1856. <li>
  1857. <p>Send client status after a GUI attaches to running server. This
  1858. was not happening before, but it was the intention. It was just broken in nsmd.cpp. This alone
  1859. would only require API_VERSION_PATCH increment, but we are already incrementing minor.</p>
  1860. </li>
  1861. <li>
  1862. <p>Send label "launch error!" when a program is added (or loaded) that
  1863. does not exist in $PATH. This requires no adaptation of any client, server or GUI because labels
  1864. are arbitrary already and this is not meant for automatic parsing, but as user information.</p>
  1865. </li>
  1866. <li>
  1867. <p><code>/nsm/gui/session/name</code> will now always send the same parameter format, regardless of how the session was opened:
  1868. simple-session-name, relative session path with subdirs below session-root.</p>
  1869. </li>
  1870. <li>
  1871. <p>When a GUI announces itself to nsmd it will receive the absolute path to the session directory
  1872. through the message <code>/nsm/gui/session/root</code>. This is not a new addition but was already in
  1873. non-session-manager git.</p>
  1874. </li>
  1875. </ul>
  1876. </div>
  1877. </div>
  1878. <div class="sect2">
  1879. <h3 id="_changes_in_api_version_1_1_1">3.3. Changes in API Version 1.1.1</h3>
  1880. <div class="ulist">
  1881. <ul>
  1882. <li>
  1883. <p>Server-capability :optional-gui: is now mandatory for SERVER implementations. Reasoning:
  1884. This is an important core feature of NSM and thus will be treated as such by guaranteeing it to exist.
  1885. After looking at all currently known clients and server-implementations it turns out that all servers
  1886. support :optional-gui: and the vast majority of clients not only support it, but actually assume it
  1887. and do <em>not</em> test for the server capability, as it was written in this document.
  1888. There are now two choices: Adjust this document to the (good) reality or consider all clients broken.
  1889. Summary: We consider this API document wrong and therefore fix it, thus increasing API version
  1890. patch-level from 1.1.0 to 1.1.1</p>
  1891. </li>
  1892. <li>
  1893. <p>Add API-section "Subdirectories / Hierarchical Structure" that explains the session directory.
  1894. This behaviour was already the case for nsm-legacy-gui and nsmd 1.5.0 was patched to adhere to this
  1895. behaviour more strictly as well, removing false session entries in 3rd party clients such as Agordejo.</p>
  1896. </li>
  1897. </ul>
  1898. </div>
  1899. </div>
  1900. <div class="sect2">
  1901. <h3 id="_changes_in_api_version_1_1_2">3.4. Changes in API Version 1.1.2</h3>
  1902. <div class="ulist">
  1903. <ul>
  1904. <li>
  1905. <p>nsmd now follows the XDG Base Directory Specifications for it&#8217;s session root and lock files. This
  1906. if of no consequence to clients but required documentation nevertheless, which was described as
  1907. "background information" in the chapters for lock files and daemon disovery.</p>
  1908. </li>
  1909. <li>
  1910. <p>nsmd now gracefully handles read-only <code>session.nsm</code> files. This theoretically enables read-only
  1911. sessions and session-templates. It is included in the patch-level because this was marked as a
  1912. long-standing <code>FIXME</code> in the code by the original author. Or in other words: just a bug fix.</p>
  1913. </li>
  1914. </ul>
  1915. </div>
  1916. </div>
  1917. </div>
  1918. </div>
  1919. </div>
  1920. <div id="footer">
  1921. <div id="footer-text">
  1922. Version API 1.1.2<br>
  1923. Last updated 2022-04-06 23:25:00 +0200
  1924. </div>
  1925. </div>
  1926. </body>
  1927. </html>