@dam You can require overtone.core with alias (:as o). It's not hygenic because it's more tought of as a runtime live-coding library for musicians than it is as library for IT systems. That said, you can use both hygenic and non-hygenic as you wish. But bear in mind that every public overtone function would live behind the alias, irrelevant of the namespace. There are so many macros at play, it would be hard to remember the dozens of namespaces of all the different functions.
Thanks. I get it.
We'll try it at my coworking space.
I'll use it with Clojure newbies so I wanted to be clear about Clojure good practices in general vs the Overtone approach.
This untidyness is mostly from a namespace hacking tool. Tell them that for every namespace hack they do for a library for other people, a dolphin dies in the sea.
If you have any problems setting up overtone, on the 0.10.3 release or the master branch, please let me know and report 🙂
😂Thanks. I'll quote that also in the README!
Ok. Thanks.
I've been trying to build something a bit like overtone in clojurescript, so I can run it on node and not worry about startup time (it's really long when running on a Raspberry Pi)
I don't want to kill any dolphins, but sometimes I wish clojurescript had more namespace-hacking potential.
You can't even refer :all
, so if I want to define my ugens in different namespaces, I would have to do a ton of different requires. Instead I'm just putting them all in one namespace, and aliasing it to u
so that I type things like (u/out (u/sin-osc 330))
, it's kind of annoying to have to do that.
one way you could get around that is to make a data-based DSL
and an interpreter for said DSL
e.g. something like [:out [:sin-osc 330]]
as a bonus, programs/patches could be serializable
i'm sure there are some downsides to that approach
Oh, hadn't considered that, not a bad idea
With lumo, I could hack the namespace, but thats not possible in non-self hosted cljs. Maybe another way.
@bfay have you thought about how you will generate the audio in the node environment?
i'm curious what the state of the art is there
I guess one downside of the data-based approach is that it would be hard to use one ugen in multiple parts of the graph. For example I'm thinking:
(let [lfo (u/mul (u/sin-osc:kr 0.2) 1000)
osc1 (u/sin-osc:ar lfo)
osc2 (u/sin-osc:ar (u/mul 100 lfo))])
Here both oscillators are reusing the same lfo to control frequency. If I wanted to do this with just data, I would need to be able to mark the id of that lfo somehow, so that I don't wind up duplicating itOh, I'm actually just using supercollider (the nodejs instance isn't creating any audio, just sending OSC messages to scsynth)
It's extremely hacky and undocumented and doesn't have a lot of features yet, but my work so far is here: https://github.com/brianfay/synchrotron
I'm also really curious what other options exist for audio from node. I remember seeing a web audio api port for node at some point, but I'm not sure if that's being actively maintained
i saw that WAA port too -- looked interesting
good point about needing references to created objects
i've been working on some data-based DSLs recently, and one way to get around that is to have a data way to represent a reference to a named thing, something like [:ref "lfo"]
which would be resolved by the interpreter
and you would also name the thing when you create it, e.g. [:fixture "lfo" [:mul ...]]
I could see that working, and it would probably make the interpreter code much easier to write and reason about. I've been having a lot of issues trying to add ugens, because SuperCollider has a lot of hidden logic on the client side - some ugens have quirky behavior where arguments only mean something to the client, and are discarded before they make it to the server.
For example, BufRd
is documented with this signature
<http://BufRd.ar|BufRd.ar>(numChannels, bufnum: 0, phase: 0, loop: 1, interpolation: 2)
In most ugens, that would mean each argument shows up somewhere in the binary synthdef file.
But in BufRd, numChannels
isn't a real input; it's used to determine the number of outputs of the ugen, and then discarded before the synthdef is generated.
The only way to figure this out is reading through a ton of supercollider source code; it's pretty amazing to me that the Overtone authors had the patience to do this so well