Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NamedControl #94

Closed
TatriX opened this issue Mar 21, 2021 · 18 comments
Closed

NamedControl #94

TatriX opened this issue Mar 21, 2021 · 18 comments

Comments

@TatriX
Copy link

TatriX commented Mar 21, 2021

Hi!
Is there something similar to NamedControl in cl-collider?

@ntrocado
Copy link
Contributor

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

@ntrocado
Copy link
Contributor

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...

@TatriX
Copy link
Author

TatriX commented Mar 22, 2021

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))))

@byulparan
Copy link
Owner

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.

@TatriX
Copy link
Author

TatriX commented Mar 22, 2021

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.

@byulparan
Copy link
Owner

byulparan commented Mar 22, 2021

@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
)

@TatriX
Copy link
Author

TatriX commented Mar 22, 2021

Oh, sorry for the confusion! No, I guess I just made it up to show as much possibilities as I could imagine.

@byulparan
Copy link
Owner

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)

@TatriX
Copy link
Author

TatriX commented Mar 23, 2021

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

@byulparan
Copy link
Owner

@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))) 

@TatriX
Copy link
Author

TatriX commented Mar 24, 2021

Works like a charm! Thank you!

@TatriX
Copy link
Author

TatriX commented Mar 24, 2021

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?

@byulparan
Copy link
Owner

byulparan commented Mar 24, 2021

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.

@TatriX
Copy link
Author

TatriX commented Mar 24, 2021

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))

@justin2004
Copy link
Contributor

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 ?

@TatriX
Copy link
Author

TatriX commented Mar 24, 2021

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.

@byulparan
Copy link
Owner

byulparan commented Mar 24, 2021

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.

@byulparan
Copy link
Owner

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! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants