# Ardour OSC Configuration Examples This document provides practical examples for configuring and using Ardour's Open Sound Control (OSC) interface. ## Quick Start ### Enabling OSC in Ardour 1. Launch Ardour: `just run-osc-debug` 2. Navigate to: `Edit > Preferences > Control Surfaces` 3. Enable: `Open Sound Control (OSC)` 4. Click: `Show Protocol Settings` ### Recommended OSC Settings ``` Port: 3819 Reply Port: Auto (or specify if needed) Bank Size: 0 (unlimited) Strip Types: All enabled Feedback: Enable for interactive control Gainmode: dB Default Strip: Audio Tracks Debug Mode: Enable during development ``` ## Testing OSC Connection ### Method 1: Using Command Line Tools ```bash # Test if port is listening just test-osc-connection # Or manually with netcat nc -zv -u 127.0.0.1 3819 ``` ### Method 2: Send Test OSC Message Install `liblo-tools`: ```bash # Ubuntu/Debian sudo apt-get install liblo-tools # macOS brew install liblo ``` Send a test command: ```bash # Start playback oscsend localhost 3819 /transport_play # Stop playback oscsend localhost 3819 /transport_stop # Get session info oscsend localhost 3819 /strip/list ``` ### Method 3: Python Script ```python #!/usr/bin/env python3 # test_osc.py - Test Ardour OSC connection from pythonosc import udp_client import time # Create OSC client client = udp_client.SimpleUDPClient("127.0.0.1", 3819) print("Testing Ardour OSC connection...") # Test transport controls print("Starting playback...") client.send_message("/transport_play", []) time.sleep(2) print("Stopping playback...") client.send_message("/transport_stop", []) time.sleep(1) print("Rewinding to start...") client.send_message("/goto_start", []) print("Test complete!") ``` Install dependencies: ```bash pip install python-osc ``` Run: ```bash python3 test_osc.py ``` ## Common OSC Commands ### Transport Control ```bash # Start/Stop oscsend localhost 3819 /transport_play oscsend localhost 3819 /transport_stop # Recording oscsend localhost 3819 /rec_enable_toggle oscsend localhost 3819 /rec_enable i 1 # Enable recording oscsend localhost 3819 /rec_enable i 0 # Disable recording # Navigation oscsend localhost 3819 /goto_start oscsend localhost 3819 /goto_end oscsend localhost 3819 /rewind oscsend localhost 3819 /ffwd # Loop oscsend localhost 3819 /loop_toggle oscsend localhost 3819 /set_loop_range # Set loop to current selection ``` ### Track/Strip Control ```bash # Gain control (ssid = strip ID, starts at 1) oscsend localhost 3819 /strip/gain if 1 0.5 # Set track 1 gain to 50% oscsend localhost 3819 /strip/gain if 1 1.0 # Set track 1 gain to 100% oscsend localhost 3819 /strip/gain if 1 0.0 # Set track 1 gain to 0% # Fader control (in dB) oscsend localhost 3819 /strip/fader if 1 0.0 # Set track 1 to 0dB oscsend localhost 3819 /strip/fader if 1 -6.0 # Set track 1 to -6dB oscsend localhost 3819 /strip/fader if 1 -inf # Set track 1 to -infinity # Pan control (-1.0 = full left, 0.0 = center, 1.0 = full right) oscsend localhost 3819 /strip/pan_stereo_position if 1 0.0 # Center oscsend localhost 3819 /strip/pan_stereo_position if 1 -1.0 # Full left oscsend localhost 3819 /strip/pan_stereo_position if 1 1.0 # Full right # Mute/Solo oscsend localhost 3819 /strip/mute if 1 1 # Mute track 1 oscsend localhost 3819 /strip/mute if 1 0 # Unmute track 1 oscsend localhost 3819 /strip/solo if 1 1 # Solo track 1 oscsend localhost 3819 /strip/solo if 1 0 # Unsolo track 1 # Record enable oscsend localhost 3819 /strip/recenable if 1 1 # Enable recording on track 1 oscsend localhost 3819 /strip/recenable if 1 0 # Disable recording on track 1 # Monitor oscsend localhost 3819 /strip/monitor_input if 1 1 oscsend localhost 3819 /strip/monitor_disk if 1 1 ``` ### Session Information ```bash # Get track list oscsend localhost 3819 /strip/list # Get track name oscsend localhost 3819 /strip/name if 1 # Get session frame rate oscsend localhost 3819 /session/frame_rate # Get current time oscsend localhost 3819 /session/timecode ``` ### Master Bus Control ```bash # Master gain oscsend localhost 3819 /master/gain f 1.0 # Master mute oscsend localhost 3819 /master/mute i 1 # Master fader (dB) oscsend localhost 3819 /master/fader f 0.0 ``` ## Python Examples ### Complete Control Script ```python #!/usr/bin/env python3 # ardour_control.py - Comprehensive Ardour control example from pythonosc import udp_client import time import sys class ArdourOSC: def __init__(self, host="127.0.0.1", port=3819): self.client = udp_client.SimpleUDPClient(host, port) def transport_play(self): """Start playback""" self.client.send_message("/transport_play", []) def transport_stop(self): """Stop playback""" self.client.send_message("/transport_stop", []) def goto_start(self): """Jump to session start""" self.client.send_message("/goto_start", []) def set_track_gain(self, track_id, gain): """Set track gain (0.0 to 1.0)""" self.client.send_message("/strip/gain", [track_id, gain]) def set_track_fader(self, track_id, db): """Set track fader in dB""" self.client.send_message("/strip/fader", [track_id, db]) def mute_track(self, track_id, mute=True): """Mute or unmute a track""" self.client.send_message("/strip/mute", [track_id, 1 if mute else 0]) def solo_track(self, track_id, solo=True): """Solo or unsolo a track""" self.client.send_message("/strip/solo", [track_id, 1 if solo else 0]) def set_pan(self, track_id, position): """Set pan position (-1.0 to 1.0)""" self.client.send_message("/strip/pan_stereo_position", [track_id, position]) def rec_enable_track(self, track_id, enable=True): """Enable/disable recording on a track""" self.client.send_message("/strip/recenable", [track_id, 1 if enable else 0]) def main(): # Create controller ardour = ArdourOSC() print("Ardour OSC Control Demo") print("-" * 40) # Example workflow print("1. Going to start...") ardour.goto_start() time.sleep(1) print("2. Setting up track 1...") ardour.set_track_fader(1, -6.0) # Set to -6dB ardour.set_pan(1, 0.0) # Center pan ardour.mute_track(1, False) # Ensure unmuted time.sleep(1) print("3. Starting playback...") ardour.transport_play() time.sleep(5) print("4. Stopping playback...") ardour.transport_stop() print("\nDemo complete!") if __name__ == "__main__": main() ``` ### Batch Track Setup ```python #!/usr/bin/env python3 # setup_mix.py - Batch configure multiple tracks from pythonosc import udp_client def setup_standard_mix(): """Set up a standard rock band mix""" client = udp_client.SimpleUDPClient("127.0.0.1", 3819) # Define mix template # Format: (track_id, gain_db, pan, name) mix_template = [ (1, -6.0, 0.0, "Kick"), # Center, moderate level (2, -8.0, 0.0, "Snare"), # Center, slightly lower (3, -10.0, -0.3, "Tom 1"), # Left of center (4, -10.0, 0.3, "Tom 2"), # Right of center (5, -6.0, -0.8, "OH Left"), # Hard left (6, -6.0, 0.8, "OH Right"), # Hard right (7, -4.0, 0.0, "Bass"), # Center, loud (8, -6.0, -0.5, "Guitar L"), # Left (9, -6.0, 0.5, "Guitar R"), # Right (10, -3.0, 0.0, "Vocal"), # Center, loudest ] print("Setting up standard rock mix...") for track_id, gain_db, pan, name in mix_template: print(f" Configuring {name} (Track {track_id})") client.send_message("/strip/fader", [track_id, gain_db]) client.send_message("/strip/pan_stereo_position", [track_id, pan]) print("Mix setup complete!") if __name__ == "__main__": setup_standard_mix() ``` ### OSC Monitor ```python #!/usr/bin/env python3 # osc_monitor.py - Monitor OSC messages from Ardour from pythonosc import dispatcher from pythonosc import osc_server import argparse def print_handler(unused_addr, *args): """Print all received OSC messages""" print(f"[OSC] {unused_addr}: {args}") def main(): parser = argparse.ArgumentParser() parser.add_argument("--ip", default="127.0.0.1", help="Listen IP") parser.add_argument("--port", type=int, default=3820, help="Listen port") args = parser.parse_args() # Set up dispatcher to catch all messages disp = dispatcher.Dispatcher() disp.set_default_handler(print_handler) # Create server server = osc_server.ThreadingOSCUDPServer((args.ip, args.port), disp) print(f"OSC Monitor listening on {args.ip}:{args.port}") print("Configure Ardour to send feedback to this port") print("Press Ctrl+C to exit\n") try: server.serve_forever() except KeyboardInterrupt: print("\nShutting down...") if __name__ == "__main__": main() ``` ## Node.js Examples ### Basic OSC Client ```javascript // ardour-osc.js - Node.js OSC client for Ardour const osc = require('node-osc'); class ArdourOSC { constructor(host = '127.0.0.1', port = 3819) { this.client = new osc.Client(host, port); } send(address, ...args) { this.client.send(address, ...args); } play() { this.send('/transport_play'); } stop() { this.send('/transport_stop'); } setTrackGain(trackId, gain) { this.send('/strip/gain', trackId, gain); } setTrackFader(trackId, db) { this.send('/strip/fader', trackId, db); } muteTrack(trackId, mute = true) { this.send('/strip/mute', trackId, mute ? 1 : 0); } } // Example usage const ardour = new ArdourOSC(); console.log('Testing Ardour connection...'); ardour.play(); setTimeout(() => ardour.stop(), 3000); ``` Install dependencies: ```bash npm install node-osc ``` ## Shell Script Examples ### Quick Control Script ```bash #!/bin/bash # ardour-ctl.sh - Shell script for Ardour control OSC_HOST="localhost" OSC_PORT="3819" osc_send() { oscsend "$OSC_HOST" "$OSC_PORT" "$@" } case "$1" in play) echo "Starting playback..." osc_send /transport_play ;; stop) echo "Stopping playback..." osc_send /transport_stop ;; start) echo "Jumping to start..." osc_send /goto_start ;; mute) if [ -z "$2" ]; then echo "Usage: $0 mute " exit 1 fi echo "Muting track $2..." osc_send /strip/mute if "$2" 1 ;; unmute) if [ -z "$2" ]; then echo "Usage: $0 unmute " exit 1 fi echo "Unmuting track $2..." osc_send /strip/mute if "$2" 0 ;; *) echo "Usage: $0 {play|stop|start|mute|unmute} [args]" exit 1 ;; esac ``` Make executable: ```bash chmod +x ardour-ctl.sh ``` Usage: ```bash ./ardour-ctl.sh play ./ardour-ctl.sh mute 1 ./ardour-ctl.sh stop ``` ## OSC Message Reference ### Path Format ``` /strip/ [ssid] [arguments] ``` Where: - `ssid` = Strip/track ID (starts at 1) - Arguments vary by command ### Complete Command List See the [Ardour OSC documentation](https://manual.ardour.org/using-control-surfaces/controlling-ardour-with-osc/osc-control/) for the complete list of supported messages. Common patterns: ``` /strip/[parameter] if [ssid] [value] /[global_command] /master/[parameter] [value] ``` ## Troubleshooting ### No Response from Ardour 1. Verify OSC is enabled in preferences 2. Check port number (default: 3819) 3. Ensure Ardour is running 4. Test with debug output: `ARDOUR_DEBUG=OSC just run` ### Messages Not Received 1. Check firewall settings 2. Verify correct IP address (use 127.0.0.1 for local) 3. Ensure UDP protocol (not TCP) 4. Test with `oscdump` to monitor traffic ### Permission Issues ```bash # Check port permissions sudo lsof -i :3819 # Allow local OSC traffic sudo ufw allow from 127.0.0.1 to any port 3819 ``` ## Best Practices 1. **Always use localhost (127.0.0.1)** for development 2. **Add error handling** in scripts 3. **Add delays** between rapid commands (10-50ms) 4. **Test commands individually** before batch operations 5. **Enable debug mode** during development 6. **Document your OSC workflows** for team members 7. **Use strip names** instead of IDs when possible (via feedback) ## Next Steps 1. Read the complete guide: `doc/ardour-mcp-integration.md` 2. Set up ardour-mcp server 3. Try the examples above 4. Create your own control scripts 5. Share your workflows with the community ## Resources - OSC Specification: http://opensoundcontrol.org/ - python-osc: https://pypi.org/project/python-osc/ - node-osc: https://www.npmjs.com/package/node-osc - Ardour Manual: https://manual.ardour.org/ --- **Last Updated**: 2025-11-06