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.

597 lines
21KB

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