This page was generated from examples/supercollider-objects/server-examples.ipynb.
Server
[ ]:
import sc3nb as scn
The SCServer
class is the central interface for
controlling the SuperCollider audio server process
managing SuperCollider Objects
using OSC for outgoing and incoming packets
To achieve all this the SCServer is
registered as a client to the SuperCollider audio server process (scsynth) and exchanging SuperCollider Commands with the server process
and also running an OSC server in python which can communicate via OSC with scsynth and sclang.
For information about how to communicate using OSC see the OSC communication notebook. This notebook focuses on using the SCServer
class for interacting with scsynth
Starting the Server
The most convienent way is to use the default sc3nb SCServer
instance
[ ]:
sc = scn.startup()
[ ]:
sc.server
However you can also use the SCServer class directly
The server connection can be created
locally using
boot
, which will start a scsynth process and connect to it orremote using
remote
for connecting to an already running scsynth process
[ ]:
serv = scn.SCServer()
serv
[ ]:
serv.boot()
Notice how the SCServer
always tries to boot using the default SuperCollider audio server port 57110. But this port is already used by sc.server
and thus the SCServer
tries to connect to the already running instance using SCserver.remote
. This enables a user to share the same scsynth instance with other users and/or use it from other notebooks. If the port to be used is explicitly specified the SCServer
instance will fail instead of connecting.
The SCServer
will register to the scsynth process using SCServer.notify()
Let’s look how many clients are allowed and what the client_id
s and the corresponding default_group
s of the SCServer instances are.
[ ]:
print(f"The scsynth process of this SCServer instance allows {sc.server.max_logins} clients to login.")
[ ]:
print(f"sc.server has client id {sc.server.client_id} and the default Group {sc.server.default_group}")
[ ]:
print(f"serv has client id {serv.client_id} and the default Group {serv.default_group}")
However also note that the instances use different ports meaning they are able to independendly send and receive OSC packets
[ ]:
sc.server.connection_info()
and also note that serv
is not connected to sclang but has the same connection info for scsynth.
[ ]:
serv.connection_info()
A Synth running on the SuperCollider audio server will be visible to all connected clients
[ ]:
serv_synth = scn.Synth("s2", {"amp": 0.05, "pan": -1, "freq": 100}, server=serv)
[ ]:
default_synth = scn.Synth("s2", {"amp": 0.05, "pan": 1, "freq": 440}) # no need to specify sc.server as server argument
This also includes sclang, which is another client of the scsynth process
[ ]:
%sc ~sclang_synth = Synth("s2", [\amp, 0.1])
[ ]:
sc.server.dump_tree()
This also means freeing all Synths at once can be done with each client
[ ]:
sc.server.free_all()
# serv.free_all()
# %sc s.freeAll
[ ]:
sc.server.dump_tree()
and quitting one server also quits the others.
[ ]:
serv.quit()
[ ]:
sc.server
Let’s reboot the default server
[ ]:
sc.server.reboot()
More information about multi client setups can be found in the SuperCollider documentation.
Configuring Server options
Startup options of the SCServer
instance can be set via ServerOptions
, which can be passed as argument when starting the SCServer
The default ServerOptions in sc3nb are:
[ ]:
scn.ServerOptions()
Getting Information
The SCServer
instance provides various kinds of information
What nodes are currently running
[ ]:
sc.server.dump_tree()
[ ]:
sc.server.query_tree()
The current status of the server, acquired via the
/status
OSC command
[ ]:
sc.server.status()
which can also be accessed directly via properties
[ ]:
sc.server.nominal_sr
[ ]:
sc.server.num_synthdefs
the version of the SC3 server process, acquired via the
/version
OSC command
[ ]:
sc.server.version()
the address of the SuperCollider audio server
[ ]:
sc.server.addr
The connection info
[ ]:
sc.server.connection_info()
other runtime properties of the Server
[ ]:
sc.server.has_booted
[ ]:
sc.server.is_running
[ ]:
sc.server.client_id
[ ]:
sc.server.max_logins
[ ]:
sc.server.default_group
[ ]:
sc.server.output_bus
[ ]:
sc.server.input_bus
Controlling Volume
[ ]:
syn = scn.Synth("s2")
[ ]:
sc.server.volume
[ ]:
scn.dbamp(sc.server.volume)
[ ]:
sc.server.muted
[ ]:
sc.server.muted = True
[ ]:
sc.server.volume = -10.0
[ ]:
scn.dbamp(sc.server.volume)
[ ]:
sc.server.muted = False
[ ]:
sc.server.volume = 0.0
[ ]:
scn.dbamp(sc.server.volume)
[ ]:
syn.free()
syn.wait(timeout=1)
Server dumps
The Server process can dump information about
incoming OSC packages. See console for output
[ ]:
sc.server.dump_osc() # specify level=0 to deactivate
currently running Nodes
[ ]:
sc.server.dump_tree() # Notice how the OSC packet is now included in the output
[ ]:
sc.server.blip() # see dumped bundle for test sound on console
Make a test sound
The following methods produces the SCServer
startup sound. The test sound should ease any anxiety whether the server is properly started/running
[ ]:
sc.server.blip()
Managing Nodes
freeing all running nodes and reinitialize the server
[ ]:
sc.server.free_all()
[ ]:
sc.server.free_all(root=False) # only frees the default group of this client
send the
/clearSched
OSC command. This is automatically done when usingfree_all
[ ]:
sc.server.clear_schedule()
Execute init hooks. This is also automatically done when using
free_all
,init
orconnect_sclang
[ ]:
sc.server.execute_init_hooks()
Adding init hooks.
[ ]:
sc.server.send_default_groups
Syncing the SuperCollider audio server by sending a
/sync
OSC command and waiting for the reply.
[ ]:
sc.server.sync()
Allocating IDs
The SCServer
instance manages the IDs for Nodes, Buffers and Buses for the SuperCollider Objects via the following methods. These can also be used for getting suitable IDs when manually creating OSC packages.
Get the IDs via the allocator.
[ ]:
ids = sc.server.buffer_ids.allocate(num=2)
ids
Free the IDs after usage via the allocator.
[ ]:
sc.server.buffer_ids.free(ids)
There are allocators for
Nodes -
sc.server.node_ids
Buffer -
sc.server.buffer_ids
Buses (Audio and Control) -
sc.server.audio_bus_ids
,sc.server.control_bus_ids
[ ]:
sc.server.reboot()
[ ]:
# example to see how consecutive buffer alloc works:
ids = sc.server.buffer_ids.allocate(num=5)
print("5 buffers:", ids)
sc.server.buffer_ids.free(ids[0:2])
print("freed buffers ", ids[0:2])
ids4 = sc.server.buffer_ids.allocate(num=4)
print("allocated 4 buffers:", ids4, "-> new numbers to be consecutive")
sc.server.sync()
ids2 = sc.server.buffer_ids.allocate(num=2)
print("allocated 2 buffers:", ids2, "-> using the two freed before")
Handling SynthDefs
The server offers the following methods for handling SynthDefs. These are shortcuts for the respective SynthDef methods.
sc.server.send_synthdef
sc.server.load_synthdef
sc.server.load_synthdefs
Refer to the SynthDef guide for more information about SynthDefs.
[ ]:
sc.exit()