This document is a WIP.
- SuperCollider requires you to coerce a pattern into a
Stream
in order to get results from it. Common Lisp already has the notion of a stream, so a pattern stream is known as apstream
.
This section lists new features relative to SuperCollider’s patterns system. For more, and for a complete listing of notable cl-patterns features, see features.org.
- multiple backends supported; not just SuperCollider and MIDI but others such as Incudine as well.
- coercion of patterns into pstreams is done automatically for you if you call
next
on a pattern:
Pseq([1,2,3]).next;
// => a Pseq
(next (pseq '(1 2 3)))
;; => 1
pwrand
/pwxrand
- weights are automatically normalized.pdurstutter
- works on event streams as well as number streams. (as do any duration-based patterns)play-quant
/end-quant
- instead of justquant
, aplay-quant
can be set to specify when a pattern can start playing, whileend-quant
sets when a pattern can end or swap to a new definition. settingquant
sets bothplay-quant
andend-quant
at the same time.
- non-patterns converted to pstreams only return one value:
(defparameter *foo* (as-pstream 1))
(next-n *foo* 3) ;=> (1 NIL NIL)
pbeat
is the pattern that returns the number of beats elapsed in the pstream (in SuperCollider it’s known asPtime
).- pdefs loop by default when played.
This is because their loop-p
slot defaults to t
. Set it to nil
to prevent this.
midi
is not a standard event type; instead, specify the event’sbackend
to have the event sent exclusively to a specific backend.The backend then interprets the event according to its capabilities. For example, the
alsa-midi
backend automatically coerces pitch keys (freq
,midinote
, etc) into standard MIDI note numbers,amp
into standard MIDI velocity values, and additional keys into control change (CC) messages. See the alsa-midi.lisp file for the ALSA MIDI backend implementation and backends.lisp for more information on supported backends and their capabilities.pfin
,pfindur
,pstutter
,pdurstutter
, etc, have their source pattern as the first input instead of the second, for consistency.
pchain
overwrites pattern data from first to last.
Pchain(Pbind(\foo,1),Pbind(\foo,2)).asStream.next(())
// => (\foo:1)
(next (pchain (pbind :foo 1) (pbind :foo 2)))
;; => (event :foo 2)
pindex
does not have arepeats
argument.