I have to interact with some custom SC plugins (e.g. the ATK one) and it's too much trouble translating things into overtone correctly (specially when some pseudo ugens in SC have the same name as real ugens, but different arguments).
So tonight I've decided to give it a shot and worked on a very simple (and direct) data representation for sclang code so I can have access to all the niceties right away. In the video below, you can see 3 the following steps happening:
1. We have the clj data structure (for now, just synthdefs work) that we transpile into a SC string (it will also return a file path)
2. We spit the contents into a .scd file and then we call sclang (which will save the synthdef into file-dir)
3. Synth loading using the file path (this is an existing function in overtone)
From the overtone side, this is a normal synthdef, so everything works just fine. sclang doesn't need to be available for the users, just when you are developing (as long as the custom plugins are available for the user) as you can distribute the generated .scsyndef file with your jar.
Much more can be done in this area, e.g. calling help method, or plot or whatever we want. If this works fine and it's useful, I can open a PR for the overtone repo.
You can see the development at https://github.com/pfeodrippe/vybe/blob/develop/src/vybe/audio/overtone.clj.
that would be cool! I’d been thinking some about a hybrid repl and visual flow model (was thinking about https://www.datarabbit.com/ as an example there), but have had to put that potential project (any many others) on the stalled-out idea backburner 😞 — clerk is a good first landing place option.
Yeah, that’s all we do, Ben, we never have time for our projects :’( This one seems a really great one though! Nice vizs, will watch the videos later o/
I think I fixed Linux, working on Windows https://github.com/overtone/overtone/pull/568
Awesome, man!! Thanks 😊
Don’t spend much time on it if it’s troublesome to make it work on Linux or Windows as people can set the path using the *sclang-user-path atom as a workaround (while they open an issue telling us the path), thanks for the path improvement and new test o/
No problem, my philosophy is by spending an extra few hours trying to get it right it will collectively save a lot of person-hours and give the impression overtone is robust. Totally worth it.
Makes sense, I guess we could also have some beta testers that we could reach for for each of the 3 OSs to make it more robust as there are things (e.g. opening the IDE help windows) that are really hard or impossible to automate in tests. At least 2 for OS • Mac, me and you • Linux, Arne(?) and TBD • Windows, TBD and TBD Wdyt?
You can cherry-pick my PR, works for all platforms.
Thanks, will merge it now, appreciate it!
Merged, ready for review again, but it's Sunday, no rush eahueuhehauehu whenever you can \o Really thanks o/
Done! This is a nice chunk of work, exciting stuff.
Nice, will merge into master \o
Appreciate it o/
Merged overtone.sc.lang ns into master. Thanks Ambrose, for the new test, review and approval \o/
This is great. I was just thinking about how to access the Platform class from Clojure.
I have a half-baked idea. One of sclang's weaknesses seems to be scoping. We work around this in overtone by ns qualifying synth names. We lean on Clojure's support for ns qualified vars for the rest. Can we use this compiler to generate sclang code that emulates these benefits?
I've been experimenting with per-file "namespaces" in sclang by creating an Environment per file. The equivalent to an in-ns call for the current file might be:
(
currentEnvironment = ({
var id = thisProcess.nowExecutingPath.asSymbol();
topEnvironment.at(id)??{ topEnvironment.put(id, Environment.make).at(id) }}.value);
);
It gives you Clojure-like "vars", in that global variables are local to the file. The problem is that you need to change the namespace before you evaluate a form in interactive dev. I modified scnvim to do this and it works. Another issue is binding conveyance: you need to remember to wrap sclang fns in .inEnvir.
There are other things you can do like return currentEnvironment at the end of your file so loading it gives you access to that namespace's vars directly. You also might want to reset (pop) the current environment at the end of the file.
But related to this compiler, perhaps we could use *ns* and *file* to isolate the current sclang code we're sending (really, just change ~ to mean the current namespace, and automatically use .inEnvir for fns). Using the same mechanism, we can then manipulate the "scoped" sclang vars for interactivity from Clojure without worrying about scope.
Maybe this is just a Quark that needs to exist, but I can't help but think of Clojure applications.+1 for this to live in overtone
Nice! Yes, we could have it to be wrapped by the environment (after the first release). The first release would be a very simple version that just calls sclang in non-deamon mode and can generate synthdefs bytecode files ready to be used by overtone (errors would refer the generated sc code), then we can increment it overtime with things like • Sclang daemon using Interpreter that listens OSC messages or whatever so the commands are as fast as they can be • Clojurey version of sclang that transpiles into the lower-level data structure representation • Schelp parsers to have documentation readily available in Clojure • Better error handling • Use server booted by overtone in the sclang daemon ◦ Then we can have scope, plots, help etc integrated in dev time • Environment wrapping (as you mentioned) • etc I will keep working on it using overtone’s functions only (so we can just copy and paste it into the overtone repo) until I have something minimal working and then I can open a PR, let’s see if I can have something until Sunday.
Thanks for the words, man, and for your own PRs so far haahah o/
Nice, my idea is very niche compared to your vision. Looking forward to seeing it, I might experiment off your namespace. the live documentation would be great.
is there a use-case for generating our own SC classes?
I don't fully understand how sclang and sc classes are related.
I will probably say things you already know. sclang is a program that acts as the client for scsynth (the server) and SC classes are only known in sclang. For overtone, there is no use-case I can see for SC classes, what I’m doing is using sclang to generate a SynthDef from some arbitrary .scd code (and this code was derived from hiccup-like Clojure data structures so we don’t have to deal with raw strings). The generated synthdef is stored as bytecode in a file and then we can load it into overtone like any other synth. This bytecode contains all the info about the ugens that are being used, parameters etc; the advantage of using this approach is that, for a new plugin or some code you want to use that’s written in the SC language, you don’t need to replicate them in Clojure to have a usable synth, you can use raw SC for it. It’s just to improve interoperability with the SC world in the same way that we use Java libs in Clojure (we don’t want or need to reinvent everything).
Let me know if this is what you wanted to know ahahah
Re: ideas, another thing I’m experimenting on is in creating a Clerk viewer for overtone synths, so people would be able to play, mix, plot things in Clerk itself, but this is more of a gray area yet, I have to check if it will be useful, e.g. you could viz a synthdef tree and play a demo of just a part of the tree to see how the signal and audio are behaving before or after some ugen.
Created https://github.com/overtone/overtone/pull/567, let me know what you think \o It's very bare-bones now, but it's working. If someone who has SuperCollider installed and could test it on Windows and/or Linux, please \o
This is the content of the generated .scd file
SynthDef("event", {
arg freq=240, amp=0.5, pan=0.0;
var env;
env = EnvGen.ar( Env( [0, 1, 1, 0], [0.01, 0.1, 0.2] ), doneAction: 2 );
Out.ar( 0, Pan2.ar( Blip.ar( freq ) * env * amp, pan ) );
}).writeDefFile("resources").add;
0.exit;Seems awesome! Thanks