Skip to content

Latest commit

 

History

History
85 lines (74 loc) · 3.93 KB

features.org

File metadata and controls

85 lines (74 loc) · 3.93 KB

Features

This is a listing of notable features of cl-patterns. For a listing of new features relative to SuperCollider’s patterns system, see sc-differences.org.

  • multiple sound server backends are supported:
  • event keys that are different representations of the same concept are automatically converted between each other. For example, if you set the amp of an event and then try to get its db, cl-patterns converts the amplitude to decibels for you:
(db (event :amp 0.5))
;=> -6.0205994
(amp (event :db -3))
;=> 0.70794576

See special-keys.org for a full listing of such keys.

  • pbind has “special” keys which alter the functionality of the pattern or pstream.

For consistency, they’re typically named after other patterns, i.e. pfin, pfindur, psync, etc. See special-keys.org for a full listing.

  • it’s possible to embed an event’s values into another from inside a pattern. For example:
(next-n (pbind :foo (pseq '(1 2 3 4))
               :embed (pseq (list (event) (event :bar 1 :baz 2) (event :qux 3))))
        3)
((EVENT :FOO 1)
 (EVENT :FOO 2 :BAR 1 :BAZ 2)
 (EVENT :FOO 3 :QUX 3))
  • all pstreams keep a history of previous values that can be referred back to at any time using pstream-elt.
  • patterns that have repeat or length arguments accept any pattern as “gate” patterns:
(let* ((foo 1)
       (bar (as-pstream (pseq '(1 2 3) (pfunc (lambda () foo))))))
  (print (next-n bar 10)) ;=> (1 2 3 1 2 3 1 2 3 1)
  (setf foo 0)
  (print (next-n bar 3)) ;=> (2 3 NIL)
  )
  • patterns keep track of their “parents”:
(defparameter *pat* (pbind :foo (pseq '(1 2 3))))

(defparameter *pseq* (getf (slot-value *pat* 'cl-patterns::pairs) :foo))

(parent-pattern *pseq*) ;=> #<PBIND {1003480F53}>

(eq *pat* (parent-pattern *pseq*)) ;=> T
  • errors in pattern execution give you the option to remove the task from the clock, or just skip one event.
    • alternatively, “performance mode” gives you the option to automatically remove erroring patterns from the clock, with their error and stack trace recorded to a variable:
(setf *performance-mode* t)

(play (pbind :x (p/ 1 (pseq '(440 220 0)))))

;; ...and then the error occurs:
;; WARNING: Task #<CL-PATTERNS::TASK {100438A803}> had error #<DIVISION-BY-ZERO {10043ABA93}>; removed from clock, with state recorded as index 0 in CL-PATTERNS::*PERFORMANCE-ERRORS*.

(car (last *performance-errors*))
;;=> (:TASK #<CL-PATTERNS::TASK {100438A803}>
;;    :ERROR #<DIVISION-BY-ZERO {10043ABA93}>
;;    :STACK (#<DISSECT::SBCL-CALL [1] ...> ...))
  • SuperCollider backend: if a node is supplied as a value for a pbind, the synth metadata for that node is used to set its input-bus or output-bus as the value instead:
  (sc::set-synthdef-metadata :fx :input-bus (bus-audio :chanls 2))

  (defparameter *fx* (proxy :fx
                            (let* ((sig (in.ar (sc::get-synthdef-metadata :fx :input-bus) 2))
                                   (sig (comb-c.ar sig 0.2 (range (lf-noise1.kr 1) 0.04 0.2))))
                              sig)))

  (pb :fx-test
    :instrument :kik
    :dur (p/ 1 (pwhite 1 16))
    :midinote (pwhite 0 127)
    :pan (pwhite -1.0 1.0)
    :out *fx*
    :pfindur 4)

(play :fx-test)

…in the future, this will be even simpler. :)

  • metadata slot for patterns

Hash table associated with each pattern for storing additional data. Access with the pattern-metadata function. Used by the midifile functionality to include track names/information/etc.