Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
Subsequence
Subsequence
  • Cookbook (tutorial)
    • Chapter 0 · Setup and Your First Sound
    • Chapter 1 · The Step Grid: Writing a Beat by Hand
    • Chapter 2 · The Rebuild Loop: Patterns That Remember
    • Chapter 3 · Notes, Beats, and Durations
    • Chapter 4 · Your First Generators: Euclidean and Spread Rhythms
    • Chapter 5 · Relative Pitch and Scales
    • Chapter 6 · Harmony as Context: Following the Current Chord
    • Chapter 7 · Progressions as Values: Building and Shaping Harmony
    • Chapter 8 · Motifs: Naming and Reusing Material
    • Chapter 9 · Phrases and Motivic Development
    • Chapter 10 · Form, Sections, and Energy: Arranging a Track
    • Chapter 11 · Explore, Capture, Produce: Seeds, Locks, Freeze
    • Chapter 12 · Deep Generative Systems: Chaos, Automata, and Scored Melody
    • Chapter 13 · Expression and Hardware Control
    • Chapter 14 · Live Performance, External Data, and Sync
    • Appendix A · The Direct Pattern API
    • Appendix B · Analysis and Set-Theory Toolkit
    • Appendix C · MIDI Routing and Troubleshooting Reference
    • Appendix D · API Quick Reference
    • Appendix E · Glossary
    • Appendix F · A Field Guide to the Generators
    • Appendix G · Learn One Verb, Predict the Rest
  • API Reference
    • subsequence.cadences
    • subsequence.chord_graphs
    • subsequence.chords
    • subsequence.composition
    • subsequence.conductor
    • subsequence.constants
      • subsequence.constants.durations
      • subsequence.constants.instruments
        • subsequence.constants.instruments.gm_cc
        • subsequence.constants.instruments.gm_drums
        • subsequence.constants.instruments.gm_instruments
        • subsequence.constants.instruments.roland_tr8s
        • subsequence.constants.instruments.vermona_drm1_drums
      • subsequence.constants.midi_notes
      • subsequence.constants.pulses
      • subsequence.constants.velocity
    • subsequence.display
    • subsequence.easing
    • subsequence.form_state
    • subsequence.forms
    • subsequence.groove
    • subsequence.harmony
    • subsequence.held_notes
    • subsequence.intervals
    • subsequence.keystroke
    • subsequence.link_clock
    • subsequence.live_client
    • subsequence.live_reloader
    • subsequence.live_server
    • subsequence.melodic_state
    • subsequence.midi
    • subsequence.midi_utils
    • subsequence.motifs
    • subsequence.osc
    • subsequence.pattern
    • subsequence.pattern_algorithmic
    • subsequence.pattern_builder
    • subsequence.pattern_midi
    • subsequence.progressions
    • subsequence.roles
    • subsequence.sequence_utils
    • subsequence.sequencer
    • subsequence.tuning
    • subsequence.voicings
    • subsequence.web_ui
Back to top
View this page

subsequence.link_clock¶

Ableton Link clock adapter for Subsequence.

Wraps aalink.Link and adapts its asyncio-native API to Subsequence’s 24 PPQN pulse model. Requires the optional link extra:

pip install subsequence[link]

Usage:

link_clock = LinkClock(bpm=120, quantum=4.0, loop=asyncio.get_running_loop())
beat_origin = await link_clock.wait_for_bar()
# ... in the pulse loop:
await link_clock.sync(beat_origin + pulse_count / PPQN)

Module Contents¶

class subsequence.link_clock.LinkClock(bpm: float, quantum: float, loop: asyncio.AbstractEventLoop)[source]¶

Thin wrapper around aalink.Link for Subsequence’s pulse-based clock.

Parameters:
  • bpm – Initial tempo in BPM (proposed to the Link session).

  • quantum – Beat cycle length — 4.0 means one bar in 4/4 time.

  • loop – The running asyncio event loop (required by aalink).

Join the Link session immediately, proposing bpm and setting the bar length to quantum beats.

disable() → None[source]¶

Disconnect from the Link session.

request_tempo(bpm: float) → None[source]¶

Propose a new tempo to the Link session.

Other peers may accept or reject the change depending on their own session rules. Subsequence’s sequencer will pick up the network- authoritative tempo on the next pulse.

async sync(beat: float) → float[source]¶

Wait until the Link session beat reaches beat, then return beat.

This is the primary timing primitive used by the sequencer loop. Calling await link_clock.sync(beat_origin + pulse / PPQN) for each successive pulse gives accurate, Link-synchronised timing.

async wait_for_bar() → float[source]¶

Wait for the next quantum boundary (bar start) and return it.

Use this to start the sequencer at a musically clean position that is phase-aligned with all other Link participants.

Returns the beat value at which playback should begin (beat_origin).

property beat: float[source]¶

Current absolute beat position in the Link session timeline.

property num_peers: int[source]¶

Number of connected Link peers (not counting self).

property playing: bool[source]¶

Whether the Link session transport is playing.

property quantum: float[source]¶

Beat cycle length (e.g. 4.0 for one bar in 4/4).

property tempo: float[source]¶

Current session tempo in BPM (authoritative from the Link network).

Next
subsequence.live_client
Previous
subsequence.keystroke
Copyright © 2026, Simon Holliday
Made with Sphinx and @pradyunsg's Furo
On this page
  • subsequence.link_clock
    • Module Contents
      • LinkClock
        • LinkClock.disable()
        • LinkClock.request_tempo()
        • LinkClock.sync()
        • LinkClock.wait_for_bar()
        • LinkClock.beat
        • LinkClock.num_peers
        • LinkClock.playing
        • LinkClock.quantum
        • LinkClock.tempo