View Source SuperCollider.SoundServer (SuperCollider v0.1.5)

GenServer for communicating with scserver or supernova.

This module is a:

  • GenServer which is used to communicate with SuperCollider's scserver or supernova
  • Struct which holds the server's basic state and configuration.

basic-configuration

Basic configuration

Buy default, it looks for scynth at 127.0.0.1 or localhost on port 57110.

starting-a-server

Starting a server

alias SuperCollider.SoundServer
{:ok, pid} = GenServer.start_link(SoundServer, SoundServer.new(opts))

requesting-the-server-s-status

Requesting the server's status

SoundServer.command(pid, :status)

# If scynth returned an OSC status response message, you can access it by fetching the SoundServer's state, accessing the responses map and status key:

SoundServer.state(pid).responses[:status]

# Returns:
# [
#   {"unused", 1},
#   {"number of unit generators", 0},
#   {"number of synths", 0},
#   {"number of groups", 2},
#   {"number of loaded synth definitions", 109},
#   {"average percent CPU usage for signal processing", 0.026054037734866142},
#   {"peak percent CPU usage for signal processing", 0.07464269548654556},
#   {"nominal sample rate", 44100.0},
#   {"actual sample rate", 44099.97125381111}
# ]

play-a-sine-wave-ugen

Play a sine wave UGen

# Play a sine wave UGen on node 600, with a frequency of 300
SoundServer.command(pid, :s_new, ["sine", 600, 1, 1, ["freq", 300]])

# Stop the sine wave by freeing node 600
SoundServer.command(pid, :n_free, 600)

Link to this section Summary

Functions

The SoundServer struct colds the servers basic state

Returns a specification to start this module under a supervisor.

Sends an OSC command to SuperCollider (scynth or supernova).

When sending calls to scserver though UDP, a response message may be returned in the following format

The init callback accepts %SoundServer{} struct holding the initial configuration and state. If none is provided, defaults are used.

Checks if scsynth is loaded by calling scsynth_booted?/1. If not it will attempt to boot it asynchronously using Task.async/1.

A convience function to create a new SoundServer struct.

Open's a UDP connection. Unless a port number is provided, by default it will use port 0.

Runs the server. By default, this function is executed when init is called.

Checks if scsynth or supernova is booted.

Returns the current state of the server.

Link to this section Functions

Link to this function

%SuperCollider.SoundServer{}

View Source (struct)

The SoundServer struct colds the servers basic state:

  • ip: the IP address of scserver. This defaults to '127.0.0.1'
  • hostname: the hostname of the server. This defaults to 'localhost'.
  • port: the port used to communicate with scserver. This defaults to 57110.
  • socket: the UDP socket used to communicate with scserver, once the connection is open.
  • type: which SuperCollider server is being used, accepts :scsynth (default) or :supernova (multicore)

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

command(pid, command_name)

View Source

Sends an OSC command to SuperCollider (scynth or supernova).

SuperCollider.SoundServer.command(pid, :version) will sendthe OSC 'version' command.

Optionally accepts arguments, depending on the command being called.

Commands must be a valid commmand (function in the SuperCollider.SoundServer.Command module) and match it's arity, otherwise an {:error, reason} tuple ie returned.

Link to this function

command(pid, command_name, args)

View Source

When sending calls to scserver though UDP, a response message may be returned in the following format:

{:udp, process_port, ip_addr, port_num, osc_response}

The handle_info/2 callback will forward these messages to Response.process_osc_message/2 for handling. The handler code must return the updated SoundServer struct for a valid state to be maintained.

To get the messages, use SuperCollider.response().

Link to this function

init(soundserver \\ %__MODULE__{})

View Source

The init callback accepts %SoundServer{} struct holding the initial configuration and state. If none is provided, defaults are used.

Calls the run/1 function which will check if SuperCollider is loaded and start OSC communication.

See the run/1 function for more details

Link to this function

maybe_boot_scsynth(soundserver)

View Source

Checks if scsynth is loaded by calling scsynth_booted?/1. If not it will attempt to boot it asynchronously using Task.async/1.

Currently attempts to start scynth or supernova at the following locations:

  • Mac: /Applications/SuperCollider.app/Contents/Resources/
  • Linux: /usr/local/
  • Windows: \Program Files\SuperCollider\

TODO: The location of the scysnth binary is currently set to the fixed locations above, but this will need to be moved out into a config or using different search strategies for different OSes.

