This document is a WIP.
- SuperCollider requires you to coerce a pattern into a
Streamin 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
nexton a pattern:
Pseq([1,2,3]).next;
// => a Pseq
(next (pseq '(1 2 3)))
;; => 1pwrand/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-quantcan be set to specify when a pattern can start playing, whileend-quantsets when a pattern can end or swap to a new definition. settingquantsets bothplay-quantandend-quantat the same time.
- non-patterns converted to pstreams only return one value:
(defparameter *foo* (as-pstream 1))
(next-n *foo* 3) ;=> (1 NIL NIL)pbeatis 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.
midiis not a standard event type; instead, specify the event’sbackendto have the event sent exclusively to a specific backend.The backend then interprets the event according to its capabilities. For example, the
alsa-midibackend automatically coerces pitch keys (freq,midinote, etc) into standard MIDI note numbers,ampinto 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.
pchainoverwrites 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)pindexdoes not have arepeatsargument.