|
- ////
- This is "asciidoctor", not plain "asciidoc".
- https://asciidoctor.org/docs/user-manual/
-
- 100 characters per line (soft limit).
-
- ////
-
-
- ////
- This documentation is licensed under the Creative Commons Attribution-ShareAlike 2.5 International License.
- To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/2.5/legalcode or send a
- letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
- A copy of the license has been provided in the file documentation/API/LICENSE.
- ////
-
-
- ////
- The revnumber API 1.1.1 below is autogenerated. Please do not touch this line.
- ////
-
- :authors: Jonathan Moore Liles, Nils Hilbricht
- :revnumber: API 1.1.2
- :revremark: License CC-By-SA v2.5
- :iconfont-remote!:
- :!webfonts:
-
- :sectnums:
- :sectnumlevels: 4
-
- :toc:
- :toc-title: Table of Contents
- :toclevels: 4
-
-
- = New Session Manager - API
-
- IMPORTANT: "New Session Manager" is a community version of the
- link:http://non.tuxfamily.org/nsm/API.html["Non Session Manager" by Jonathan Moore Liles], who also
- wrote the majority of this API document, especially the API itself. *The API is the same*. Any
- technical changes or differences in behaviour are described in <<API Versions and Behaviour Changes>>.
- All other changes to this document can be reviewed by accessing the git log. This document is
- licensed under CC-By-Sa v2.5. See link:https://github.com/jackaudio/new-session-manager/tree/master/docs/src/api[LICENSE]
-
-
- IMPORTANT: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
- NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
- described in link:https://tools.ietf.org/html/rfc2119[RFC 2119].
-
-
- The "New Session Manager"-API is used by many music and audio programs in Linux distributions
- to allow any number of independent programs to be managed together as part of a logical session
- (i.e. a song). Thus, operations such as loading and saving are synchronized.
-
- The API comprises a simple Open Sound Control (OSC) based protocol, along with some behavioral
- guidelines, which can easily be implemented by various applications.
-
- This project contains a program called `nsmd` which is an implementation of the server side of
- the NSM API. `nsmd` can be controlled by direct OSC messages, or (more commonly) a GUI:
- Included in this package is the `nsm-legacy-gui`, which gets symlinked to "non-session-manager`.
- Another GUI is "Agordejo". Other applications exist that (partially) support the NSM API and are able
- to load clients, but they do not use the New-Session-Manager (or Non-Session-Manager) implementation
- and are therefore out of scope for this document.
-
- However, the same server-side API can also be implemented by other programs (such as Carla),
- although consistency and robustness will likely suffer if non-NSM compliant clients are allowed to
- participate in a session.
-
- There is no direct dependency for client implementations, as long as they
- can send and receive OSC.
- Some clients use `liblo` (the OSC library), which becomes a dependency if you choose to implement
- NSM-support with the provided header file `nsm.h` (`extras/nsm.h/nsm.h` in the git repository).
- Some clients use the provided single-file python library `pynsm` (`extras/pynsm/nsmclient.py` in the git repository)
- which has no dependencies outside the Python3 standard library.
-
-
- The aim of this project is to thoroughly define the behavior required of clients. Often the
- difficulty with other session-management approaches has been not in implementing code-support for
- them, but in not defining rules and behaviour clearly enough.
-
- As written above unambiguous rules are created by using RFC 2119 in this document. For the good of
- the user, these rules are meant to be followed and are non-negotiable. If an application does not
- conform to this specification it should be considered broken. Consistency across applications under
- session management is very important for a good user experience.
-
-
- == Client Behavior Under Session Management
-
- Most graphical applications make available to the user a common set of file operations, typically
- presented under a File or Project menu.
-
- These are: New, Open, Save, Save As, Close and Quit or Exit.
-
- The following sub-sections describe how these options should behave when the application is part of
- an NSM session. These rules only apply when session management is active, that is, after the
- `announce` handshake described in the <<NSM OSC Protocol>> section. In order to provide a
- consistent and predictable user experience, it is critically important for applications to adhere
- to these guidelines.
-
-
- === File Menu
-
-
- ==== New
-
- This option MAY empty/reset the current file or project (possibly after user confirmation).
- It MUST NOT allow the user to create a new project/file in another location.
-
-
- ==== Open
-
- This option MUST be disabled.
-
- The application MAY elect to implement an option called "Import into Session", which creates a
- copy of a file/project which is then saved at the session path provided by NSM.
-
-
- ==== Save
-
- This option should behave as normal, saving the current file/project as established by the NSM
- `open` message.
-
- This option MUST NOT present the user with a choice of where to save the file.
-
-
- ==== Save As
-
- This option MUST be disabled.
-
- The application MAY elect to implement an option called 'Export from Session', which
- creates a copy of the current file/project which is then saved in a user-specified location outside
- of the session path provided by NSM.
-
-
- ==== Close (as distinguished from Quit or Exit)
-
- This option MUST be disabled unless its meaning is to disconnect the application from session
- management.
-
-
- ==== Quit or Exit
-
- This option MAY behave as normal (possibly asking the user to confirm exiting), or MAY do nothing
- to only allow quit from the session-manager control.
- When the client supports :optional-gui: this option SHOULD be replaced with hiding the client's GUI
- so a quit by window manager hides.
-
-
- === Data Storage
-
-
- ==== Internal Files
-
- All project specific data created by a client MUST be stored in the per-client storage area
- provided by NSM. This includes all recorded audio and MIDI files, snapshots, etc. Only global
- configuration items, exports, and renders of the project may be stored elsewhere (wherever the user
- specifies).
-
-
- ==== External Files
-
- Files required by the project but external to it (typically read-only data such as audio samples)
- SHOULD be referenced by creating a symbolic link within the assigned session area, and then
- referring to the symlink. This allows sessions to be archived and transported simply (e.g. with
- "tar -h") by tools that have no knowledge of the project formats of the various clients in the
- session. The symlinks thus created should, at the very least, be named after the files they refer
- to. Some unique component may be required to prevent collisions.
-
- ==== Session Root and Session Directories
-
- Client programs MUST NOT handle the following themselves. This section is background-information.
-
- NSM follows the link:https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html[XDG Base Directory Specifications]
-
- All existing and new sessions are directories below the session-root, which defaults to
- `$XDG_DATA_HOME/nsm/`, which usually results in `$HOME/.local/share/nsm/`.
-
- Each session directory contains a file `session.nsm` with one client per line `name:executable:UID\n`
- For example:
- ```
- JACKPatch:jackpatch:nBEIQ
- jack_mixer:jack_mixer:nTXHV
- Carla-Rack:carla-rack:nFAOD
- ```
- `nsmd` loads and saves this file, client names are their self-reported names.
- The file format is final and frozen. Additions or changes SHALL NOT be made.
-
- ===== Subdirectories / Hierarchical Structure
-
- Subdirectories MAY be made to organize sessions into meaningful structures, such as album/track or
- composer/genre/piece. For example: `Johann Sebastian Bach/Kantaten/Wie schön leuchtet der Morgenstern`.
- Which results in the same directory structure on disk. Session names can contain any characters that
- are supported by the underlying file system, usually UTF-8.
-
- Subdirectories are created by either `nsmd` itself or by the users themselves, through their file
- manager or a GUI (while the session is not open).
-
- The project_name from `/nsm/server/new s:project_name` accepts the format `a/b/c/d`.
-
- Any session itself MUST be a "leaf" in this directory tree. A session MUST NOT contain further
- session subdirectories: any directory that contains a file `session.nsm` is the final
- element in the hierarchy.
-
- ===== Write-Protection for Session Templates
-
- Write protection for a whole session directory can either happen by "accident" (files from
- another user, a network mount etc.) or on purpose, to protect a session template against accidental
- changes. The latter is possible with a recursive `chown`, `chmod` or `chattr -R +i session-dir`.
-
- nsmd itself just checks if `session.nsm` is read-only. In this case it will not send the save
- command to it's session clients. This does not prevent hypothetical problems when the user
- triggers a clients internal save command in a write protected directory. Clients SHOULD handle
- their write protected save files themselves.
-
- Advanced contraptions, like overlay filesystems or copy-on-write hardlinks to create read-only
- sessions without the clients noticing, are out of scope for nsm.
-
- ===== Lockfiles
-
- Because multiple `nsmd` can run at the same time we need to prevent accidental write-access to the
- same session by different nsm-daemons, and subsequently GUIs.
-
- Therefore each currently open session creates a lockfile under `$XDG_RUNTIME_DIR/nsm/` (usually
- `/run/user/XXXX/nsm/`) that tells `nsmd` to not open such a locked session. This directory gets
- cleaned by the operating system, preventing sessions to stay locked after e.g. a power failure.
-
- If the system is not XDG-compliant nsmd will try to fallback to `/run/user/XXXX`, which must exist
- according to the Linux Filesystem Hierarchy Standard. I this also fails the user has to
- set $XDG_RUNTIME_DIR manually to start nsmd.
-
- The lockfile is named after the simple session name combined with a numeric ID for the session
- root. It is possible that two `nsmd` opened two different session roots, both with the same simple
- session name, e.g. "my song". Lockfiles are able to distinguish between those and will not prevent
- access in this scenario. The numeric ID is a djb2 hash modulo (%) 65521 of the session root directory
- (see `src/file.cpp` function `simple_hash()`).
-
-
- The lockfile contains, on separate lines:
-
- * The absolute path to the session, including the root-dir, which could be overriden by `nsmd --session-root`, allowing two sessions of the same basic name in different roots.
- * the OSC URL of the server that runs this session, the same as `$NSM_URL`.
- * the PID of `nsmd`
-
- Example:
- ```
- /home/johann/.local/share/nsm/cantatas/easter1751
- osc.udp://myuser.localdomain:11287/
- 3022
- ```
-
- ===== Daemon Discovery
-
- Each running `nsmd`, per user, creates a state file under `$XDG_RUNTIME_DIR/nsm/d/` (usually
- `/run/user/XXXX/nsm/d/`) that can be used to look up running daemons, even if no session is loaded.
- The name of the file is `nsmd` PID and the files contain their daemons osc.udp URL that is
- compatible with the --nsm-url parameter of the GUI.
-
-
- This enables you to e.g. start nsmd at boot with a random free port. Server-control programs such
- as GUIs can then use this to look for running servers without requiring the user to look up and
- input an osc URL manually as command line parameter.
-
-
- == NSM OSC Protocol
-
- All message parameters are REQUIRED. All messages MUST be sent from the same socket as the `announce`
- message, using the `lo_send_from` method of liblo or its equivalent, as the server uses the return
- addresses to distinguish between clients.
-
-
- Clients MUST create thier OSC servers using the same protocol (UDP,TCP) as found in `NSM_URL`.
- `nsmd` itself is using UDP only.
-
-
-
- === Establishing a Connection
-
- ==== Announce
-
- At launch, the client MUST check the environment for the value of `NSM_URL`. If present, the client
- MUST send the following message to the provided address as soon as it is ready to respond to the
- `/nsm/client/open` event:
-
- [source%nowrap,OSC]
- ----
- /nsm/server/announce s:application_name s:capabilities s:executable_name i:api_version_major i:api_version_minor i:pid
- ----
-
- If `NSM_URL` is undefined, invalid, or unreachable, then the client should proceed assuming that
- session management is unavailable.
-
- `api_version_major` and `api_version_minor` must be the two parts of the version number of the NSM API
- as defined by this document.
-
- Note that if the application intends to register JACK clients, `application_name` MUST be the same as
- the name that would normally be passed to `jack_client_open`. For example, Non-Mixer sends
- "Non-Mixer" as its `application_name`. Applications MUST NOT register their JACK clients until
- receiving an `open` message; the `open` message will provide a unique client name prefix suitable for
- passing to JACK. This is probably the most complex requirement of the NSM API, but it isn't
- difficult to implement, especially if the application simply wishes to delay its initialization
- process briefly while awaiting the `announce` reply and subsequent `open` message.
-
- `capabilities` MUST be a string containing a colon separated list of the special capabilities the
- client possesses. e.g. `:dirty:switch:progress:`
-
- `executable_name` MUST be the executable name that the program was launched with. For C programs,
- this is simply the value of `argv[0]`. Note that hardcoding the name of the program here is not the
- same as using, as the user may have launched the program from a script with a different name using
- exec, or have created a symlink to the program. Getting the correct value in scripting languages
- like Python can be more challenging.
-
- .Available Client Capabilities
- [options="header", stripes=even]
- |===
-
- |Name | Description
-
- |switch | client is capable of responding to multiple `open` messages without restarting
- |dirty | client knows when it has unsaved changes
- |progress | client can send progress updates during time-consuming operations
- |message | client can send textual status updates
- |optional-gui | client has an optional GUI
-
- |===
-
-
- ==== Response
-
- The server will respond to the client's announce message with the following message:
-
- [source%nowrap,OSC]
- ----
- /reply "/nsm/server/announce" s:message s:name_of_session_manager s:capabilities
- ----
-
- `message` is a welcome message.
-
- The value of `name_of_session_manager` will depend on the implementation of the NSM server. It
- might say "New Session Manager", or it might say "Non Session Manager" etc. This is for display to
- the user.
-
- `capabilities` will be a string containing a colon separated list of special server capabilities.
-
- Presently, the server `capabilities` are:
-
- .Available Server Capabilities
- [options="header", stripes=even]
- |===
-
- |Name | Description
-
- |server-control | client-to-server control
- |broadcast | server responds to /nsm/server/broadcast message
- |optional-gui | server responds to optional-gui messages. This capability is always present and MUST be supported by any server implementation.
-
- |===
-
- A client should not consider itself to be under session management until it receives this response.
- For example, the Non applications activate their "SM" blinkers at this time.
-
- If there is an error, a reply of the following form will be sent to the client:
-
-
- [source%nowrap,OSC]
- ----
- /error "/nsm/server/announce" i:error_code s:error_message
- ----
-
- The following table defines possible values of `error_code`:
-
- .Response codes
- [options="header", stripes=even]
- |===
-
- |Code | Meaning
-
- |ERR_GENERAL | General Error
- |ERR_INCOMPATIBLE_API | Incompatible API version
- |ERR_BLACKLISTED | Client has been blacklisted.
-
- |===
-
-
- === Server to Client Control Messages
-
- Compliant clients MUST accept the client control messages described in this section. All client
- control messages REQUIRE a response. Responses MUST be delivered back to the sender (`nsmd`) from the
- same socket used by the client in its `announce` message (by using `lo_send_from`) AFTER the action has
- been completed or if an error is encountered. The required response is described in the subsection
- for each message.
-
- If there is an error and the action cannot be completed, then `error_code` MUST be set to a valid
- error code (see <<Error Code Definitions>>) and `message` to a string describing the problem
- (suitable for display to the user).
-
- The reply can take one of the following two forms, where path MUST be the `path` of the message being
- replied to (e.g. "nsm/client/save":
-
- [source%nowrap,OSC]
- ----
- /reply s:path s:message
- ----
-
- [source%nowrap,OSC]
- ----
- /error s:path i:error_code s:message
- ----
-
-
- ==== Quit
-
- There is no message for this. Clients will receive the Unix SIGTERM signal and MUST close cleanly
- IMMEDIATELY, without displaying any kind of dialog to the user and regardless of whether or not
- unsaved changes would be lost. When a session is closed the application will receive this signal
- soon after having responded to a `save` message.
-
-
- [#server-to-client-control-messages-open]
- ==== Open
-
- [source%nowrap,OSC]
- ----
- /nsm/client/open s:path_to_instance_specific_project s:display_name s:client_id
- ----
-
- `path_to_instance_specific_project` is a path name in the form client_name.ID, assigned to the
- client for storing its project data. The client MUST choose one of the four strategies below to
- save, so that every file in the session can be traced back to a client and, vice versa, a client
- name.ID can be used to look up all its files. (For example to clean up the session dir)
-
- * The client has no state and does not save at all
- ** and it MUST NOT misuse e.g. ~/.config to save session specific information e.g. synth-instrument settings
- * The client may use the path client_name.ID directly, resulting in a file client_name.ID in the session directory
- * The client may append its native file extension (e.g. `.json`) to the path client_name.ID
- * The client may use the path as directory, creating arbitrary files below, for example recorded .wav.
- ** 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).
- ** best case practice is to always use the same file names, for example `client_name.ID/savefile.json`
-
- If a project exists at the path, the client MUST immediately open it.
-
- If a project does not exist at the path, then the client MUST immediately create and open a new one
- at the specified path or, for clients which hold all their state in memory, store the path for
- later use when responding to the `save` message.
-
- No file or directory will be created at the specified path by the server. It is up to the client to
- create what it needs.
-
- For clients which HAVE NOT specified the `:switch:` capability, the `open` message will only be
- delivered once, immediately following the `announce` response.
-
- For clients which HAVE specified the `:switch:` capability, the client MUST immediately switch to the
- specified project or create a new one if it doesn't exist.
-
- Clients which are incapable of switching projects or are prone to crashing upon switching MUST NOT
- include `:switch:` in their capability string.
-
- If the user the is allowed to run two or more instances of the application simultaneously
- then such an application MUST PRE-PEND the provided `client_id` string, followed by "/", to any
- names it registers with common subsystems (e.g. JACK client names). This ensures that multiple
- instances of the same application can be restored in any order without scrambling the JACK
- connections or causing other conflicts.
-
- The provided `client_id` will be a concatenation of the value of `application_name` sent by the
- client in its `announce` message and a unique identifier.
-
- Therefore, applications which create single JACK clients can use the value of `client_id` directly
- as their JACK client name.
-
- Applications which register multiple JACK clients (e.g. Carla or Non-Mixer) MUST PRE-PEND
- `client_id` value, followed by "/", to the client names they register with JACK and the application
- determined part MUST be unique for that (JACK) client.
-
- For example, Carla is a plugin-host that loads each plugin as JACK client.
- Suitable JACK client names are: `carla-jack-multi.nBAF/ZynAddSubFx` or `carla-jack-multi.nBAF/Helm`
- Please note that ZynAddSubFx and Helm are *not ports* but clients. Each of them can have any number
- of audio and midi ports below them.
-
- Note that this means that the application MUST NOT register with JACK (or any
- other subsystem requiring unique names) until it receives an `open` message from NSM. Likewise,
- applications with the `:switch:` capability should close their JACK clients and re-create them with
- using the new `client_id` (renaming JACK-clients is not possible, only ports).
-
- A response is REQUIRED as soon as the open operation has been completed. Ongoing progress MAY be
- indicated by sending messages to `/nsm/client/progress`.
-
-
- ===== Response
-
- The client MUST respond to the 'open' message with:
-
- [source%nowrap,OSC]
- ----
- /reply "/nsm/client/open" s:message
- ----
-
- Or
-
- [source%nowrap,OSC]
- ----
- /error "/nsm/client/open" i:error_code s:message
- ----
-
-
- .Response codes
- [options="header", stripes=even]
- |===
-
- |Code | Meaning
-
- |ERR | General Error
- |ERR_BAD_PROJECT | An existing project file was found to be corrupt
- |ERR_CREATE_FAILED | A new project could not be created
- |ERR_UNSAVED_CHANGES | Unsaved changes would be lost
- |ERR_NOT_NOW | Operation cannot be completed at this time
-
- |===
-
-
- ==== Save
-
- [source%nowrap,OSC]
- ----
- /nsm/client/save
- ----
-
- This message will only be delivered after a previous `open` message, and may be sent any number of
- times within the course of a session (including zero, if the user aborts the session).
-
- ===== Response
-
- [source%nowrap,OSC]
- ----
- /reply "/nsm/client/save" s:message
- ----
-
- Or
-
- [source%nowrap,OSC]
- ----
- /error "/nsm/client/save" i:error_code s:message
- ----
-
-
- .Response codes
- [options="header", stripes=even]
- |===
-
- |Code | Meaning
-
- |ERR | General Error
- |ERR_SAVE_FAILED | Project could not be saved
- |ERR_NOT_NOW | Operation cannot be completed at this time
-
- |===
-
-
- === Server to Client Informational Messages
-
- ==== Session is Loaded
-
- Accepting this message is optional. The intent is to signal to clients which may have some
- interdependence (say, peer to peer OSC connections) that the session is fully loaded and all their
- peers are available. Most clients will not need to act on this message. This message has no meaning
- when a session is being built or run; only when it is initially loaded. Clients who intend to act
- on this message MUST NOT do so by delaying initialization waiting for it.
-
- [source%nowrap,OSC]
- ----
- /nsm/client/session_is_loaded
- ----
-
- This message does not require a response.
-
-
- ==== Show Optional Gui
-
- If the client has specified the `optional-gui` capability, then it may receive this message from the
- server when the user wishes to change the visibility state of the GUI. It doesn't matter if the
- optional GUI is integrated with the program or if it is a separate program \(as is the case with
- SooperLooper\). When the GUI is hidden, there should be no window mapped and if the GUI is a
- separate program, it should be killed.
-
- [source%nowrap,OSC]
- ----
- /nsm/client/show_optional_gui
- ----
-
- [source%nowrap,OSC]
- ----
- /nsm/client/hide_optional_gui
- ----
-
- This message does not require a response.
-
-
-
- === Client to Server Informational Messages
-
- ==== Optional GUI
-
- If the client has specified the `optional-gui` capability, then it MUST send this message whenever
- the state of visibility of the optional GUI has changed. It also MUST send this message after its
- announce message to indicate the initial visibility state of the optional GUI.
-
- The client SHOULD always start hidden, if not saved as visible. That implies the first load, after
- adding to the session, SHOULD always be hidden.
-
- It is the responsibility of the client to remember the visibility state of its GUI across session
- loads.
-
- [source%nowrap,OSC]
- ----
- /nsm/client/gui_is_hidden
- ----
-
- [source%nowrap,OSC]
- ----
- /nsm/client/gui_is_shown
- ----
-
- No response will be delivered.
-
-
- ==== Progress
-
- [source%nowrap,OSC]
- ----
- /nsm/client/progress f:progress
- ----
-
- For potentially time-consuming operations, such as `save` and `open`, progress updates may be
- indicated throughout the duration by sending a floating point value between 0.0 and 1.0, 1.0
- indicating completion, to the NSM server.
-
- The server will not send a response to these messages, but will relay the information to the user.
-
- Note that even when using the `progress` feature, the final response to the `save` or `open`
- message is still REQUIRED.
-
- Clients which intend to send progress messages MUST include `:progress:` in their `announce`
- capability string.
-
-
- ==== Dirtiness
-
- [source%nowrap,OSC]
- ----
- /nsm/client/is_dirty
- ----
-
- [source%nowrap,OSC]
- ----
- /nsm/client/is_clean
- ----
-
- Some clients may be able to inform the server when they have unsaved changes pending. Such clients
- may optionally send `is_dirty` and `is_clean` messages.
-
- Clients which have and use this capability MUST include `:dirty:` in their `announce` capability string.
-
- ==== Status Messsages
-
- [source%nowrap,OSC]
- ----
- /nsm/client/message i:priority s:message
- ----
-
- Clients may send miscellaneous status updates to the server for possible display to the user. This
- may simply be chatter that is normally written to the console. `priority` MUST be a number from 0
- to 3, 3 being the most important.
-
- Clients which have and use this capability MUST include `:message:` in their `announce` capability
- string.
-
-
- === Error Code Definitions
-
- .Error Code Definitions
- [options="header", stripes=even]
- |===
-
- |Symbolic Name | Integer Value
-
- |ERR_GENERAL | -1
- |ERR_INCOMPATIBLE_API | -2
- |ERR_BLACKLISTED | -3
- |ERR_LAUNCH_FAILED | -4
- |ERR_NO_SUCH_FILE | -5
- |ERR_NO_SESSION_OPEN | -6
- |ERR_UNSAVED_CHANGES | -7
- |ERR_NOT_NOW | -8
- |ERR_BAD_PROJECT | -9
- |ERR_CREATE_FAILED | -10
-
- |===
-
- === Client to Server Control
-
- If the server publishes the `:server-control:` capability, then clients can also initiate action by
- the server. For example, a client might implement a 'Save All' option which sends a
- `/nsm/server/save` message to the server, rather than requiring the user to switch to the session
- management interface to effect the save.
-
-
- === Server Control API
-
- The session manager not only manages clients via OSC, but it is itself controlled via OSC messages.
- The server responds to the following messages.
-
- All of the following messages will be responded to, at the sender's address, with one of the two
- following messages:
-
- [source%nowrap,OSC]
- ----
- /reply s:path s:message
- ----
-
- [source%nowrap,OSC]
- ----
- /error s:path i:error_code s:message
- ----
-
- The first parameter of the reply is the path to the message being replied to. The `/error` reply
- includes an integer error code (non-zero indicates error). `message` will be a description of the
- error.
-
- The possible errors are:
-
- .Responses
- [options="header", stripes=even]
- |===
-
- |Code |Meaning
-
- |ERR_GENERAL | General Error
- |ERR_LAUNCH_FAILED | Launch failed
- |ERR_NO_SUCH_FILE | No such file
- |ERR_NO_SESSION | No session is open
- |ERR_UNSAVED_CHANGES | Unsaved changes would be lost
-
- |===
-
-
- * `/nsm/server/add s:executable_name`
- ** Adds a client to the current session.
-
- * `/nsm/server/save`
- ** Saves the current session.
-
- * `/nsm/server/open s:project_name`
- ** Saves the current session and loads a new session.
-
- * `/nsm/server/new s:project_name`
- ** Saves the current session and creates a new session.
-
- * `/nsm/server/duplicate s:new_project`
- ** Saves and closes the current session, makes a copy, and opens it.
-
- * `/nsm/server/close`
- ** Saves and closes the current session.
-
- * `/nsm/server/abort`
- ** Closes the current session WITHOUT SAVING
-
- * `/nsm/server/quit`
- ** Saves and closes the current session and terminates the server.
-
- * `/nsm/server/list`
- ** Lists available projects. One `/reply` message will be sent for each existing project.
- ** Afer listing the last session one final `/reply` with `/nsm/server/list, ""` will be send. That is an empty string.
-
-
- ==== Client to Client Communication
-
- If the server includes `:broadcast:` in its capability string, then clients may send broadcast
- messages to each other through the NSM server. Clients may send messages to the server at the path
- `/nsm/server/broadcast`.
-
- The format of this message is as follows:
-
- [source%nowrap,OSC]
- ----
- /nsm/server/broadcast s:path [arguments...]
- ----
-
- The message will then be relayed to all clients in the session at the path `path` (with the
- arguments shifted by one).
-
- For example the message:
-
-
- [source%nowrap,OSC]
- ----
- /nsm/server/broadcast /tempomap/update "0,120,4/4:12351234,240,4/4"
- ----
-
- Would broadcast the following message to all clients in the session (except for the sender), some
- of which might respond to the message by updating their own tempo maps.
-
-
- [source%nowrap,OSC]
- ----
- /tempomap/update "0,120,4/4:12351234,240,4/4"
- ----
-
- The Non programs use this feature to establish peer to peer OSC communication by symbolic names
- (client IDs) without having to remember the OSC URLs of peers across sessions.
-
-
- == API Versions and Behaviour Changes
-
- Here we will document all technical changes or differences in behaviour together with their API and
- project version numbers. The term "original" refers to Non Session Manager and "new" refers to New
- Session Manager.
-
- Version numbers follow link:https://semver.org/spec/v2.0.0.html[Semantic Versioning 2.0.0]
-
- .Semantic Versioning Scheme
- ```
- Given a version number MAJOR.MINOR.PATCH, increment the:
-
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards compatible manner, and
- PATCH version when you make backwards compatible bug fixes.
- ```
-
-
- .NSM Version Numbers
- [options="header", stripes=even]
- |===
-
- |Subject | Version
-
- |Non Session Manager at moment of fork | 1.2 (June 2020)
- |Non Session Manager API | 1.0 link:https://github.com/original-male/non/blob/master/session-manager/src/nsmd.C[NON nsmd.C]
- |Original API Document | 1.0 link:http://non.tuxfamily.org/nsm/API.html[non.tuxfamily.org/nsm/API.html]
- |New Session Manager | 1.6.0
- |New Session Manager API | 1.1.2 link:https://github.com/jackaudio/new-session-manager/blob/master/src/nsmd.cpp[NEW nsmd.cpp]
- |New API Document | 1.5.0 link:#[Here]
-
- |===
-
-
- === Guidelines
-
- The most important factor in decision making is to keep client compatibility at 100%.
- No client will ever receive an unrequested OSC message except those in API 1.0.0.
-
- Messages that drastically change existing `/nsm/client/` or `/nsm/server` behaviour require an
- inrecement to `API_VERSION_MAJOR`, which we want to avoid.
-
- `nsmd` checks if the clients `API_VERSION_MAJOR` is greater than its own and refuses the client
- with `ERR_INCOMPATIBLE_API`.
-
- All changes (that concern client/server behaviour) that increment `API_VERSION_MINOR` will be
- request-only or gated by new capabilities (e.g. `:optional-gui:`). `nsmd` will not send any
- messages if a capability was not sent by the client in <<Announce,`announce`>>. This includes
- mostly optional features about requesting extra information.
-
- New actions for server-control, for example a hypothetical `/nsm/server/save_as`, which would be
- triggered by the client and would only be *answered* by the server ("no unrequested message") will
- increment `API_VERSION_MINOR`.
-
- All changes that increment `API_VERSION_PATCH` will not have any effect on behaviour, except to
- fix clear problems, where "problem" is defined by having a different effect than described in this
- document, which includes technical problems such as crashes.
-
- All messages regarding GUI-communication that start with `/nsm/gui/...` were undocumented in API
- 1.0.0 and only used by `non-session-manager` / `nsm-legacy-gui`. Until properly documented in this
- document this part of the API is considered unstable and may change at any time without notice.
- However, when changing already existing messages and behaviour it MAY increment `API_VERSION_MINOR`
- or `API_VERSION_PATCH`. In that case it will appear in the list below.
-
- Last factor of compatibility is that any unknown message sent to `nsmd` will just print a warning
- message to stdout, but will otherwise be ignored. This secures a stable server, even when a client
- misbehaves and sends too-new messages outside of announced :capabilites:
-
- === Changes in API Version 1.1.0
-
- Rewritten API document without code changes to adapt to existing code or existing client behaviour:
-
- * Changed versioning scheme to Semantic Versioning with three positions Major.Minor.Patch
- * <<Quit or Exit>> SHOULD hide instead of exiting when :optional-gui: is supported and MAY not
- act on the quit through menu otherwise.
- * <<#server-to-client-control-messages-open,Open>>: Make clear that there are only certain
- possibilities for save paths. We added MUST because the rule was just implied before.
- * <<#server-to-client-control-messages-open,Open>>: Make clear that the delimiter for
- multi-jack clients is "/".
- * <<Optional GUI>> SHOULD start hidden, always after a fresh add to the session. After that saving
- the visibility state may override it for next time.
- * <<Progress>> MUST be announced in :capabilities: . Before there was a lower case "should",
- which means nothing. Parallel-examples in the specs cleary say that supporting optional features must be announced first.
- ** Same for <<Dirtiness>> and <<Status Messsages>>.
- * <<Status Messsages>> have priority numbers between 0 and 3, so they MUST send that.
- It was never an arbitrary value.
-
- Code changes:
-
- * <<Server Control API>>: `/nsm/server/list` chain of single OSC messages, one for each session,
- is now finalized with sending and empty string "" as session name. Previously this was just
- a symbolically irrelevant console message `"Done."`
- * Replies to `/nsm/server/save` etc. will now be sent back to the sender and not falsely to the last
- client who replied to `/nsm/client/save`. This alone would only require API_VERSION_PATCH
- increment, but we are already incrementing minor.
- * <<Server Control API>>: `/nsm/server/add` was replying with an undocumented error code on success.
- Instead, as this document always specificed, it now sends `"/reply", path, "Launched."`.
- Again, this would have been just API_VERSION_PATCH on its own.
-
- Undocumented (Unstable) `/nsm/gui` protocol
-
- * Send client status after a GUI attaches to running server. This
- was not happening before, but it was the intention. It was just broken in nsmd.cpp. This alone
- would only require API_VERSION_PATCH increment, but we are already incrementing minor.
- * Send label "launch error!" when a program is added (or loaded) that
- does not exist in $PATH. This requires no adaptation of any client, server or GUI because labels
- are arbitrary already and this is not meant for automatic parsing, but as user information.
- * `/nsm/gui/session/name` will now always send the same parameter format, regardless of how the session was opened:
- simple-session-name, relative session path with subdirs below session-root.
- * When a GUI announces itself to nsmd it will receive the absolute path to the session directory
- through the message `/nsm/gui/session/root`. This is not a new addition but was already in
- non-session-manager git.
-
- === Changes in API Version 1.1.1
-
- * Server-capability :optional-gui: is now mandatory for SERVER implementations. Reasoning:
- This is an important core feature of NSM and thus will be treated as such by guaranteeing it to exist.
- After looking at all currently known clients and server-implementations it turns out that all servers
- support :optional-gui: and the vast majority of clients not only support it, but actually assume it
- and do _not_ test for the server capability, as it was written in this document.
- There are now two choices: Adjust this document to the (good) reality or consider all clients broken.
- Summary: We consider this API document wrong and therefore fix it, thus increasing API version
- patch-level from 1.1.0 to 1.1.1
-
- * Add API-section "Subdirectories / Hierarchical Structure" that explains the session directory.
- This behaviour was already the case for nsm-legacy-gui and nsmd 1.5.0 was patched to adhere to this
- behaviour more strictly as well, removing false session entries in 3rd party clients such as Agordejo.
-
- === Changes in API Version 1.1.2
-
- * nsmd now follows the XDG Base Directory Specifications for it's session root and lock files. This
- if of no consequence to clients but required documentation nevertheless, which was described as
- "background information" in the chapters for lock files and daemon disovery.
-
- * nsmd now gracefully handles read-only `session.nsm` files. This theoretically enables read-only
- sessions and session-templates. It is included in the patch-level because this was marked as a
- long-standing `FIXME` in the code by the original author. Or in other words: just a bug fix.
|