supriya-project / supriya

A Python API for SuperCollider
http://supriya-project.github.io/supriya
MIT License
250 stars 29 forks source link

Saving synthdefs as .scsynthdef file? #393

Closed alicegas909 closed 3 months ago

alicegas909 commented 3 months ago

I was just wondering if there is currently an equivalent to the writeDefFile method so i can save synthdefs i make as .scsynthdef files on my hard drive. Thanks

josephine-wolf-oberholtzer commented 3 months ago

There's no one-shot method for doing this, but it's quite easy with two ingredients: Path.write_bytes() and SynthDef.compile().

Let's define a trivial SynthDef:

>>> from supriya import synthdef, ugens
>>> @synthdef()
... def example():
...     ugens.Out.ar(source=ugens.SinOsc.ar())
...
>>> example
<SynthDef: example>
>>> example.compile()
b'SCgf\x00\x00\x00\x02\x00\x01\x07example\x00\x00\x00\x02C\xdc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06SinOsc\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x01\x02\x03Out\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> print(example)
synthdef:
    name: example
    ugens:
    -   SinOsc.ar:
            frequency: 440.0
            phase: 0.0
    -   Out.ar:
            bus: 0.0
            source[0]: SinOsc.ar[0]

Then write it to disk:

>>> from pathlib import Path
>>> # Note I'm using .scsyndef, not .scsynthdef: scsynth seems to get grumpy about the extra "th" for some reason.
>>> path = Path("~/Desktop/my-synthdef.scsyndef").expanduser()
>>> path.write_bytes(example.compile())
110

We can also read it back from disk and decompile it back into a SynthDef object in Python:

>>> from supriya.ugens import decompile_synthdef
>>> compiled = path.read_bytes()
>>> decompiled = decompile_synthdef(compiled)
>>> print(decompiled)
synthdef:
    name: example
    ugens:
    -   SinOsc.ar:
            frequency: 440.0
            phase: 0.0
    -   Out.ar:
            bus: 0.0
            source[0]: SinOsc.ar[0]

... Or we can boot a server and have it load the SynthDef (in case you haven't figured this part out yet):

>>> from supriya import Server
>>> server = Server().boot()
>>> _ = server.load_synthdefs(path)
alicegas909 commented 3 months ago

awesome, thank you for the detailed response!

josephine-wolf-oberholtzer commented 3 months ago

You're welcome, darling.