Pattern

A rhythm's pattern is a sequence of pulse values that defines the temporal occurence of events. It feeds the emitter 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.

A pattern can be generated by algorithms such as Euclidean rhythms, or it can be expressed as a static Lua table, or it can be generated by a dynamic generator - a Lua function.

The default pattern is an endless repeated pulse train of 1's.

Offset

By default, the pattern starts running immediately when the rhythm is triggered. Using the offset property you can delay the start by the amount specified in the rhythm's unit.

» offset = 4 delay start by 4 * rhythm'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 pattern is a Lua table (array) of numbers or boolean values:

» pattern = {0, 1, 1} skip, trigger, trigger - repeat

» pattern = {1, 0, 1, 1} 1/2th followed by two 1/4th triggers in a 1/4th unit rhythm

» pattern = {0.8, 0, 1, 0.2} pulse values are passed as numbers to gates and emitters in function contexts

tip

The default gate implementation skips all 0 pulses and passes all other pulse values to the 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 emitter function to create accents.

Sub-Divisions

Each number value in the specified Lua table represents a single pulse in the rhythm'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.

» pattern = {{1, 1, 1}, {1, 1}} triplet followed by two quarter notes with unit 1/2

» pattern = {{1, 0}, {0, 1}} basic bossanova rhythm with unit 1/4

Dynamic Patterns

When using a Lua function instead of a table as a pattern generator, you can dynamically generate pulse values.

» pattern = function(context) return math.random() end randomly emit pulse values between 0 and 1

The expected return value of a dynamic pattern function is a pulse value (true, false, 0, 1) or nil.

Use functions in order to create dynamic patterns that can interact with user interaction, or to create probability based pattern rules. To connect the functions to its runtime use the passed context argument.

See generators for more info about using functions as generators.

Pattern Library

afseq comes with a built-in pattern library, which contains a bunch of helper functions and generators to ease creating patterns.

» pattern = pattern.from{0, 1} * 3 + {1, 0} combine sub patterns

» pattern = pattern.new(12, function(k, v) return k % 3 == 1 end), functionally create patterns

» pattern = pattern.euclidean{3, 8, -1} create euclidean patterns

See Pattern API Lua reference for more info and examples.

Examples

Static pattern.

return rhythm {
  pattern = { 1, 0, 0, 1 },
  emit = "c4"
}

Cram pulses into a single pulse slot via subdivisions in static patterns.

return rhythm {
  pattern = { 1, { 1, 1, 1 } },
  emit = "c4"
}

Static pattern created using the "pattern" lib

return rhythm {
  pattern = pattern.from{1, 0} * 5 + {1, 1},
  emit = "c4"
}

Euclidean pattern created using the "patterns" lib.

return rhythm {
  pattern = pattern.euclidean(7, 16, 2),
  emit = "c4"
}

Stateless function.

return rhythm {
  pattern = function(context)
    return math.random(0, 1)
  end,
  emit = "c4"
}

Stateful generator.

return rhythm {
  pattern = function(init_context)
    local rand = math.randomstate(12345)
    local triggers = table.new{ 0, 6, 10 }
    return function(context)
      local step = (context.pulse_step - 1) % 16
      return rand() > 0.8 and triggers:contains(step)
    end
  end,
  emit = "c4"
}

See generators for more info about stateful generators.