SAS Audio Processor

# SAS Audio Processor This is a component of [Signals & Sorcery](https://signalsandsorcery.com/), a music production application. A suite of 25 audio processing tools — trim, normalize, compress, EQ, reverb, pitch-shift, time-stretch, key detection, MIDI extraction, and more — exposed as MCP tools via [DeclarAgent](https://github.com/shiehn/DeclarAgent). ## What You Get | Category | Tools | |----------|-------| | **Processing** | trim, time-stretch, convert, mono, silence-remove, split-bars | | **Effects** | normalize, gain, compress, eq, reverb, limit, filter, pitch-shift | | **Analysis** | analyze, detect-key, loudness, onset-detect | | **MIDI** | melody-to-midi | | **Composite** | master-track, sample-prep, tempo-match, full-analysis, melody-extract | Every tool accepts WAV files and outputs structured JSON. ## Quick Start (Claude Code) This is the primary use case — use these audio tools directly from Claude Code via MCP. ### 1. Install DeclarAgent ```bash go install github.com/shiehn/declaragent@latest ``` ### 2. Install sas-audio-processor ```bash # From source git clone https://github.com/shiehn/sas-audio-processor.git cd sas-audio-processor python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt && pip install -e . ``` Or use the pre-built binary (macOS only): ```bash ./build.sh # Binary at dist/sas-processor/sas-processor ``` ### 3. Add MCP config Add to `~/.claude/settings.json`: ```json { "mcpServers": { "sas-audio": { "command": "declaragent", "args": ["--plans-dir", "/path/to/sas-audio-processor/plans"] } } } ``` ### 4. Use it Now Claude Code has access to all 25 audio tools. Example conversation: ``` You: Analyze this drum loop and tell me the BPM Claude: [calls analyze tool] The drum loop is at 128 BPM, 44100 Hz, stereo, 8.2 seconds long. You: Trim it to 4 bars and normalize to -14 LUFS Claude: [calls trim tool, then normalize tool] Done — trimmed to 4 bars starting at the downbeat, normalized to -14 LUFS. You: Now master it Claude: [calls master-track tool] Applied normalize → compress → limit chain. Output saved. ``` ## Quick Start (Other MCP Clients) ### Claude Desktop Add to `claude_desktop_config.json`: ```json { "mcpServers": { "sas-audio": { "command": "declaragent", "args": ["--plans-dir", "/path/to/sas-audio-processor/plans"] } } } ``` ### Cursor / Windsurf / Copilot Add the same MCP server config to your editor's MCP settings. The `command` and `args` are identical — only the config file location differs per editor. ## How It Works ``` MCP Client (Claude Code, Claude Desktop, etc.) │ └─► DeclarAgent (reads YAML plan files from plans/) │ └─► sas-processor --input ... --output ... │ └─► stdout: JSON result ``` Each YAML plan file in `plans/` defines one MCP tool. DeclarAgent reads these at startup and exposes them to MCP clients. When a tool is called, DeclarAgent runs the `sas-processor` CLI under the hood. ## Available Tools ### Processing | Tool | Description | |------|-------------| | `trim` | Detect downbeat and trim audio to specified number of bars | | `time-stretch` | Change tempo while preserving pitch | | `convert` | Change sample rate and/or bit depth | | `mono` | Convert stereo to mono | | `silence-remove` | Trim silence from start and end | | `split-bars` | Split audio into N-bar chunks | ### Effects | Tool | Description | |------|-------------| | `normalize` | Normalize to target LUFS or peak level | | `gain` | Apply volume change in dB | | `compress` | Dynamics compression with threshold/ratio/attack/release | | `eq` | Parametric EQ band (boost or cut at frequency) | | `reverb` | Algorithmic reverb with room size and wet/dry mix | | `limit` | Brick-wall limiter | | `filter` | High-pass or low-pass filter | | `pitch-shift` | Shift pitch by semitones | ### Analysis | Tool | Description | |------|-------------| | `analyze` | Detect BPM, duration, sample rate, channels | | `detect-key` | Detect musical key and mode (major/minor) | | `loudness` | Measure integrated LUFS and peak dB | | `onset-detect` | Detect onset/transient times | ### MIDI | Tool | Description | |------|-------------| | `melody-to-midi` | Extract monophonic melody to MIDI file | ### Composite (Multi-Step) | Tool | Description | |------|-------------| | `master-track` | normalize → compress → limit | | `sample-prep` | analyze → trim → normalize → convert | | `tempo-match` | analyze → time-stretch to target BPM | | `full-analysis` | analyze + detect-key + loudness | | `melody-extract` | normalize → melody-to-midi | ## CLI Reference All subcommands output line-delimited JSON to stdout. Errors go to stderr as JSON. ```bash sas-processor [options] ``` ### ping ```bash sas-processor ping ``` Health check — returns version and status. ### analyze ```bash sas-processor analyze --input ``` Returns BPM, duration, sample rate, and channel count. ### trim ```bash sas-processor trim --input --output --bpm --bars [--meter 4] [--verbose] ``` Detects the downbeat and trims audio to the specified number of bars. ### time-stretch ```bash sas-processor time-stretch --input --output --source-bpm --target-bpm ``` Changes tempo while preserving pitch. ### normalize ```bash sas-processor normalize --input --output [--mode lufs|peak] [--target-lufs -14] [--target-peak -1] ``` ### gain ```bash sas-processor gain --input --output --db ``` ### mono ```bash sas-processor mono --input --output ``` ### convert ```bash sas-processor convert --input --output [--sample-rate ] [--bit-depth 16|24|32] ``` ### silence-remove ```bash sas-processor silence-remove --input --output [--top-db 30] ``` ### compress ```bash sas-processor compress --input --output [--threshold -20] [--ratio 4] [--attack 1.0] [--release 100] ``` ### eq ```bash sas-processor eq --input --output --freq --gain-db [--q 1.0] ``` ### reverb ```bash sas-processor reverb --input --output [--room-size 0.5] [--damping 0.5] [--wet-level 0.33] ``` ### limit ```bash sas-processor limit --input --output [--threshold -1] ``` ### filter ```bash sas-processor filter --input --output --type highpass|lowpass --cutoff-hz ``` ### pitch-shift ```bash sas-processor pitch-shift --input --output --semitones ``` ### detect-key ```bash sas-processor detect-key --input ``` Returns key, mode (major/minor), and confidence score. ### loudness ```bash sas-processor loudness --input ``` Returns integrated LUFS and peak dB. ### onset-detect ```bash sas-processor onset-detect --input ``` Returns onset count and onset times in seconds. ### split-bars ```bash sas-processor split-bars --input --output-dir --bpm [--bars-per-chunk 1] [--meter 4] ``` ### melody-to-midi ```bash sas-processor melody-to-midi --input --output ``` ## Building from Source ### Prerequisites - macOS 10.15+ - Python 3.9+ ### Build Steps ```bash git clone https://github.com/shiehn/sas-audio-processor.git cd sas-audio-processor python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt && pip install -e . # Build self-contained binary pyinstaller sas-processor.spec --clean --noconfirm # Output: dist/sas-processor/ ``` Or use the build script: ```bash ./build.sh ``` ### Cross-Architecture Builds **Apple Silicon (ARM64):** ```bash pyinstaller sas-processor.spec --clean --noconfirm mv dist/sas-processor dist/sas-processor-arm64 ``` **Intel (x86_64):** ```bash arch -x86_64 /bin/bash -c " python3 -m venv venv-x64 source venv-x64/bin/activate pip install -r requirements.txt pyinstaller sas-processor.spec --clean --noconfirm " mv dist/sas-processor dist/sas-processor-x86_64 ``` ## Running Tests ```bash source venv/bin/activate # All tests pytest tests/ -v # E2E subcommand tests only pytest tests/test_plans_e2e.py -v # With coverage pytest tests/ -v --cov=sas_processor ``` ## JSON Output Format All subcommands output line-delimited JSON to stdout. ### Result (stdout) ```json {"type": "", "success": true, "output": "/path/to/output.wav", ...} ``` ### Progress Events (stdout, trim only) ```json {"type": "progress", "stage": "loading", "percent": 0} {"type": "progress", "stage": "detecting", "percent": 30} {"type": "progress", "stage": "trimming", "percent": 60} {"type": "progress", "stage": "complete", "percent": 100} ``` ### Errors (stderr) ```json {"type": "error", "code": "FILE_NOT_FOUND", "message": "Input file not found: /path/to/file.wav", "severity": "fatal"} ``` ## Creating a Release Releases are built automatically by GitHub Actions. To create a new release: 1. Update the version in `pyproject.toml` 2. Commit and push your changes 3. Tag the commit and push the tag: ```bash git tag v2.0.0 git push origin v2.0.0 ``` This triggers the release workflow which: - Runs tests on both architectures - Builds self-contained binaries for **ARM64** (Apple Silicon) and **x86_64** (Intel) - Creates a GitHub Release with both `.tar.gz` archives attached Download binaries from the [Releases](https://github.com/shiehn/sas-audio-processor/releases) page. ## Limitations - **WAV only** — no MP3, FLAC, or other formats - **macOS only** — binary builds target macOS (CLI works anywhere Python runs) - **Binary size ~220MB** — due to numpy/scipy/librosa dependencies ## License MIT