Subsystem

subsequence.groove

The API reference for Groove.

Groove

class Groove(
    offsets: typing.List[float],
    grid: float = 0.25,
    velocities: typing.Optional[typing.List[float]] = None,
)

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

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],
)

Members: from_agr, grid, offsets, swing, velocities

Groove.offsets

Groove.offsets: typing.List[float]

Groove.grid

Groove.grid: float = 0.25

Groove.velocities

Groove.velocities: typing.Optional[typing.List[float]] = None

Groove.swing

staticmethod Groove.swing(
    percent: float = 57.0,
    grid: float = 0.25,
) -> 'Groove'

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

Groove.from_agr

staticmethod Groove.from_agr(
    path: str,
    grid: typing.Optional[float] = None,
) -> 'Groove'

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).

Without grid=, the grid is inferred as clip length / note count — which assumes the clip plays exactly one note per grid cell (the standard shape for a groove clip). A clip with rests or chords breaks that assumption: pass grid= explicitly (e.g. grid=0.25 for a 16th-note groove) and empty cells keep a neutral offset. A clip whose notes cannot be assigned one-per-cell raises rather than importing a wrong feel.

What is extracted:

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