This is a small collection of extensions for working with cl-collider. It includes:
- Pseugens (pseudo-ugens) like
b2
andfbn
. - Syntax sugar like
ds
(wrappingdefsynth
) anddn
(wrappingproxy
). - Convenience functions like
plot
. - Maybe more in the future?
Refer to the “Features” section below for a more detailed overview of the provided functionality.
NOTE: This library should be considered to be in “beta” stages. You will probably run into a bug or two, so it’s advised not to depend on its functionality for a live performance yet.
collidxr is not yet part of Quicklisp, but the plan is to have it added in the future.
In the meantime, it can be installed manually by cloning the repo into your Quicklisp local-projects
directory.
Once you’ve done that, you can simply run (ql:quickload "collidxr")
in your REPL to load it into Lisp.
Show a graphical plot of the provided data. Data can be:
- A list of numbers
- A cl-collider
buffer
- A
pattern
(when cl-patterns is loaded) - A
bdef
(when bdef is loaded)
Wrap the provided ugen in a pan2.ar
or balance2.ar
as appropriate. In other words, if IN
is mono, wrap it in pan2.ar
, or if IN
is stereo, wrap it in balance2.ar
. PAN
and LEVEL
are the panning and amplitude arguments, respectively.
Feedback node, for creating feedback loops within synthdefs. It’s recommended to use fbn
to create an fbnode
, and then fbn-read
and fbn-write
to read and write to it.
Create a fbnode
for doing feedback within synthdefs. NUM-CHANNELS
is the number of channels of the internal delay buffer. MAX-DELAY-TIME
is the length in seconds that the delay buffer should be allocated to, defaulting to the minimum delay possible (one block). INTERPOLATION
is the type of interpolation to use when reading from the delay, as per buf-rd.ar
.
(defsynth :echoed ((freq 440) (delay 0.5) (feed 0.5) (amp 0.5) (out 0))
(let* ((fbn (fbn 2 0.5))
(sig (var-saw.ar (+ (rand.ir -2.0 (list 2.0 2.0)) freq) 0 0.5 (env-gen.kr (perc 0.01 0.25))))
(sig (rlpf.ar (+ sig (* feed (fbn-read fbn delay)))
(* freq 0.9) 0.9)))
(fbn-write fbn sig)
(detect-silence.ar (leak-dc.ar sig) 1.0e-4 :time delay :act :free)
(out.ar out (* sig amp))))
Read from FBNODE
at a time DELAY
seconds from its input. DELAY
defaults to the fbnode
’s max delay time.
Write INPUT
to FBNODE
.
“Define Synth”; syntax sugar wrapping defsynth
. It does the following:
- Provides a more concise syntax for writing proxies;
BODY
is simply a plist mapping variable names to their values. Nolet*
needed! params
are inserted aswith-controls
.
- If not specified by the user, auto-inserts parameters for
dur
,tempo
,pan
,amp
, andout
with sensible defaults, marked as ignorable, to avoid warnings if they aren’t used. - Bindings named
-
or_
are automatically declared ignorable. - When
:fx
is the first element ofPARAMS
, allocate a 2-channel bus and bindsig
to(in.ar BUS 2)
. - If
out
is bound inBODY
, its value is automatically used as the input for anout.ar
. - If there is no
out
inBODY
but there is asig
,sig
is automatically fed into ab2
inside anout.ar
. In other words, thepan
,amp
, andout
arguments will “just work”. - Can be provided as an
:instrument
in apbind
to set the parameters of the node. - Can be provided as an
:out
in apbind
to send the output of triggered synths to the node (for use with:fx
nodes).
Example; you can write this:
(ds :foo ((gate 1) (freq 440))
:env (env-gen.kr (env-adsr 0.01 0.1 0.5 0.1) :gate gate :act :free)
:sig (pulse.ar freq)
:sig (rlpf.ar sig (* freq 2) 0.5)
:sig (* sig env)
:- (poll.kr (impulse.kr 1) sig))
instead of this:
(defsynth :foo ((gate 1) (freq 440) (pan 0) (amp 0.5) (out 0))
(let* ((env (env-gen.kr (adsr 0.01 0.1 0.5 0.1) :gate gate :act :free))
(sig (pulse.ar freq))
(sig (rlpf.ar sig (* freq 2) 0.5))
(sig (* sig env))
(ign (poll.kr (impulse.kr 1) sig)))
(declare (ignore ign))
(out.ar out (pan2.ar sig pan amp))))
In the future, it might also:
- Allow specifying a ControlSpec, lag time, and rate (
:ar
,:kr
, etc) for each parameter. - Allow output with
replace-out.ar
instead of onlyout.ar
.
Like cl-collider:synth
, but can also start a synth variant. To specify a variant, NAME
should be in the format NAME.VARIANT
.
Synth variants are specified in the synthdef metadata. Set the metadata key :VARIANTS
to a plist mapping the name of the variant to the plist of arguments to the synthdef.
Example:
;; define the \"noisy\" variant for the :tb303 synth:
(setf (synthdef-metadata :tb303 :variants) (list :noisy (list :dist 1 :clip 1 :bias 1)))
;; play the variant:
(synth-variant :tb303.noisy :freq 420 :dist 0) ; notice that you can override the arguments set in the variant.
;; the above is the same as doing:
(synth :tb303 :freq 420 :dist 0 :clip 1 :bias 1)
“Define Node”; syntax sugar wrapping proxy
. In addition to its standard functionality, it also does the following:
- Provides a more concise syntax for writing proxies;
BODY
is simply a plist mapping variable names to their values. Nolet*
needed! params
are inserted aswith-controls
.- Without
BODY
, just returns the node. - If not specified by the user, auto-inserts parameters for
dur
,tempo
,pan
,amp
, andout
with sensible defaults, marked as ignorable, to avoid warnings if they aren’t used. - Bindings named
-
or_
are automatically declared ignorable. :pos
binding can be used to specify the:pos
of the node within its group (i.e.:head
,:tail
, etc).- When
:fx
is the first element ofPARAMS
, allocate a 2-channel bus and bindsig
to(in.ar BUS 2)
. - If
out
is bound inBODY
, its value is automatically used as the input for anout.ar
. - If there is no
out
inBODY
but there is asig
,sig
is automatically fed into ab2
inside anout.ar
. In other words, thepan
,amp
, andout
arguments will “just work”. - Can be provided as an
:instrument
in apbind
to set the parameters of the node. - Can be provided as an
:out
in apbind
to send the output of triggered synths to the node (for use with:fx
nodes).
Example; you can write this:
(dn :echo (:fx (time 1.0) (decay 0.5) (pos :head))
:sig (comb-c.ar sig 1 time decay))
instead of this:
(proxy :echo
(with-controls ((time 1.0) (decay 0.5) (dur 1) (tempo 1) (pan 0) (amp 0.5))
(let* ((sig (in.ar 16 2))
(sig (comb-c.ar sig 1 time decay)))
sig))
:pos :head) ; note that :pos defaults to :head for non-:fx `dn's and :tail for :fx `dn's