-
Hi, I'm trying to get a synthdef-factory macro up and running, but I am bumping my head against the wall in various ways, and can't quite figure out how to move forwards. Right now I have this: (defmacro defsynth-factory (name &key params sig)
`(dolist (num-channels '(1 2 4 6))
(defsynth (format nil "~A-~A" ,name num-channels) ,params
(let* ,sig
(* (named-control 'amp :kr 1)
(out.ar
(named-control 'out :kr 0)
(cond
((= num-channels 1)
sig)
((= num-channels 2)
(pan2.ar sig
(named-control 'pan :kr 0)))
((> num-channels 2)
(pan-az.ar num-channels
sig
(named-control 'pan :kr 0)
1
(named-control 'width :kr 2.0))))))))))
(defsynth-factory playbuf-mono
:params ((buf 0) (rate 1) (start-pos 0) (loop 0) (attack 0.1)
(release 0.5) (gate 1))
:sig ((env (env-gen.kr (asr attack 1 release)
:gate gate :act :free))
(sig (* (play-buf.ar 1 buf rate
:start-pos start-pos
:loop loop)
env)))) I was able to get everything working up until the point when I wrapped the defsynth-making process in a Execution of a form compiled with errors.
Form:
(DEFSYNTH (FORMAT NIL "~A-~A" PLAYBUF-MONO-ASR NUM-CHANNELS)
((BUF 0) (RATE 1) (START-POS 0) (LOOP 0) (ATTACK 0.1) (RELEASE 0.5)
(GATE 1))
(LET* ((ENV (ENV-GEN.KR (ASR ATTACK 1 RELEASE) :GATE GATE :ACT :FREE))
(SIG (* (PLAY-BUF.AR 1 BUF RATE :START-POS START-POS :LOOP LOOP) ENV)))
(* (NAMED-CONTROL 'AMP :KR 1)
(OUT.AR (NAMED-CONTROL 'OUT :KR 0) (COND (# SIG) (# #) (# #))))))
Compile-time error:
during macroexpansion of
(DEFSYNTH (FORMAT NIL "~A-~A" ...)
(# # # ...)
...).
Use *BREAK-ON-SIGNALS* to intercept.
(FORMAT NIL "~A-~A" PLAYBUF-MONO-ASR NUM-CHANNELS) is not a string designator.
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR] It seems the problem is how to create a name for the synthdefs with dolist and format inside a macro, but how to do this is beyond my limited common-lisp understanding. It is, of course, possible that I'm attacking this from the completely wrong angle, in which case I'm grateful for pointers on how to approach this in a more lisp-y idiomatic way. |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
You're getting that error because the > (macroexpand-1 '(defsynth-factory playbuf-mono
:params ((buf 0) (rate 1) (start-pos 0) (loop 0) (attack 0.1)
(release 0.5) (gate 1))
:sig ((env (env-gen.kr (asr attack 1 release)
:gate gate :act :free))
(sig (* (play-buf.ar 1 buf rate
:start-pos start-pos
:loop loop)
env))))) becomes (DOLIST (NUM-CHANNELS '(1 2 4 6))
(DEFSYNTH (FORMAT NIL "~A-~A" PLAYBUF-MONO NUM-CHANNELS)
((BUF 0) (RATE 1) (START-POS 0) (LOOP 0) (ATTACK 0.1) (RELEASE 0.5)
(GATE 1))
(LET* ((ENV (ENV-GEN.KR (ASR ATTACK 1 RELEASE) :GATE GATE :ACT :FREE))
(SIG
(* (PLAY-BUF.AR 1 BUF RATE :START-POS START-POS :LOOP LOOP) ENV)))
(* (NAMED-CONTROL 'AMP :KR 1)
(OUT.AR (NAMED-CONTROL 'OUT :KR 0)
(COND ((= NUM-CHANNELS 1) SIG)
((= NUM-CHANNELS 2)
(PAN2.AR SIG (NAMED-CONTROL 'PAN :KR 0)))
((> NUM-CHANNELS 2)
(PAN-AZ.AR NUM-CHANNELS SIG (NAMED-CONTROL 'PAN :KR 0)
1 (NAMED-CONTROL 'WIDTH :KR 2.0))))))))) Note the You probably want to write your macro like this: (defmacro defsynth-factory (name &key params sig)
(let (defsynths)
(dolist (num-channels '(1 2 4 6) `(progn ,@defsynths))
(push `(defsynth ,(format nil "~A-~A" name num-channels) ,params
(let* ,sig
(* (named-control 'amp :kr 1)
(out.ar
(named-control 'out :kr 0)
,(cond
((= num-channels 1)
'sig)
((= num-channels 2)
'(pan2.ar sig
(named-control 'pan :kr 0)))
((> num-channels 2)
`(pan-az.ar ,num-channels
sig
(named-control 'pan :kr 0)
1
(named-control 'width :kr 2.0))))))))
defsynths)))) Aside from the format thing, also note that since You also probably want the |
Beta Was this translation helpful? Give feedback.
-
Thanks a lot for the detailed breakdown! Now I just need to drill into the code and understand what is going on there :-) The next step is to add different envelopes as well, so that I would get |
Beta Was this translation helpful? Give feedback.
-
No prob :)
Sounds right to me! 👍 |
Beta Was this translation helpful? Give feedback.
-
Making progress here with my nested dolist :-) However I'm running into a problem when adding different envelopes into the mix. When I expand the macros they look fine, but I am getting an error that (defmacro defsynth-factory (name &key params sig (pan t))
(let (defsynths)
(dolist (num-channels '(1 2 4 6) `(progn ,@defsynths))
(dolist (envelope '(:asr :perc))
(push `(defsynth ,(format nil "~A-~A-~A" name envelope num-channels) ,params
(let* ,sig
(* (named-control 'amp :kr 1)
,(cond
((equal envelope :asr)
'(env-gen.kr (asr attack 1 release)
:gate gate :act :free))
((equal envelope :perc)
'(env-gen.kr (perc attack release)
:act :free)))
(out.ar
(named-control 'out :kr 0)
,(cond
((or (= num-channels 1) (eql pan nil))
'sig)
((= num-channels 2)
'(pan2.ar sig
(named-control 'pan :kr 0)))
((> num-channels 2)
`(pan-az.ar ,num-channels
sig
(named-control 'pan :kr 0)
1
(named-control 'width :kr 2.0))))))))
defsynths)))))
(defsynth-factory playbuf-mono
:params ((buf 0) (rate 1) (start-pos 0) (loop 0) (attack 0.1)
(release 0.5) (gate 1))
:sig ((sig (* (play-buf.ar 1 buf rate
:start-pos start-pos
:loop loop))))) |
Beta Was this translation helpful? Give feedback.
-
OK, I managed to get rid of the variable warning by replacing the gate parameter in the defsynth arg list with a |
Beta Was this translation helpful? Give feedback.
-
Ah, figured it out... when I do it this way it works: (defmacro defsynth-factory (name &key params sig (pan-p t))
(let (defsynths)
(dolist (num-channels '(1 2 4 6) `(progn ,@defsynths))
(dolist (envelope '(:asr :perc))
(push `(defsynth ,(format nil "~A-~A-~A" name envelope num-channels) ,params
(let* (,@sig
(sig (* sig (named-control 'amp :kr 1)))
(sig (* sig ,(cond
((equal envelope :asr)
'(env-gen.kr (asr (named-control 'attack :kr 0.1) 1 (named-control 'release :kr 0.5))
:gate (named-control 'gate :kr 1) :act :free))
((equal envelope :perc)
'(env-gen.kr (perc (named-control 'attack :kr 0.01) (named-control 'release :kr 0.5))
:act :free))))))
(out.ar
(named-control 'out :kr 0)
,(cond
((or (= num-channels 1) (eql pan-p nil))
'sig)
((= num-channels 2)
'(pan2.ar sig
(named-control 'pan :kr 0)))
((> num-channels 2)
`(pan-az.ar ,num-channels
sig
(named-control 'pan :kr 0)
1
(named-control 'width :kr 2.0)))))))
defsynths))))) |
Beta Was this translation helpful? Give feedback.
You're getting that error because the
format
form is not being run at macro-expansion time, but instead is being passed to the defsynth form. When you macroexpand it, you can see thatbecomes