Sequence Generators (in Alphabetical Order)
cyc - Cycle Generator
Generates a fixed-time cycle. The duration between the event onsets will be determined by the number of events, while the overall time duration of the cycle is fixed.
Accepts shorthand syntax.
Syntax
(cyc <name> :time <cycle time> <event sequence>)
Parameters
- name - generator name
- sequence - sequence description
:time- the overall time of the cycle in milliseconds. The default is 800ms. Duration between events within the cycle will betime/number of events.- DEPRECATED
:rep- probability of repeating an event - DEPRECATED
:max-rep- limits number of repetitions - DEPRECATED
:rnd- random connection probability (currently not working the way I expected it ...) - DEPRECATED
:events- use labeled events
Example
The default time for a cycle is 800ms. Thus, the following example will create an even beat with a spacing of 200ms between each event onset:
;; plain
(sx 'simple #t
(cyc 'beat (bd) (hats) (bd) (hats)))
This one, on the other hand, will result in an spacing of 266.666667ms (800/3),
between event onsets, while the overall cycle duration will remain:
;; plain
(sx 'triplet #t
(cyc 'perc (risset 2000) (risset 2000) (risset 2000)))
This can be used to create 3-against-4 rhythms very easily, which also makes the idea clearer:
;; plain
(sx 'three-against-four #t
(cyc 'beat (bd) (hats) (bd) (hats))
(cyc 'perc (risset 2000) (risset 2000) (risset 2000)))
In this example, we make use of the reprtitions. Here you can see that Mégra isn't a cycle-language, really, as this breaks the cycle length:
;; with a 40% chance of repetition, 2 times at max
(sx 'simple #t
(cyc 'beat :rep 40 :max-rep 2 (bd) (hats) (bd) (hats)))
;; control cycles with a loop
(sx 'control #t
(loop 'ba
:time 1599 ;; switch just in time ... will run out of sync eventually
(ctrl (sx 'controlled #t (cyc 'fa (bd) (sn))))
(ctrl (sx 'controlled #t (cyc 'fa (hats) (hats))))
))
Cycles from Vectors
You can use the (vec ...) structure to construct cycles:
(let cycsource (vec (saw 100) (saw 200) (saw 120)))
(sx 'ba #t
(cyc 'foo loopsource))
You can use this feature to create more abstract generator functions:
(fun x3 (a)
(vec a a a))
(sx 'ba #t
(cyc 'foo (x3 (saw 200))))
chop - Chop Sample
Chop a sample into parts, that will be played as a loop. All other parameters of
a loop can be applied (rep, max-rep and rnd).
Examples
;; chop violin sample into 8 parts (each of which is 200ms long)
(sx 'some #t
(chop 'chops 8 (violin 'a3 :sus 200)))
facts - Factors for Parameters
This is great to use together with the cmp (compose) function to write shorthands.
Syntax
(facts <name> :<param> <sequence of multipliers>)
Examples
;; make a melody by applying factor to frequency
(sx 'foo #t
(cmp
(facts 'baz :freq 1 1.2 0.9 1.3) ;; apply a series of factors to create a melody
(nuc 'bar (saw 100))))
;; make complex rhythms by applying factors to duration
(sx 'foo #t
(cmp
(facts 'baz :dur 1.25 0.75 1.5 0.5) ;; apply a series of factors to create a rhythm
(loop 'bar (bd) (sn))))
flower - Flower Generator
Create ... well, look at the examples.
Syntax
(flower <name> :pistil <event> :layers <layers> :petals <events>)
Parameters
name- generator name:layers- number of layers:pistil- pistil or central event:petals- list of events (will be padded to appropriate lenght if necessary)
Examples
;; flower with one layer and four petals
(sx 'a-rose-is-a #t
(flower 'rose
:pistil (saw 100)
:petals (saw 200) (saw 300) (saw 400) (saw 150)))
Flower with 2 layers:
(sx 'a-rose-is-a #t
(flower 'rose
:layers 2
:pistil (saw 100)
:petals (saw 200) (saw 300) (saw 400) (saw 150)
(saw 400) (saw 600) (saw 800) (saw 300)))
friendship - Windmill Generator
This creates a directed version of a Friendship- or Windmill graph.
Syntax
(friendship <name> :center <center event> :friends <list of events>)
Parameters
name- the generator name:center- the center of the "social circle":friends- the "friends".:rep- chance of repetition.:max-rep- maximum number of repetitions:rnd- generate random shortcuts:events- collect labeled events
Example
(sx 'friend #t
(cmp
(pear (atk 1) (rel 90) (sus 10) (rev 0.07))
(friendship 'ship
:dur 100
:center (saw 'a2)
:friends (saw 'c3) (saw 'e3) (saw 'b3) (saw 'd3) (saw 'f3) (saw 'c4))))
fully - Random Generator
Each node follows each other node with equal probablity ... so basically a random generator.
Syntax
(fully <name> :dur <duration> <list of events>)
Example
;; random generator with five events
(sx 'full #t
(fully 'mel (saw 'a3) (saw 'f2) (saw 'c3) (saw 'e3) (saw 'a4)))
infer - Infer from Rules
Infer a generator from arbitrary rules. Make sure every event has at least one exit, otherwise the generator will stop.
Also, exit probablities for each node should add up to 100.
Parameters
name- generator name:events- labeled event mapping:rules- transition rules - Format(rule <source> <destination> <probability> <duration (optional)>)
Example
;; infer
(sx 'con #t
(infer 'duct :events
'a (saw 'a2)
'b (saw 'f2)
'c (saw 'c3)
'd (saw 'e4)
:rules
(rule 'a 'a 80 200) ;; repeat 'a with 80% chance
(rule 'a 'b 20 200) ;; move to 'b with 20% chance
(rule 'aaa 'c 100 200) ;; after 3 repetitions of 'a, always move to 'c
(rule 'b 'b 100 400) ;; repeat 'b always
(rule 'bb 'd 100 400) ;; ... well, 2x max
(rule 'c 'c 100 100) ;; same for 'c
(rule 'ccc 'a 100 400)
(rule 'd 'd 80 200) ;; 'd is repeated with 80% chance as well
(rule 'd 'a 20 200) ;; and moves back to 'a with 20% chance
(rule 'ddddd 'b 100 400))) ;; and is repeated 5x max
learn - Learn a Generator
Learn a generator from a sample string. Based on the variable-order Markov chain learning algorithm proposed in Ron, Singer, Tishby - The Power of Amnesia (1996).
Parameters
:events- Event definitions. Can be amap.:sample- Sample string to learn from. Uses the defined event mapping as characters. Can be avec.:bound- The maximum order of the learned markov chain, that is, how far to look back when determining the next step.:epsilon- Probability threshold, a connection that's less likely than that won't be learned. The higher, the longer it takes to learn.:size- Maximum generator size (nodes in the probabilistic finite automaton generated).:autosilence- Use~as default character for silence.:tie- Automatically restart in case this generator gets stuck in an "end state" (a state without children)
Example
Learn a trap-like beat from a sample string. When event labels have only one character, the sample string doesn't need spaces.
(sx 'from #t
(learn 'data
:events 'x (bd) 'o (sn) 'h (hats)
:sample "xoxoxoxox~~o~h~~~h~h~h~~h~h~~hhh~x~o
~x~o~x~o~x~o~xh~h~~hhh~x~o~x~o~x~o~x
ox~xox~xox~xoxo~xoxo~xoxox~oooo~xxxx
~xoxoxox~ohxhohxhohxhxhxhxhxhxhxhoho
hoh"))
You can also use arbitrary labels for events, in which case you need to leave a space between tokens:
(sx 'bat #f
(learn 'alo
:events 'cat (saw 100) 'dog (saw 400) 'owl (saw 600)
:sample
"cat cat dog owl ~ ~ ~ owl ~ ~ cat cat dog owl ~ ~ ~ owl ~ ~ cat dog owl cat"))
Lastly, you can use map and vec to assemble your learning data from external sources, such as OSC or MIDI.
Here's an example for a statical assembly (see documentation on map/vec and OSC to learn how to assemble things from
external sources).
(let ork (vec "~" "~" "~" "cat" "bat" "bat" "~" "~" "~" "cat" "bat" "cat"))
(let dork (map (pair "cat" (saw 300)) (pair "bat" (saw 600))))
(sx 'ba #f
(learn 'tro :events dork :sample ork))
lin - Linear Sequence
If you just need a simple, linear sequence (no repetition), this is the way to go. This is great to write scores, using the linear sequence with control events to score other generators.
Example
;; default durations
(sx 'conductor #t
(lin 'score
(ctrl (sx 'part #t (cyc 'ga "bd ~ sn ~"))) 4000
(ctrl (sx 'part #t (cyc 'ga "bd hats sn hats"))) 4000
(ctrl (sx 'part #t (cyc 'ga "[bd cym] cym [sn cym] cym"))) 4000
(ctrl (clear))
))
loop - Loop Generator
The loop generator, unlike cyc, creates a loop of events, where the overall duration is dependent
on the number of events you pass in.
The default duration between event onsets is 200ms.
Accepts shorthand syntax.
Syntax
(loop <name> :dur <duration between event onsets> <event and optional duration sequence>)
Parameters
- generator name dur- default duration between event onsets (optional, default 200ms)- Sequence description. Plain numbers between events stand for the duration between the events and will overwrite default duration.
Example
;; use default duration, total loop time is 800ms
(sx 'around #t
(loop 'and-around (saw 100) (saw 200) (saw 300) (saw 400)))
;; assuming the default duration is 200ms, this loop will have an overall duration (or cycle-time) of 1000ms
(sx 'around #t
(loop 'and-around (saw 100) (saw 200) (saw 300) (saw 400) (saw 500)))
;; change default duration
(sx 'around #t
(loop 'and-around :dur 100 (saw 100) (saw 200) (saw 300) (saw 400) (saw 500)))
;; use custom durations between event onsets
(sx 'around #t
(loop 'and-around (saw 100) 400 (saw 200) 100 (saw 300) 200 (saw 400)))
;; compare with a cycle, on the other hand:
(sx 'around #t
(cyc 'and-around (saw 100) (saw 200) (saw 300) (saw 400) (saw 500)))
nuc - Nucleus Generator
Generates a one-node repeating generator, i.e. as a starting point for growing.
Parameters
- name (symbol)
- event(s) (event or list of events) - events to be repeated
:dur- transition duration between events
Syntax
(nuc <name> :dur <duration> <event(s)>)
Example
;; with one event
(sx 'just #t
(nuc 'a-bassdrum :dur 400 (bd)))
;; with multiple events
(sx 'just #t
(nuc 'a-bassdrum-and-a-snare :dur 400 (bd) (sn)))
You can also pass a vec of events:
(let evs (vec (saw 100) (saw 200)))
(sx 'ba #t
(nuc 'ta evs))
stages - Stages Generator
This generator arranges sound events in "stages". See for yourself.
Syntax
(stages <name> :pprev <prob> :pnext <prob> :dur <duration> <events>)
Parameters
name- generator name:dur- duration between events:pprev- probability to return to previous stage:pnext- probability to advance to next stage:cyc- cyclical (last stage will advance to first stage)
Example
;; non-cyclical
(sx 'ba #t
(stages 'ga :pprev 10 :pnext 10 (saw 100) (saw 200) (saw 300) (saw 400)))
;; cyclical
(sx 'ba #t
(stages 'ga :pprev 10 :pnext 10 (saw 100) (saw 200) (saw 300) (saw 400)))
vals - Explicit Values for Parameters
This is great to use together with the cmp (compose) function to write shorthands
Syntax
(vals <name> :<param> <sequence of values>)
Examples
;; make a melody by replacing frequencies
(sx 'foo #t
(cmp
(vals 'baz :freq 100 120 90 130) ;; apply a series of values to create a melody
(nuc 'bar (saw))))
;; make complex rhythms by replacing durations
(sx 'foo #t
(cmp
(vals 'baz :dur 250 150 300 100) ;; apply a series of values to create a rhythm
(loop 'bar (bd) (sn))))
;; you can also sequence sample keys
(sx 'foo #t
(cmp
(vals 'baz :keys 'a3 'as3 'b3 'c4)
(nuc 'bar (piano 'mp))))