Contexts¶
Supriya’s context
interface exposes
a set of common functions for interacting with scsynth-compatible
execution contexts in both realtime and non-realtime.
>>> server = supriya.Server().boot() # realtime
>>> score = supriya.Score() # non-realtime
See the servers and scores pages for in-depth documentation on how each time of context works.
Moments¶
Contexts can bundle requests together via
Moment
context managers.
For non-realtime contexts, all requests must happen inside a moment, while for
realtime contexts issuing requests outside of a moment - or inside a moment
with no timestamp - simply means “do this as soon as possible”. Use
at()
to create a new moment.
Scores count time from zero:
>>> with score.at(0): ... score_group = score.add_group() ...
Servers use real timestamps:
>>> import time >>> with server.at(time.time() + 0.1): # 0.1 seconds from now ... server_group = server.add_group() ...
Servers can use moments without timestamps:
>>> with server.at(): # do it ASAP ... server.add_group() ... Group(context=<Server ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, id_=1001, parallel=False)
Servers can also omit moments entirely:
>>> server.add_group() Group(context=<Server ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, id_=1002, parallel=False)
Completions¶
Some commands to SuperCollider are “async” and may take multiple control blocks to complete, e.g. reading a file from disk into a buffer. These commands often accept a final “completion message”: an OSC message or bundle to be executed once the original command completes. A common use-case is to load a SynthDef and then allocate a synth using that definition in the completion message.
Like moments, Supriya exposes completions via
Completion
context managers. Some context
methods return a completion, and all requests issued inside that completion’s
context with be bundled together into the original request’s on_completion
argument.
>>> with score.at(0):
... with score.add_synthdefs(supriya.default):
... score.add_synth(supriya.default, target_node=score_group)
...
Synth(context=<Score ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, id_=1001, synthdef=<SynthDef: default>)
>>> with server.at():
... with server.add_synthdefs(supriya.default):
... server.add_synth(supriya.default, target_node=server_group)
...
Synth(context=<Server ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, id_=1003, synthdef=<SynthDef: default>)
Because realtime contexts can issue requests outside of a moment context, all
command methods that return completions also accept an on_completion
argument: a callable taking the context as its only argument. This callable
will be executed and any issued requests will be bundled as a completion
message.
>>> server.add_synthdefs(
... supriya.default,
... on_completion=lambda context: context.add_synth(supriya.default),
... )
Completion(context=<Server ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, moment=Moment(context=<Server ONLINE [/usr/local/bin/scsynth -R 0 -l 1 -u 57110]>, seconds=None, closed=True, requests=[(ReceiveSynthDefs(synthdefs=(<SynthDef: default>,), on_completion=None), ...)]), requests=[(NewSynth(synthdef=<SynthDef: default>, synth_id=1004, add_action=AddAction.ADD_TO_HEAD, target_node_id=1, controls={}), None)])
If issuing commands inside a moment, the completion must be used before the moment closes, because the request to which the completion message will be added will have been sent once the moment closed.
>>> with server.at():
... completion = server.add_buffer(channel_count=1, frame_count=512)
...
>>> with completion:
... ...
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/runner/work/supriya/supriya/supriya/contexts/entities.py", line 90, in __enter__
return self.completion.__enter__()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/runner/work/supriya/supriya/supriya/contexts/core.py", line 187, in __enter__
raise MomentClosed
supriya.contexts.errors.MomentClosed