A convience function to create a new SoundServer struct.

The struct holds the basic state and configuration.

The default values can be overrided by providing a keyword list using the same keys used in the struct. For example:

  SoundServer.new(hostname: 'othersoundserver')

will override the default hostname of 'localhost'.

For more information, see the SoundServer struct documentation.

Open's a UDP connection. Unless a port number is provided, by default it will use port 0.

Uses :gen_udp.open from Erlang which associates a UDP port number with the calling process (this GenServer).

Link to this function

run(soundserver \\ %__MODULE__{})

View Source

Runs the server. By default, this function is executed when init is called.

This function:

  • checks if server is loaded, otherwise attempts to boot it
  • opens a USP socket for Open Sound Communication (OSC) communication with the server.
Link to this function

scsynth_booted?(soundserver)

View Source

Checks if scsynth or supernova is booted.

It does this by sending the OSC command '/status' through the previously opened UDP port to the address that scsynth is expected.

It then waits up to 5 seconds to see if a UDP packet is returned.

This function returns:

  • true if if a '/status.reply' message was recieved via UDP.
  • false if either a non-compliant message is recieved or no message is recieved after 5 seconds. In this case the scsynth has been considered not to be loaded.

Note: an UDP socket must be set on the %SoundServer{} state, e.g.:

soundserver =
  %SuperCollider.SoundServer{
    socket: #Port<0.8>, # Socket established here, otherwise this would be nil
    ip: '127.0.0.1',
    hostname: 'localhost',
    port: 57110,
    type: :scsynth,
    responses: %{}
  }

SuperCollider.SoundServer.scsynth_booted?(soundserver)
# Returns true if booted

If you don't have a curently opened socket, you can get one by calling SoundServer.open/1, e.g.:

{:ok, socket} = SoundServer.open()

soundserver = SoundServer.new(socket: socket)

# Returns SoundServer struct with socket populated:
# %SuperCollider.SoundServer{
#   socket: #Port<0.9>,
#   ip: '127.0.0.1',
#   hostname: 'localhost',
#   port: 57110,
#   type: :scsynth,
#   responses: %{}
# }

SuperCollider.SoundServer.scsynth_booted?(soundserver)

# If already booted returns true
# 11:53:43.734 [info] scsynth - already booted ✅
# true

Sockets are automatically created when SoundServer is booted in the typical way through SoundServer.start_link or SuperCollider.start.

Starts the SuperCollider.SoundServer GenServer.

You can override the default configuration by passing a keyword list with the new values. Currently the following can be set:

  • ip: the IP address of scserver. This defaults to '127.0.0.1'
  • hostname: the hostname of the server. This defaults to 'localhost'.
  • port: the port used to communicate with scserver. This defaults to 57110.
  • socket: the UDP socket used to communicate with scserver, once the connection is open.

example

Example

# Start SoundServer with default configuration
{:ok, pid} = SuperCollider.SoundServer.start_link()

# Start SoundServer specifying scynth's port to 57000
{:ok, pid} = SuperCollider.SoundServer.start_link(port: 57000)

Returns the current state of the server.

For example, calling SuperCollider.SoundServer.state(pid) will return the populated state struct, which includes configuration and any scynth OSC message responses stored in the reponses key:

%SuperCollider.SoundServer{
  ip: '127.0.0.1',
  hostname: 'localhost',
  port: 57110,
  socket: #Port<0.7>,
  responses: %{
    fail: ["/n_free", "Node 100 not found"],
    status: [
      {"unused", 1},
      {"number of unit generators", 0},
      {"number of synths", 0},
      {"number of groups", 2},
      {"number of loaded synth definitions", 109},
      {"average percent CPU usage for signal processing", 0.026054037734866142},
      {"peak percent CPU usage for signal processing", 0.07464269548654556},
      {"nominal sample rate", 44100.0},
      {"actual sample rate", 44099.97125381111}
    ],
    version: [
      {"Program name. May be "scsynth" or "supernova".", "scsynth"},
      {"Major version number. Equivalent to sclang's Main.scVersionMajor.", 3},
      {"Minor version number. Equivalent to sclang's Main.scVersionMinor.", 13},
      {"Patch version name. Equivalent to the sclang code "." ++ Main.scVersionPatch ++ Main.scVersionTweak.",
      ".0"},
      {"Git branch name.", "Version-3.13.0"},
      {"First seven hex digits of the commit hash.", "3188503"}
    ]
  }
}