I built a Bitwig OSC Translator that listens to OSC messages from external controllers / sensors and turns them into Bitwig actions, device parameters, and musical note events. On top, it includes a Chromatic Scale Transition engine that morphs incoming notes between scales in real time — perfect for data-driven performance and generative sets.
What it does
- OSC → Bitwig: Map any OSC path to Bitwig device parameters, clips, macros, transport, or note events.
- Bi-directional (optional): Mirror selected Bitwig parameters back out as OSC for visual feedback.
- Chromatic Scale Transitions: Constrain notes to a target scale, then morph to another scale (and octave) smoothly over time or on triggers.
- Scene-aware: Each scene or track can have its own scale, octave, and transition rules.
System architecture
OSC Sources (sensors, apps) → Node.js Translator → WebSockets/OSC → Bitwig (Controller Script) → Instruments
- Node.js Translator
- Receives OSC (UDP/TCP)
- Normalizes ranges (0–1, bipolar, dB, Hz)
- Routing rules (per device/track)
- Scale engine (quantize + morph)
- Bitwig Controller Script
- Exposes track/parameter endpoints
- Triggers notes, macros, sends, clip actions
- Optional return-channel for LEDs/meters
Mapping examples
OSC → Parameter
/city/noise→ Track 1 Filter Cutoff (0–1 → 30 Hz–16 kHz)/light/level→ Master Reverb Send/motion/speed→ LFO Rate on Mod Device
OSC → Note
/grid/x= pitch seed,/grid/pressure= velocity- Quantize to D Phrygian for Track 2; when Scene changes, transition to E Harmonic Minor over 8 bars.
Chromatic Scale Transitions (how it “morphs” scales)
- Quantize: Incoming MIDI/derived pitch snaps to current scale (e.g., C Minor).
- Transition Curve: Over a defined period (beats/ms/bars) the scale set interpolates to a new one.
- Strategies (selectable per track):
- Nearest-Note: always move to closest in the target scale.
- Directional: push notes upward or downward during morph.
- Weighted Chromatic: allow chromatic passing tones with decay.
- Octave Policy:
- Fixed, Wrap, or Follow-Velocity (strong hits jump octave).
- Event Triggers:
- Scene launch, clip end, OSC flag (
/scale/next), or threshold (e.g., noise>0.7).
- Scene launch, clip end, OSC flag (
Typical performance setup
- Track 1: Drums, OSC maps crowd density → groove amount, light → transient shaper.
- Track 2: Polysynth, notes from sensor grid → quantize to A Dorian, scene change → C Lydian (4-bar morph).
- Track 3: Bass, chromatic glide to E Phrygian on breakdown; octave follows motion intensity.
Routing & config (concise)
- Ports: OSC in
:9000, OSC out:9001. - Profiles: JSON files per project with:
sources: OSC paths, scaling, smoothingroutes:path → track.parameterorpath → notescales: per scene/track plus transition time, strategy, octave policy
- Smoothing: Exponential or moving average to avoid zipper noise.
- Safety: Range clamps, denormalization guard on very low levels.
Why Bitwig?
- Modulators everywhere, per-note expressions, and a friendly Controller API make it ideal for data-driven performance and adaptive harmony.
Use cases
- City Heart Modulation: Amsterdam sensor feeds reshape harmony globally.
- Installations: Visitors’ movement alters both mix parameters and tonal center.
- Live sets: One fader morphs an entire show from minor darkness to bright Lydian.