non/session/doc/NSM.mu

493 lines
17 KiB
Plaintext

! title Non Session Management API
! author Jonathan Moore Liles #(email,male@tuxfamily.org)
! date August 1, 2010
-- Table Of Contents
: Non Session Management API version 0.7
The Non Session Management API is an API for session management used
by the various parts of the Non music production suite. It comprises
a simple OSC based protocol which can easily be implemented by other
applications. NSM provides robust session management, including
interactive features.
The Non project contains an implementation of the NSM server API
called `nsmd` which can be controlled by the `non-session-manager`
GUI, but the same server API can easily be implemented by other
session managers (such as LADISH).
The only dependency for clients `liblo` (the OSC library), which
several Linux audio applications already link to or plan to link to
in the future.
The aim of this project is to thoroughly define the behavior
required of clients. This is an area where other attempts at session
management (LASH and JACK-Session) have failed. Often the difficulty
with these previous system been, not in implementing support for
them, but in attempting to interpret the confusing and ambiguous API
documentation. For this reason, all LASH support has been removed
from Non.
You *WILL* see a lot of unambiguous language in this document. 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 #(ref,NSM OSC Protocol) section).
In order to provide a consistent and predictable user experience, it
is important for applications to adhere to these guidelines.
::: New
This option may empty\/reset the current file or project (possibly
after user confirmation). *UNDER NO CIRCUMSTANCES* should it allow
the user to create a new project\/file in another location.
::: Open
This option should be disabled.
The application may, however, elect to implement an option called
'Import into Session', creates a copy of a file\/project which is
then saved in 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.
*UNDER NO CIRCUMSTANCES* should this option present the user with a
choice of where to save the file!
::: Save As
This option should be disabled.
The application may, however, 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 should be disabled, unless its meaning is to disconnect
the application from session management.
::: Quit or Exit
This option may behave as normal (even possibly asking the user to
confirm exiting).
:: 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 (the server uses the return
addresses to distinguish between clients).
::: Establishing a Connection
:::: Announce
When started clients *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:
> /nsm/server/announce s:application_name s:capabilities 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 by 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.
`capabilities` *MUST* be a string containing a colon separated list
of the special capabilities the client
possesses. e.g. ":dirty:switch:progress:"
// Available Client Capabilities
[[ 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
[[ status, client can send textual status updates
:::: Response
The server will respond to the client's `announce` with the following message:
> /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 "Non Session Manager",
or it might say "LADISH".
`capabilities` will be a string containing a colon separated list of
special server capabilities.
Presently, the server `capabilities` are:
// Available Server Capabilities
[[ Name, Description
[[ server_control, client-to-server control
A client should not consider itself to be under session management
until it receives this response (the Non programs activate their
"SM" blinkers at this time.)
If there is an error, a reply of the following form will be sent to
the client:
> /error "/nsm/server/announce" i:error_code s:error_message
The following table defines possible values of `error\_code`:
// Response codes
[[ 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 (NSM)
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 #(fig,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"):
> /reply s:path s:message
> /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).
:::: Open
> /nsm/client/open s:path_to_instance_specific_project s:client_id
The client *MUST* open an existing project, or create new one if one
doesn't already exist, at `path\_to\_instance_specific\_project`
If the path provided doesn't exist, then the client *MUST*
immediately create and open a new file\/project at the specified
path (whether that means creating a single file or a project
directory).
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.
The client may append to the path, creating a subdirectory,
e.g. '/song.foo' or simply append the client's native file extension
(e.g. '.non' or '.XML'). The same transformation *MUST* be applied
to the name when opening an existing project, as NSM will only
provide the instance specific part of the path.
For clients which *HAVE NOT* specified the 'switch' capability, the
`open` message will only be delivered once, immediately after the
'announce' response.
For client 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 (that is to say, there is no technical
limitation preventing them from doing so, even if it doesn't make
sense to the author), then such an application *MUST* prepend the
provided `client\_id` string to any names it registers with common
subsystems (e.g. JACK client names). This ensures that the 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. Non-Mixer) *MUST* prepend `client_id` value to the
client names they register with JACK and the application determined
part *MUST* be unique for that (JACK) client.
For example, a suitable JACK client name would be:
> $CLIENT_ID/track-1
A response is *REQUIRED* *AFTER* the load\/new 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:
> /reply "/nsm/client/open" s:message
Or
> /error "/nsm/client/open" i:error_code s:message
// Response Codes
[[ 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
> /nsm/client/save
The client *MUST* immediately save the current application specific
project data to the project path previously established in the
'open' message. *UNDER NO CIRCUMSTANCES* should a dialog be
displayed to the user (giving a choice of where to save, etc.)
::::: Response
The client *MUST* respond to the 'save' message with:
> /reply "/nsm/client/save" s:message
Or
> /error "/nsm/client/save" i:error_code s:message
// Response Codes
[[ 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 interdependency (say, peer to peer OSC
connections) that the session is fully loaded and all their peers
are available.
> /nsm/client/session_is_loaded
This message does not require a response.
::: Client to Server Informational Messages
These are optional messages which a client can send to the NSM
server to inform it about the client's status. The client should not
expect any reply to these messages. If a client intends to send a
message described in this section, then it *MUST* add the
appropriate value to its `capabilities` string when composing the
`announce` message.
:::: Progress
> /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 should include
`:progress:` in their `announce` capability string.
:::: Dirtiness
> /nsm/client/is_dirty
> /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 this capability should include `:dirty:` in their
`announce` capability string.
:::: Status Messages
> /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` should be a number from 0 to 3, 3
being the most important.
Clients which have this capability should include `:message:` in their
`announce` capability string.
::: Error Code Definitions
// Error Code Definitions
[[ 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 back to the sender's address
with one of the two following messages:
> /reply s:path s:message
> /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
[[ 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:path_to_executable
Adds a client to the current session.
= /nsm/server/save
Saves the current session.
= /nsm/server/load 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/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/duplicate s:new_project
Saves and closes the current session, creates a complete copy of
it as `new_project` and opens it. The existing project should ideally be
a lightweight template, as copying any audio data could be very time
consuming.
= /nsm/server/list
Lists available projects. One `\/reply` message will be sent for each existing project.
# = /nsm/server/client/list
# Lists clients in the current session, their client IDs and statuses
# = /nsm/server/ve
:::: 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
`\/broadcast`.
The format of this message is as follows:
> /nsm/server/broadcast s:path [other parameters...]
The message will then be relayed to all clients in the session at
the path given in the `path` parameter and with the other parameters
shifted forward by one.
For example the message:
> /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.
> /tempomap/update "0,120,4/4:12351234,240,4/4"
Clients may use this feature to establish peer to peer OSC
communication with symbolic names without having to remember the OSC
URLs of peers.