Closed TatriX closed 3 years ago
I think you can get the same basic functionality with the with-controls
macro:
SC-USER> (proxy :sine-synth (with-controls ((freq 440 :lag 2)) (sin-osc.ar freq 0 0.2)))
=> #<CL-COLLIDER::NODE :server #<CL-COLLIDER::EXTERNAL-SERVER localhost-127.0.0.1:4444> :id 1003 :name "sine-synth">
SC-USER> (ctrl :sine-synth :freq 880)
=> :SINE-SYNTH
A limitation is that we can't have duplicate control names on the same node, while NamedControl
allows this.
For example, if you try to replicate the last example in the SC help page, you get something like this:
(defun make-env (env &optional (done 0))
(with-controls ((gt 1))
(env-gen.kr env :gate gt :act done)))
(defmacro choose-noise ()
(alexandria:random-elt '((pink-noise.ar)
(white-noise.ar)
(lf-noise2.ar (+ 100 (random 900))))))
(defmacro filter-input (in)
(alexandria:random-elt `((with-controls ((freq 800))
(bpf.ar (sc::*~ ,in 15) freq 0.2))
(with-controls ((freq 800 :lag 0.2))
(rhpf.ar ,in freq 0.2)))))
(proxy :a (* (sin-osc.ar 440)
(make-env (asr) :free)))
(ctrl :a :gate -3)
(proxy :a (* (choose-noise)
(make-env (asr) :free)))
(ctrl :a :gate -3)
(proxy :a (* (filter-input (choose-noise))
(make-env (asr) :free)))
(ctrl :a :freq 1000)
(ctrl :a :gate -3)
(proxy :a (splay.ar (loop :repeat 8
:collect (* (filter-input (choose-noise))
(make-env (asr) :free)))))
;;; => ERROR: duplicate control names
Which is kind of unfortunate because it seems like a cool and flexible way of combining functions to build synthdefs...
Yep, with-controls
is nice, as it doesn't have most of the downsides of arg
in sclang.
What is nice about NamedControl
is that you can inline it in the synth, so it's easier to rename things and also make controls more visible. Maybe something like this:
(proxy :named-control
(pan2.ar (sin-osc.ar (+ (kr :freq 440)
(in.ar (ar :fm (sin-osc.ar 20))))
0
(kr :amp 0.1))))
with-controls
seems need improvement and inline control looks cool.
currentl cl-collider's control process is not clean, I'll fixed that in near future.
Thank you so much @byulparan ! This project is extremely cool! I finally learned enough about synthesis and SuperCollider, so I've started using it more and more. And with-controls
does its job perfectly fine. Named controls could make make it even better.
@TatriX Thank you :-)
I have question. Is it possible use UGen for NamedControl's default value?
(proxy :named-control
(pan2.ar (sin-osc.ar (+ (kr :freq 440)
(in.ar (ar :fm (sin-osc.ar 20)))) ;; <--- is it ok?
0
(kr :amp 0.1))))
my test code not run in SC.
(
x = SynthDef(\test, {
var sig = Pan2.ar(SinOsc.ar(\freq.kr(SinOsc.kr(1).range(440, 880)), 0, 0.1));
Out.ar(0,sig);
});
x.add; // ERROR: SynthDef: could not write def: DoesNotUnderstandError
)
Oh, sorry for the confusion! No, I guess I just made it up to show as much possibilities as I could imagine.
I commit named-control
. please test :-)
I'll add kr
, ar
for short code.
(defun kr (name &optional value lag) (named-control name :kr value lag))
(defun ar (name &optional value lag) (named-control name :ar value lag))
(defun make-env (env &optional (done 0))
(env-gen.kr env :gate (kr :gt 1) :act done))
(defun choose-noise ()
(funcall
(alexandria:random-elt (list (lambda () (pink-noise.ar))
(lambda () (white-noise.ar))
(lambda () (lf-noise2.ar (+ 100 (random 900))))))))
(defun filter-input (in)
(funcall
(alexandria:random-elt
(list (lambda () (bpf.ar (sc::*~ in 15) (kr :freq 800) 0.2))
(lambda () (rhpf.ar in (kr :freq 800) 0.2))))))
(proxy :a (* (sin-osc.ar 440)
(make-env (asr) :free)))
(ctrl :a :gate -3)
(proxy :a (* (choose-noise)
(make-env (asr) :free)))
(ctrl :a :gate -3)
(proxy :a (* (filter-input (choose-noise))
(make-env (asr) :free)))
(ctrl :a :freq 1000)
(ctrl :a :gate -3)
(proxy :a (splay.ar (loop :repeat 8
:collect (* (filter-input (choose-noise))
(make-env (asr) :free)))))
(ctrl :a :gate -3)
That was fast!
Works perfectly fine when evaluating proxy
and with ctrl
.
Example below doesn't seem to work:
(defsynth beep ()
(out.ar 0 (pan2.ar (* (sin-osc.ar (dup (kr :freq 1000)))
(env-gen.kr (perc) :act :free))
0
(kr :amp 0.1))))
(synth :beep)
(synth :beep :freq 200) ; passed :freq is ignored
@TatriX
It solved!
(defun kr (name &optional value lag) (named-control name :kr value lag))
(defsynth beep ()
(out.ar 0 (pan2.ar (* (sin-osc.ar (dup (kr :freq 1000)))
(env-gen.kr (perc) :act :free))
0
(kr :amp 0.1))))
(synth :beep)
(synth :beep :freq (+ 500 (random 500)))
Works like a charm! Thank you!
It looks so sweet now:
(proxy :saw
(->> (-> (saw.ar (kr :freq 220))
(lpf.ar (in.kr *fader-1*))
(* (make-env (perc) :free))
(pan2.ar (kr :pan 0)))
(out.ar (kr :out 0))))
Will you add ar
and friends to the lib?
I'm considering...
In most cases, control rate are "kr" so kr
seems need.kr
will add.
but ar
and tr
are....I don't know if that would be good.
and I already using tr
symbol for other uses.
Sounds reasonable. For ar
one most likely will use (in.ar (kr :in-bus))
A bit off-topic, but what do you think about adding:
(defun midi-lin (value from to)
(sc:lin-lin value 0 127 from to))
(defun midi-exp (value from to)
(sc:lin-exp value 0 127 from to))
It's quite useful if you have external midi signal, like in:
(lpf.ar sig (midi-exp (in.kr *fader-bus*) 20 20000))
It looks so sweet now:
(proxy :saw (->> (-> (saw.ar (kr :freq 220)) (lpf.ar (in.kr *fader-1*)) (* (make-env (perc) :free)) (pan2.ar (kr :pan 0))) (out.ar (kr :out 0))))
is that https://github.com/nightfly19/cl-arrows ?
is that https://github.com/nightfly19/cl-arrows ?
Yes. It messes up eldoc a bit, but makes signal flow a bit more readable for me.
How about make your own extension library for cl-collider. and add your custom musical / utility function to there.
I just want to keep the core on cl-collider. If I add all the functions that are only useful in a specific situation or sugar function then cl-collider will be too huge.
ofcourse I also have my own contrib like sc-extensions
.
I added kr
. If really need ar
too then I will add it.
Today I will close this issue.
Thanks for request and report issue! :-)
Hi! Is there something similar to NamedControl in cl-collider?