@ktamas77/abletonlink
v1.2.3
Published
Node.js native bindings for Ableton Link - Real-time music synchronization
Downloads
29
Maintainers
Readme
@ktamas77/abletonlink
Node.js native bindings for Ableton Link - Real-time music synchronization
Overview
This package provides a TypeScript/Node.js wrapper around the native Ableton Link C++ SDK to expose tempo sync functionality in JavaScript.
Features
- Tempo Synchronization: Get/set tempo (BPM) across connected peers
- Beat & Phase Information: Query beat position and phase for quantized synchronization
- Transport Control: Start/stop playback state synchronization
- Peer Discovery: Automatic discovery of Link-enabled applications on the network
- Quantum Support: Beat subdivision for perfect loop synchronization
- TypeScript Support: Full type definitions for a great developer experience
Installation
npm install @ktamas77/abletonlinkNote: This package includes native bindings and will be compiled during installation.
Usage
import { AbletonLink } from '@ktamas77/abletonlink';
// Create a new Link instance with initial tempo
const link = new AbletonLink(120.0);
// Enable Link
link.enable(true);
// Enable start/stop sync to synchronize transport state
link.enableStartStopSync(true);
// Get current tempo
console.log('Current tempo:', link.getTempo());
// Set new tempo
link.setTempo(128.0);
// Get number of connected peers
console.log('Connected peers:', link.getNumPeers());
// Query beat information
const beat = link.getBeat();
const phase = link.getPhase(4.0); // 4-beat quantum
// Transport control
link.setIsPlaying(true);
console.log('Is playing:', link.isPlaying());
// Set up callbacks for real-time notifications
link.setNumPeersCallback((numPeers) => {
console.log(`Peers changed: ${numPeers}`);
});
link.setTempoCallback((tempo) => {
console.log(`Tempo changed: ${tempo} BPM`);
});
link.setStartStopCallback((isPlaying) => {
console.log(`Playing state: ${isPlaying}`);
});Examples
The examples/ directory contains several scripts demonstrating different features:
basic.js
A simple example showing core Link functionality including tempo sync, beat/phase tracking, and transport control. Great starting point for understanding the basics.
callbacks.js
Demonstrates the callback system for real-time notifications when peers connect/disconnect, tempo changes, or transport starts/stops. Shows how to build reactive applications.
quantized-launch.js
Advanced example showing quantized beat alignment and synchronized starts. Essential for DAW-like applications that need sample-accurate synchronization with other Link peers.
auto-tempo.js
Shows how to automatically adopt the tempo from an existing Link session. Useful for applications that want to immediately sync with whatever session is already running.
monitor-playing.js
Real-time monitor for the isPlaying state. Shows current play/stop status, tempo, beat position, and detects state changes. Useful for debugging transport synchronization issues.
diagnose-playing.js
Diagnostic tool that checks all prerequisites for isPlaying functionality including start/stop sync, network connectivity, and peer discovery. Provides troubleshooting hints if synchronization isn't working.
diagnose-playing-sync.js
Advanced diagnostic that analyzes the synchronization sequence when joining a session, helping identify timing issues with play state synchronization.
sync-with-playing.js
Shows how to properly wait for initial synchronization when joining a Link session that may already be playing.
join-playing-session.js
Best practices example demonstrating the recommended initialization sequence for reliable synchronization with existing Link sessions.
test-initial-sync.js
Tests various timing scenarios for enableStartStopSync to understand synchronization behavior.
force-sync-workaround.js
Demonstrates workarounds to force synchronization when joining a session that's already playing.
typescript-example.ts
Demonstrates TypeScript usage with full type safety and autocompletion support.
Run any example with:
node examples/basic.jsAPI Reference
new AbletonLink(bpm: number)
Creates a new Ableton Link instance with the specified initial tempo.
enable(enabled: boolean): void
Enable or disable Link synchronization.
isEnabled(): boolean
Check if Link is currently enabled.
getTempo(): number
Get the current tempo in BPM.
setTempo(bpm: number): void
Set a new tempo in BPM.
getNumPeers(): number
Get the number of connected Link peers.
getBeat(): number
Get the current beat position.
getPhase(quantum: number): number
Get the current phase for the given quantum (beat subdivision).
isPlaying(): boolean
Check if transport is playing.
Important: Start/stop sync must be enabled with enableStartStopSync(true) for this method to work correctly. Without start/stop sync, Link only synchronizes tempo and beat position, not play/stop state.
Note on synchronization: When joining a Link session that's already playing, there may be a brief delay before the play state synchronizes. The initial state will be "stopped" until the Link protocol completes synchronization. Use the start/stop callback to be notified when the state updates. See the join-playing-session.js example for best practices.
setIsPlaying(playing: boolean): void
Start or stop transport playback.
enableStartStopSync(enabled: boolean): void
Enable or disable start/stop synchronization with other Link peers. When enabled, play/stop state changes will be synchronized across all connected applications.
isStartStopSyncEnabled(): boolean
Check if start/stop synchronization is enabled.
forceBeatAtTime(beat: number, time: number, quantum: number): void
Force a specific beat at a specific time with the given quantum.
setNumPeersCallback(callback: (numPeers: number) => void): void
Register a callback to be notified when the number of connected peers changes.
setTempoCallback(callback: (tempo: number) => void): void
Register a callback to be notified when the tempo changes.
setStartStopCallback(callback: (isPlaying: boolean) => void): void
Register a callback to be notified when the play/stop state changes.
requestBeatAtTime(beat: number, time: number, quantum: number): void
Request a specific beat to occur at a specific time. When connected to peers, this will quantize to the nearest quantum boundary for synchronized starts.
requestBeatAtStartPlayingTime(beat: number, quantum: number): void
Request a specific beat (usually 0) when transport starts playing. Useful for resetting the beat counter on playback start.
setIsPlayingAndRequestBeatAtTime(isPlaying: boolean, time: number, beat: number, quantum: number): void
Combined operation to start/stop playback and align beats at a specific time. Perfect for synchronized launches.
timeForIsPlaying(): number
Get the time when the transport will start or stop. Returns the scheduled time in seconds.
Implementation Plan
Components
- Ableton Link SDK (C++) – Official synchronization engine from Ableton
- Node.js Native Addon – C++ bridge to expose Link functionality to JS/TS
- node-gyp – Build system for compiling the native module
- TypeScript Definitions – Clean and typed API exposed to the user
Project Structure
abletonlink/
├── src/ # C++ source files
│ ├── abletonlink.cc # Main addon implementation
│ └── abletonlink.h # Header file
├── examples/ # Example scripts
│ ├── basic.js # Basic usage example
│ ├── callbacks.js # Demonstrates callback functionality
│ ├── quantized-launch.js # Shows quantized launch features
│ ├── auto-tempo.js # Auto-adopt tempo from session
│ ├── monitor-playing.js # Real-time isPlaying monitor
│ ├── diagnose-playing.js # Diagnose transport sync issues
│ ├── diagnose-playing-sync.js # Analyze sync sequence
│ ├── sync-with-playing.js # Handle already-playing sessions
│ ├── join-playing-session.js # Best practices for joining
│ ├── test-initial-sync.js # Test sync timing scenarios
│ ├── force-sync-workaround.js # Workarounds for sync issues
│ └── typescript-example.ts # TypeScript usage example
├── test/ # Test files
│ ├── abletonlink.test.js # Main test suite
│ └── link.test.js # Additional tests
├── build/ # Compiled native module (generated)
├── link/ # Ableton Link SDK (git submodule)
├── .husky/ # Git hooks
│ └── pre-commit # Runs prettier and tests
├── binding.gyp # node-gyp build configuration
├── index.js # Main entry point
├── index.d.ts # TypeScript definitions
├── package.json # NPM package configuration
├── tsconfig.json # TypeScript configuration
├── jest.config.js # Jest test configuration
├── .prettierrc.json # Prettier code formatting config
├── .prettierignore # Files to ignore for formatting
└── README.md # This fileBuilding from Source
- Clone the repository with submodules:
git clone --recursive https://github.com/ktamas77/ableton-link.git
cd ableton-link- Install dependencies:
npm install- Build the native addon:
npm run buildPublishing to npm
To publish this package to npm:
- Make sure you're logged in to npm:
npm login- Update the version in package.json:
npm version patch # or minor/major- Build and test the package:
npm run build
npm test- Publish to npm:
npm publish --access publicThe package is published as @ktamas77/abletonlink on npm.
Requirements
- Node.js >= 18.0.0
- C++ build tools:
- macOS: Xcode Command Line Tools
- Windows: Visual Studio 2019 or later with C++ workload
- Linux: gcc/g++ and make
Platform Support
- macOS (x64, arm64)
- Windows (x64)
- Linux (x64)
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This package wraps the Ableton Link SDK by Ableton AG.
