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.

670 lines
22KB

  1. ////
  2. This is not an "asciidoctor", not plain "asciidoc" document.
  3. https://asciidoctor.org/docs/user-manual/
  4. ////
  5. ////
  6. This documentation is licensed under the Creative Commons Attribution-ShareAlike 2.5 International License.
  7. To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/2.5/legalcode or send a
  8. letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
  9. A copy of the license has been provided in the file documentation/API/LICENSE.
  10. ////
  11. :authors: Jonathan Moore Liles
  12. :email: <male@tuxfamily.org>
  13. :revnumber: 1.2
  14. :revdate: 2013-04-06
  15. :iconfont-remote!:
  16. :!webfonts:
  17. :sectnums:
  18. :sectnumlevels: 4
  19. :toc: preamble
  20. :toc-title: Table of Contents
  21. :toclevels: 4
  22. = Non Session Manager API
  23. == Non Session Management API
  24. The Non Session Management API is used by the various components of the Non audio production suite
  25. to allow any number of independent programs to be managed together as part of a logical session
  26. (i.e. a song). Thus, operations such as loading and saving are synchronized.
  27. The API comprises a simple Open Sound Control (OSC) based protocol, along with some behavioral
  28. guidelines, which can easily be implemented by various applications.
  29. The Non project contains an program called `nsmd` which is an implementation of the server side of
  30. the NSM API. `nsmd` is controlled by the `non-session-manager` GUI. However, the same server-side
  31. API can also be implemented by other session managers (such as LADISH), although consistency and
  32. robustness will likely suffer if non-NSM compliant clients are allowed to participate in a session.
  33. The only dependency for client implementations `liblo` (the OSC library), which several Linux audio
  34. applications already link to or plan to link to in the future.b
  35. The aim of this project is to thoroughly define the behavior required of clients. This is an area
  36. where other attempts at session management (LASH and JACK-Session) have failed. Often the
  37. difficulty with these systems has been not in implementing support for them, but in attempting to
  38. interpret the confusing, ambiguous, or ill-conceived API documentation. For these reasons and more
  39. all previous attempts at Linux audio session management protocols are considered harmful.
  40. You WILL see some unambiguous and emphatic language in this document. For the good of the user,
  41. these rules are meant to be followed and are non-negotiable. If an application does not conform to
  42. this specification it should be considered broken. Consistency across applications under session
  43. management is very important for a good user experience.
  44. === Client Behavior Under Session Management
  45. Most graphical applications make available to the user a common set of file operations, typically
  46. presented under a File or Project menu.
  47. These are: New, Open, Save, Save As, Close and Quit or Exit.
  48. The following sub-sections describe how these options should behave when the application is part of
  49. an NSM session. These rules only apply when session management is active (that is, after the
  50. `announce` handshake described in the <<NSM OSC Protocol>> section. In order to provide a
  51. consistent and predictable user experience, it is critically important for applications to adhere
  52. to these guidelines.
  53. ==== File Menu
  54. ===== New
  55. This option may empty/reset the current file or project (possibly after user confirmation). UNDER
  56. NO CIRCUMSTANCES should it allow the user to create a new project/file in another location.
  57. ===== Open
  58. This option MUST be disabled.
  59. The application may, however, elect to implement an option called 'Import into Session', creates a
  60. copy of a file/project which is then saved at the session path provided by NSM.
  61. ===== Save
  62. This option should behave as normal, saving the current file/project as established by the NSM
  63. `open` message.
  64. UNDER NO CIRCUMSTANCES should this option present the user with a choice of where to save the file.
  65. ===== Save As
  66. This option MUST be disabled.
  67. The application may, however, elect to implement an option called 'Export from Session', which
  68. creates a copy of the current file/project which is then saved in a user-specified location outside
  69. of the session path provided by NSM.
  70. ===== Close (as distinguished from Quit or Exit)
  71. This option MUST be disabled unless its meaning is to disconnect the application from session
  72. management.
  73. ===== Quit or Exit
  74. This option may behave as normal (possibly asking the user to confirm exiting).
  75. ==== Data Storage
  76. ===== Internal Files
  77. All project specific data created by a client MUST be stored in the per-client storage area
  78. provided by NSM. This includes all recorded audio and MIDI files, snapshots, etc. Only global
  79. configuration items, exports, and renders of the project may be stored elsewhere (wherever the user
  80. specifies).
  81. ===== External Files
  82. Files required by the project but external to it (typically read-only data such as audio samples)
  83. SHOULD be referenced by creating a symbolic link within the assigned session area, and then
  84. referring to the symlink. This allows sessions to be archived and transported simply (e.g. with
  85. "tar -h") by tools that have no knowledge of the project formats of the various clients in the
  86. session. The symlinks thus created should, at the very least, be named after the files they refer
  87. to (some unique component may be required to prevent collisions)
  88. === NSM OSC Protocol
  89. All message parameters are REQUIRED. All messages MUST be sent from the same socket as the `announce`
  90. message, using the `lo_send_from` method of liblo or its equivalent, as the server uses the return
  91. addresses to distinguish between clients.
  92. Clients MUST create thier OSC servers using the same protocol (UDP,TCP) as found in `NSM_URL`. liblo
  93. is lacking a robust TCP implementation at the time of writing, but in the future it may be useful.
  94. ==== Establishing a Connection
  95. ===== Announce
  96. At launch, the client MUST check the environment for the value of `NSM_URL`. If present, the client
  97. MUST send the following message to the provided address as soon as it is ready to respond to the
  98. `/nsm/client/open` event:
  99. [source%nowrap,OSC]
  100. ----
  101. /nsm/server/announce s:application_name s:capabilities s:executable_name i:api_version_major i:api_version_minor i:pid
  102. ----
  103. If `NSM_URL` is undefined, invalid, or unreachable, then the client should proceed assuming that
  104. session management is unavailable.
  105. `api_version_major` and `api_version_minor` must be the two parts of the version number of the NSM API
  106. as defined by this document.
  107. Note that if the application intends to register JACK clients, `application_name` MUST be the same as
  108. the name that would normally be passed to `jack_client_open`. For example, Non-Mixer sends
  109. "Non-Mixer" as its `application_name`. Applications MUST NOT register their JACK clients until
  110. receiving an `open` message; the `open` message will provide a unique client name prefix suitable for
  111. passing to JACK. This is probably the most complex requirement of the NSM API, but it isn't
  112. difficult to implement, especially if the application simply wishes to delay its initialization
  113. process breifly while awaiting the `announce` reply and subsequent `open` message.
  114. `capabilities` MUST be a string containing a colon separated list of the special capabilities the
  115. client possesses. e.g. `:dirty:switch:progress:`
  116. `executable_name` MUST be the executable name that the program was launched with. For C programs,
  117. this is simply the value of `argv[0]`. Note that hardcoding the name of the program here is not the
  118. same as using, as the user may have launched the program from a script with a different name using
  119. exec, or have created a symlink to the program. Getting the correct value in scripting languages
  120. like Python can be more challenging.
  121. .Available Client Capabilities
  122. [options="header", stripes=even]
  123. |===
  124. |Name | Description
  125. |switch | client is capable of responding to multiple `open` messages without restarting
  126. |dirty | client knows when it has unsaved changes
  127. |progress | client can send progress updates during time-consuming operations
  128. |message | client can send textual status updates
  129. |optional-gui | client has an optional GUI
  130. |===
  131. ===== Response
  132. The server will respond to the client's announce message with the following message:
  133. [source%nowrap,OSC]
  134. ----
  135. /reply "/nsm/server/announce" s:message s:name_of_session_manager s:capabilities
  136. ----
  137. `message` is a welcome message.
  138. The value of `name_of_session_manager` will depend on the implementation of the NSM server. It might
  139. say "Non Session Manager", or it might say "LADISH". This is for display to the user.
  140. `capabilities` will be a string containing a colon separated list of special server capabilities.
  141. Presently, the server `capabilities` are:
  142. .Available Server Capabilities
  143. [options="header", stripes=even]
  144. |===
  145. |Name | Description
  146. |server_control | client-to-server control
  147. |broadcast | server responds to /nsm/server/broadcast message
  148. |optional-gui | server responds to optional-gui messages--if this capability is not present then clients with optional-guis MUST always keep them visible
  149. |===
  150. A client should not consider itself to be under session management until it receives this response.
  151. For example, the Non applications activate their "SM" blinkers at this time.
  152. If there is an error, a reply of the following form will be sent to the client:
  153. [source%nowrap,OSC]
  154. ----
  155. /error "/nsm/server/announce" i:error_code s:error_message
  156. ----
  157. The following table defines possible values of `error_code`:
  158. .Response codes
  159. [options="header", stripes=even]
  160. |===
  161. |Code | Meaning
  162. |ERR_GENERAL | General Error
  163. |ERR_INCOMPATIBLE_API | Incompatible API version
  164. |ERR_BLACKLISTED | Client has been blacklisted.
  165. |===
  166. ==== Server to Client Control Messages
  167. Compliant clients MUST accept the client control messages described in this section. All client
  168. control messages REQUIRE a response. Responses MUST be delivered back to the sender (NSM) from the
  169. same socket used by the client in its `announce` message (by using `lo_send_from`) AFTER the action has
  170. been completed or if an error is encountered. The required response is described in the subsection
  171. for each message.
  172. If there is an error and the action cannot be completed, then `error_code` MUST be set to a valid
  173. error code (see <<Error Code Definitions>>) and `message` to a string describing the problem
  174. (suitable for display to the user).
  175. The reply can take one of the following two forms, where path MUST be the `path` of the message being
  176. replied to (e.g. "nsm/client/save":
  177. [source%nowrap,OSC]
  178. ----
  179. /reply s:path s:message
  180. ----
  181. [source%nowrap,OSC]
  182. ----
  183. /error s:path i:error_code s:message
  184. ----
  185. ===== Quit
  186. There is no message for this. Clients will receive the Unix SIGTERM signal and MUST close cleanly
  187. IMMEDIATELY, without displaying any kind of dialog to the user and regardless of whether or not
  188. unsaved changes would be lost. When a session is closed the application will receive this signal
  189. soon after having responded to a `save` message.
  190. ===== Open
  191. [source%nowrap,OSC]
  192. ----
  193. /nsm/client/open s:path_to_instance_specific_project s:display_name s:client_id
  194. ----
  195. `path_to_instance_specific_project` is a path name assigned to the client for storing its project
  196. data.
  197. The client may append to the path, creating a sub-directory, e.g. '/song.foo' or simply append the
  198. client's native file extension (e.g. '.non' or '.XML'). The same transformation MUST be applied to
  199. the name when opening an existing project, as NSM will only provide the instance specific part of
  200. the path.
  201. If a project exists at the path, the client MUST immediately open it.
  202. If a project does not exist at the path, then the client MUST immediately create and open a new one
  203. at the specified path or, for clients which hold all their state in memory, store the path for
  204. later use when responding to the `save` message.
  205. No file or directory will be created at the specified path by the server. It is up to the client to
  206. create what it needs.
  207. For clients which HAVE NOT specified the `:switch:` capability, the `open` message will only be
  208. delivered once, immediately following the `announce` response.
  209. For clients which HAVE specified the `:switch:` capability, the client MUST immediately switch to the
  210. specified project or create a new one if it doesn't exist.
  211. Clients which are incapable of switching projects or are prone to crashing upon switching MUST NOT
  212. include `:switch:` in their capability string.
  213. If the user the is allowed to run two or more instances of the application simultaneously (that is
  214. to say, there is no technical limitation preventing them from doing so, even if it doesn't make
  215. sense to the author), then such an application MUST PRE-PEND the provided `client_id` string to any
  216. names it registers with common subsystems (e.g. JACK client names). This ensures that multiple
  217. instances of the same application can be restored in any order without scrambling the JACK
  218. connections or causing other conflicts. The provided `client_id` will be a concatenation of the value
  219. of `application_name` sent by the client in its `announce` message and a unique identifier. Therefore,
  220. applications which create single JACK clients can use the value of `client_id` directly as their JACK
  221. client name. Applications which register multiple JACK clients (e.g. Non-Mixer) MUST PRE-PEND
  222. `client_id` value to the client names they register with JACK and the application determined part
  223. MUST be unique for that (JACK) client.
  224. For example, a suitable JACK client name would be: `$CLIENT_ID/track-1`
  225. Note that this means that the application MUST NOT register with JACK (or any
  226. other subsystem requiring unique names) until it receives an `open` message from NSM. Likewise,
  227. applications with the `:switch:` capability should close their JACK clients and re-create them with
  228. using the new `client_id`. Re-registering is necessary because the JACK API does currently support
  229. renaming existing clients, although this is a sorely needed addition.
  230. A response is REQUIRED as soon as the open operation has been completed. Ongoing progress may be
  231. indicated by sending messages to `/nsm/client/progress`.
  232. ====== Response
  233. The client MUST respond to the 'open' message with:
  234. [source%nowrap,OSC]
  235. ----
  236. /reply "/nsm/client/open" s:message
  237. ----
  238. Or
  239. [source%nowrap,OSC]
  240. ----
  241. /error "/nsm/client/open" i:error_code s:message
  242. ----
  243. .Response codes
  244. [options="header", stripes=even]
  245. |===
  246. |Code | Meaning
  247. |ERR | General Error
  248. |ERR_BAD_PROJECT | An existing project file was found to be corrupt
  249. |ERR_CREATE_FAILED | A new project could not be created
  250. |ERR_UNSAVED_CHANGES | Unsaved changes would be lost
  251. |ERR_NOT_NOW | Operation cannot be completed at this time
  252. |===
  253. ===== Save
  254. [source%nowrap,OSC]
  255. ----
  256. /nsm/client/save
  257. ----
  258. This message will only be delivered after a previous `open` message, and may be sent any number of
  259. times within the course of a session (including zero, if the user aborts the session).
  260. ====== Response
  261. [source%nowrap,OSC]
  262. ----
  263. /reply "/nsm/client/save" s:message
  264. ----
  265. Or
  266. [source%nowrap,OSC]
  267. ----
  268. /error "/nsm/client/save" i:error_code s:message
  269. ----
  270. .Response codes
  271. [options="header", stripes=even]
  272. |===
  273. |Code | Meaning
  274. |ERR | General Error
  275. |ERR_SAVE_FAILED | Project could not be saved
  276. |ERR_NOT_NOW | Operation cannot be completed at this time
  277. |===
  278. ==== Server to Client Informational Messages
  279. ===== Session is Loaded
  280. Accepting this message is optional. The intent is to signal to clients which may have some
  281. interdependence (say, peer to peer OSC connections) that the session is fully loaded and all their
  282. peers are available. Most clients will not need to act on this message. This message has no meaning
  283. when a session is being built or run--only when it is initially loaded. Clients who intend to act
  284. on this message MUST not do so by delaying initialization waiting for it.
  285. [source%nowrap,OSC]
  286. ----
  287. /nsm/client/session_is_loaded
  288. ----
  289. This message does not require a response.
  290. ===== Show Optional Gui
  291. If the client has specified the `optional-gui` capability, then it may receive this message from the
  292. server when the user wishes to change the visibility state of the GUI. It doesn't matter if the
  293. optional GUI is integrated with the program or if it is a separate program \(as is the case with
  294. SooperLooper\). When the GUI is hidden, there should be no window mapped and if the GUI is a
  295. separate program, it should be killed.
  296. [source%nowrap,OSC]
  297. ----
  298. /nsm/client/show_optional_gui
  299. ----
  300. [source%nowrap,OSC]
  301. ----
  302. /nsm/client/hide_optional_gui
  303. ----
  304. No response is message is required.
  305. ==== Client to Server Informational Messages
  306. ===== Optional GUI
  307. If the client has specified the `optional-gui` capability, then it MUST send this message whenever
  308. the state of visibility of the optional GUI has changed. It also MUST send this message after it's
  309. announce message to indicate the initial visibility state of the optional GUI.
  310. It is the responsibility of the client to remember the visibility state of its GUI across session
  311. loads.
  312. [source%nowrap,OSC]
  313. ----
  314. /nsm/client/gui_is_hidden
  315. ----
  316. [source%nowrap,OSC]
  317. ----
  318. /nsm/client/gui_is_shown
  319. ----
  320. No response will be delivered.
  321. ===== Progress
  322. [source%nowrap,OSC]
  323. ----
  324. /nsm/client/progress f:progress
  325. ----
  326. For potentially time-consuming operations, such as `save` and `open`, progress updates may be
  327. indicated throughout the duration by sending a floating point value between 0.0 and 1.0, 1.0
  328. indicating completion, to the NSM server.
  329. The server will not send a response to these messages, but will relay the information to the user.
  330. Note that even when using the `progress` feature, the final response to the `save` or `open`
  331. message is still REQUIRED.
  332. Clients which intend to send progress messages should include `:progress:` in their `announce`
  333. capability string.
  334. ===== Dirtiness
  335. [source%nowrap,OSC]
  336. ----
  337. /nsm/client/is_dirty
  338. ----
  339. [source%nowrap,OSC]
  340. ----
  341. /nsm/client/is_clean
  342. ----
  343. Some clients may be able to inform the server when they have unsaved changes pending. Such clients
  344. may optionally send `is_dirty` and `is_clean` messages.
  345. Clients which have this capability should include `:dirty:` in their `announce` capability string.
  346. ===== Status Messsages
  347. [source%nowrap,OSC]
  348. ----
  349. /nsm/client/message i:priority s:message
  350. ----
  351. Clients may send miscellaneous status updates to the server for possible display to the user. This
  352. may simply be chatter that is normally written to the console. `priority` should be a number from 0
  353. to 3, 3 being the most important.
  354. Clients which have this capability should include `:message:` in their `announce` capability
  355. string.
  356. ==== Error Code Definitions
  357. .Error Code Definitions
  358. [options="header", stripes=even]
  359. |===
  360. |Symbolic Name | Integer Value
  361. |ERR_GENERAL | -1
  362. |ERR_INCOMPATIBLE_API | -2
  363. |ERR_BLACKLISTED | -3
  364. |ERR_LAUNCH_FAILED | -4
  365. |ERR_NO_SUCH_FILE | -5
  366. |ERR_NO_SESSION_OPEN | -6
  367. |ERR_UNSAVED_CHANGES | -7
  368. |ERR_NOT_NOW | -8
  369. |ERR_BAD_PROJECT | -9
  370. |ERR_CREATE_FAILED | -10
  371. |===
  372. ==== Client to Server Control
  373. If the server publishes the `:server_control:` capability, then clients can also initiate action by
  374. the server. For example, a client might implement a 'Save All' option which sends a
  375. `/nsm/server/save` message to the server, rather than requiring the user to switch to the session
  376. management interface to effect the save.
  377. ==== Server Control API
  378. The session manager not only manages clients via OSC, but it is itself controlled via OSC messages.
  379. The server responds to the following messages.
  380. All of the following messages will be responded to, at the sender's address, with one of the two
  381. following messages:
  382. [source%nowrap,OSC]
  383. ----
  384. /reply s:path s:message
  385. ----
  386. [source%nowrap,OSC]
  387. ----
  388. /error s:path i:error_code s:message
  389. ----
  390. The first parameter of the reply is the path to the message being replied to. The `/error` reply
  391. includes an integer error code (non-zero indicates error). `message` will be a description of the
  392. error.
  393. The possible errors are:
  394. .Responses
  395. [options="header", stripes=even]
  396. |===
  397. |Code |Meaning
  398. |ERR_GENERAL | General Error
  399. |ERR_LAUNCH_FAILED | Launch failed
  400. |ERR_NO_SUCH_FILE | No such file
  401. |ERR_NO_SESSION | No session is open
  402. |ERR_UNSAVED_CHANGES | Unsaved changes would be lost
  403. |===
  404. * `/nsm/server/add s:executable_name`
  405. ** Adds a client to the current session.
  406. * `/nsm/server/save`
  407. ** Saves the current session.
  408. * `/nsm/server/open s:project_name`
  409. ** Saves the current session and loads a new session.
  410. * `/nsm/server/new s:project_name`
  411. ** Saves the current session and creates a new session.
  412. * `/nsm/server/duplicate s:new_project`
  413. ** Saves and closes the current session, makes a copy, and opens it.
  414. * `/nsm/server/close`
  415. ** Saves and closes the current session.
  416. * `/nsm/server/abort`
  417. ** Closes the current session WITHOUT SAVING
  418. * `/nsm/server/quit`
  419. ** Saves and closes the current session and terminates the server.
  420. * `/nsm/server/list`
  421. ** Lists available projects. One `/reply` message will be sent for each existing project.
  422. ===== Client to Client Communication
  423. If the server includes `:broadcast:` in its capability string, then clients may send broadcast
  424. messages to each other through the NSM server. Clients may send messages to the server at the path
  425. `/nsm/server/broadcast`.
  426. The format of this message is as follows:
  427. [source%nowrap,OSC]
  428. ----
  429. /nsm/server/broadcast s:path [arguments...]
  430. ----
  431. The message will then be relayed to all clients in the session at the path `path` (with the
  432. arguments shifted by one).
  433. For example the message:
  434. [source%nowrap,OSC]
  435. ----
  436. /nsm/server/broadcast /tempomap/update "0,120,4/4:12351234,240,4/4"
  437. ----
  438. Would broadcast the following message to all clients in the session (except for the sender), some
  439. of which might respond to the message by updating their own tempo maps.
  440. [source%nowrap,OSC]
  441. ----
  442. /tempomap/update "0,120,4/4:12351234,240,4/4"
  443. ----
  444. The Non programs use this feature to establish peer to peer OSC communication by symbolic names
  445. (client IDs) without having to remember the OSC URLs of peers across sessions.