Pulse
A pattern's pulse
defines the temporal occurence of events - the rhythm. It triggers events with pulse values that are optionally filtered out by a gate. It is created from a list of pulses with possible subdivisions, an optional number of repeats and an optional time offset.
Pulses can be generated by algorithms such as Euclidean rhythms, can be expressed as a static Lua tables, or can be generated by a dynamic generator - a Lua function.
The default pulse is an endless repeated pulse train of 1's.
Offset
By default, the pattern starts running immediately when the pattern is triggered. Using the offset
property you can delay the start by the amount specified in the pattern's unit.
» offset = 4
delay start by 4 * pattern's unit.
Repeat
By default, a pattern repeats endlessly. To create one-shot patterns, or patterns that repeat only a few times, you can use the repeats
property.
» repeats = false
one-shot
» repeats = 1
play pattern twice, then stop
Static Patterns
The simplest form of a pulse is a Lua table (array) of numbers or boolean values:
» pulse = {0, 1, 1}
skip, trigger, trigger - repeat
» pulse = {1, 0, 1, 1}
1/2th followed by two 1/4th triggers in a 1/4th unit rhythm
» pulse = {0.8, 0, 1, 0.2}
pulse values are passed as numbers to gate and event in function contexts
tip
The default gate implementation skips all 0 pulses and passes all other pulse values to the event emitter. When using a custom gate function, you can e.g. use the pulse value as a probability or you can use the pulse value as a volume value in a custom event function to create accents.
Sub-Divisions
Each number value in the specified Lua table represents a single pulse in the pattern's specified time unit. By using tables instead of pulse numbers as values, you can cram sub-patterns into a pattern to create more complex rhythms.
» pulse = {{1, 1, 1}, {1, 1}}
triplet followed by two quarter notes with unit 1/2
» pulse = {{1, 0}, {0, 1}}
basic bossanova rhythm with unit 1/4
Dynamic Patterns
When using a Lua function instead of a table as a pulse generator, you can dynamically generate pulse values.
» pulse = function(context) return math.random() end
randomly emit pulse values between 0 and 1
The expected return value of a dynamic pattern function is (true
, false
, 0
, 1
) or nil
and will be converted to a number when passed to the event emitter.
Use functions in order to create dynamic rhythms that can interact with the user, or to create probability based trigger rules. To connect the functions to its runtime use the passed context
argument.
See generators for more info about using functions as generators.
Pulse Library
pattrns comes with a built-in pulse
Lua library, which contains a bunch of helper functions and generators to ease creating pulse arrays.
» pulse = pulse.from{0, 1} * 3 + {1, 0}
combine sub pulses
» pulse = pulse.new(12, function(k, v) return k % 3 == 1 end),
functionally create pulses
» pulse = pulse.euclidean{3, 8, -1}
create euclidean rhythms
See Pattern API Lua reference for more info and examples.
Examples
Static pulse.
return pattern {
pulse = { 1, 0, 0, 1 },
event = "c4"
}
Cram pulses into a single pulse slot via subdivisions.
return pattern {
pulse = { 1, { 1, 1, 1 } },
event = "c4"
}
Static pulse pattern created using the "pulse" library.
return pattern {
pulse = pulse.from{1, 0} * 5 + {1, 1},
event = "c4"
}
Euclidean pattern created using the "pulse" library.
return pattern {
pulse = pulse.euclidean(7, 16, 2),
event = "c4"
}
Stateless function.
return pattern {
pulse = function(context)
return math.random(0, 1)
end,
event = "c4"
}
Stateful function.
return pattern {
pulse = function(init_context)
local rand = math.randomstate(12345)
local triggers = table.from{ 0, 6, 10 }
return function(context)
local step = (context.pulse_step - 1) % 16
return rand() > 0.8 and triggers:contains(step)
end
end,
event = "c4"
}
See generators for more info about stateful functions.