Skip to content
Back to skills

Ableton Link

ASecurity

Configure, implement, and test Pulp's optional desktop Ableton Link tempo-sync adapter while preserving the developer-supplied SDK, licensing, realtime, latency-compensation, and no-install boundaries.

  • 22 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 3, 2026
developmentc++bashgitapibackend

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 30, 2026

npx -y skills add danielraffel/pulp --skill ableton-link --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ableton Link?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ableton Link
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/danielraffel-ableton-link/badge)](https://www.skillsdirectory.com/skills/danielraffel-ableton-link)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ableton-link
description: Configure, implement, and test Pulp's optional desktop Ableton Link tempo-sync adapter while preserving the developer-supplied SDK, licensing, realtime, latency-compensation, and no-install boundaries.
---

# Ableton Link

Use this skill for Pulp's desktop `Ableton/link` integration, its CMake opt-in,
or the backend-neutral tempo-sync seam in `core/playback`.

## Scope and licensing boundary

- This is the desktop C++ `Ableton/link` SDK. It is not iOS LinkKit and not
  `m4l-connection-kit`. LinkKit needs a separate licensing decision, option,
  SDK path, and implementation.
- Link is available under GPLv2+ or a proprietary arrangement with Ableton.
  Pulp's MIT license grants no Link rights. The developer enabling the adapter
  is responsible for having suitable rights.
- Pulp never fetches, bundles, installs, exports, or redistributes Link. Keep
  the SDK outside the Pulp source tree. Do not add it to `DEPENDENCIES.md` or
  `NOTICE.md` because Pulp ships none of it.
- The portable `pulp::playback` target owns only Pulp code. The optional
  `pulp::ableton-link` target exists only in a source build with the SDK enabled
  and must never enter `cmake --install` or Pulp's exported target closure. Its
  adapter declaration lives under `core/playback/adapters/include`, exposed
  only through that target's `BUILD_INTERFACE`; do not place it under the
  installed `core/playback/include` tree.

## Obtain and enable the desktop SDK

Clone recursively to an absolute path outside the checkout; Link requires its
ASIO submodule even on platforms that do not use an ASIO audio device:

```bash
git clone --recurse-submodules https://github.com/Ableton/link.git /absolute/path/to/link

cmake -S . -B build-link -DCMAKE_BUILD_TYPE=Release \
  -DPULP_ENABLE_ABLETON_LINK=ON \
  -DPULP_ABLETON_LINK_SDK_DIR=/absolute/path/to/link
```

`PULP_ENABLE_ABLETON_LINK` defaults to `OFF`. When enabled, a missing, partial,
in-tree, or non-desktop SDK path is a configure error. The SDK path can also
come from the `PULP_ABLETON_LINK_SDK_DIR` environment variable, but an explicit
CMake cache value is easier to audit.

## Runtime contract

- `TempoSyncSource` is Pulp's backend-neutral, audio-thread interface. Keep
  Link types and Link-specific peer/enable/start-stop controls out of it.
- `AbletonLinkTempoSync` owns those Link-specific controls. Call `set_enabled`
  and `set_start_stop_sync_enabled` from a control thread, never from the audio
  callback. `output_host_time` and `capture_audio_block` are realtime-safe.
- Call `output_host_time(output_latency_frames, sample_rate, time)` in the audio
  callback, then pass its opaque `TempoSyncHostTime` to `MasterTransport`. The
  adapter reads Link's realtime clock and adds device/output latency so the
  timestamp names the first sample at the output boundary. A callback timestamp
  without compensation produces a stable audible offset.
- `TempoSyncHostTime` is tagged with its producing source. A transport rejects
  a default token or one from another source before asking its backend to
  capture a block, preventing Link, device, and wall-clock epochs from mixing.
- The public desktop adapter models APIs that report output latency from the
  callback. It does not accept an arbitrary device-host timestamp. A platform
  integration whose audio API exposes a calibrated future device timestamp
  needs an explicit Link-clock conversion boundary; do not forward that raw
  timestamp or a jittery wall-clock read as though it were Link time.
- A configured `TempoSyncSource` must outlive `MasterTransport`. Use the
  host-time `begin_block(frame_count, output_host_time, snapshot)`
  overload. The ordinary overload returns `TempoSyncHostTimeRequired`.
- The session mapping is authoritative. Disabled, failed, or invalid sources
  fail the block; they never fall back to the document tempo clock.
- Joining does not send the config's initial tempo, position, or play state.
  Only explicit `set_tempo_sync_tempo`, `seek`, and `set_playing` calls publish
  session commands, which avoids hijacking an existing jam on attach.
- A Link-projected block retains Pulp's fixed one-or-two-range transport
  contract and precise fractional host ticks. `begin_scrub()` rejects an active
  shared tempo source because scrubbing needs a private repositioning clock;
  use an unsynchronized transport for scrub playback.
- Preserve `SessionState::timeForIsPlaying()` in
  `TempoSyncBlockState::is_playing_at_host_time_micros`. A
  `TransportSnapshot` has one playing state for its whole half-open block: a
  start/stop effective at or before the first sample applies immediately, while
  one inside or at/after the block end is deterministically deferred until a
  later block starts at or beyond that timestamp. Do not flatten the timestamp
  into `SessionState::isPlaying()` or claim sample-accurate start/stop splitting
  that the snapshot contract cannot represent.

## Verification

The SDK-independent interface tests are the public-CI gate. They compile into
the grouped `pulp-test-group-timeline-playback` executable, so build that
target and select the suite by its file tag. The SDK-present
test is always registered: a stock build exits 77 and CTest reports `Skipped`
with the enablement flags, while an enabled local build executes the real
adapter.

```bash
cmake --build build --target \
  pulp-test-group-timeline-playback \
  pulp-test-ableton-link-sdk \
  timeline-program-threadless-no-exceptions-check

build/test/pulp-test-group-timeline-playback -# "[#test_playback_tempo_sync]" \
  --reporter compact
ctest --test-dir build -V -R '^playback-ableton-link-sdk-present$'

cmake --build build-link --target \
  pulp-test-group-timeline-playback pulp-test-ableton-link-sdk
ctest --test-dir build-link -V -R '^playback-ableton-link-sdk-present$'
```

Check the interface assertion count; a filtered CTest command can match
nothing. For substantive changes, prove negative controls for fail-closed
source errors and precise beat projection, then restore the implementation.

When the portable interface or transport integration changes, also update the
`playback` skill and keep `tempo_sync.cpp` in the native, threadless, WAM, and
WebCLAP playback source closure. Keep the SDK adapter under
`core/playback/adapters/`, outside the portable `src/` closure.

Files in this skill

  • SKILL.md6 KB
  • agents/openai.yaml196 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.