subsequence.groove

Groove templates — repeating timing and velocity feels applied to quantized patterns.

Exports the public Groove class: build one by hand, from a swing percentage, or from an Ableton .agr file, then apply it with p.groove(template).

Module Contents

class subsequence.groove.Groove[source]

A timing/velocity template applied to quantized grid positions.

A groove is a repeating pattern of per-step timing offsets and optional velocity adjustments aligned to a rhythmic grid. Apply it as a post-build transform with p.groove(template) to give a pattern its characteristic feel — swing, shuffle, MPC-style pocket, or anything extracted from an Ableton .agr file.

Parameters:
  • offsets – Timing offset per grid slot, in beats. Repeats cyclically. Positive values delay the note; negative values push it earlier.

  • grid – Grid size in beats (0.25 = 16th notes, 0.5 = 8th notes).

  • velocities – Optional velocity scale per grid slot (1.0 = unchanged). Repeats cyclically alongside offsets.

Example:

# Ableton-style 57% swing on 16th notes
groove = Groove.swing(percent=57)

# Custom groove with timing and velocity
groove = Groove(
        grid=0.25,
        offsets=[0.0, +0.02, 0.0, -0.01],
        velocities=[1.0, 0.7, 0.9, 0.6],
)
static from_agr(path: str) Groove[source]

Import timing and velocity data from an Ableton .agr groove file.

An .agr file is an XML document containing a MIDI clip whose note positions encode the groove’s rhythmic feel. This method reads those note start times and velocities and converts them into the Groove dataclass format (per-step offsets and velocity scales).

What is extracted:

  • Time attribute of each MidiNoteEvent → timing offsets relative to ideal grid positions.

  • Velocity attribute of each MidiNoteEvent → velocity scaling (normalised to the highest velocity in the file).

  • TimingAmount from the Groove element → pre-scales the timing offsets (100 = full, 70 = 70% of the groove’s timing).

  • VelocityAmount from the Groove element → pre-scales velocity deviation (100 = full groove velocity, 0 = no velocity changes).

The resulting Groove reflects the file author’s intended strength. Use strength= when applying to further adjust.

What is NOT imported:

RandomAmount (use p.randomize() separately for random jitter) and QuantizationAmount (not applicable - Subsequence notes are already grid-quantized by construction).

Other MidiNoteEvent fields (Duration, VelocityDeviation, OffVelocity, Probability) are also ignored.

Parameters:

path – Path to the .agr file.

static swing(percent: float = 57.0, grid: float = 0.25) Groove[source]

Create a swing groove from a percentage.

50% is straight (no swing). 67% is approximately triplet swing. 57% is a moderate shuffle — the Ableton default.

Parameters:
  • percent – Swing amount (50–75 is the useful range).

  • grid – Grid size in beats (0.25 = 16ths, 0.5 = 8ths).

subsequence.groove.apply_groove(steps: Dict[int, subsequence.pattern.Step], groove: Groove, pulses_per_quarter: int = subsequence.constants.MIDI_QUARTER_NOTE, strength: float = 1.0) Dict[int, subsequence.pattern.Step][source]

Apply a groove template to a step dictionary keyed by pulse positions.

Notes close to a grid position are shifted by the groove’s offset for that slot. Notes between grid positions are left untouched.

Parameters:
  • steps – Step dictionary (pulse → Step).

  • groove – The groove template to apply.

  • pulses_per_quarter – Internal MIDI clock resolution (default 24).

  • strength – How much of the groove to apply (0.0–1.0). 0.0 leaves all timing and velocity unchanged; 1.0 applies the full groove. Intermediate values blend between the two, equivalent to Ableton’s TimingAmount / VelocityAmount dials.