GitHub - shiehn/sas-audio-processor: sas-audio-processor

6 min read Original article ↗

SAS Audio Processor

SAS Audio Processor

This is a component of Signals & Sorcery, 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.

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

go install github.com/stevehiehn/declaragent@latest

2. Install sas-audio-processor

# From source
git clone https://github.com/stevehiehn/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):

./build.sh
# Binary at dist/sas-processor/sas-processor

3. Add MCP config

Add to ~/.claude/settings.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:

{
  "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 <subcommand> --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.

sas-processor <subcommand> [options]

ping

Health check — returns version and status.

analyze

sas-processor analyze --input <file>

Returns BPM, duration, sample rate, and channel count.

trim

sas-processor trim --input <file> --output <file> --bpm <float> --bars <int> [--meter 4] [--verbose]

Detects the downbeat and trims audio to the specified number of bars.

time-stretch

sas-processor time-stretch --input <file> --output <file> --source-bpm <float> --target-bpm <float>

Changes tempo while preserving pitch.

normalize

sas-processor normalize --input <file> --output <file> [--mode lufs|peak] [--target-lufs -14] [--target-peak -1]

gain

sas-processor gain --input <file> --output <file> --db <float>

mono

sas-processor mono --input <file> --output <file>

convert

sas-processor convert --input <file> --output <file> [--sample-rate <int>] [--bit-depth 16|24|32]

silence-remove

sas-processor silence-remove --input <file> --output <file> [--top-db 30]

compress

sas-processor compress --input <file> --output <file> [--threshold -20] [--ratio 4] [--attack 1.0] [--release 100]

eq

sas-processor eq --input <file> --output <file> --freq <float> --gain-db <float> [--q 1.0]

reverb

sas-processor reverb --input <file> --output <file> [--room-size 0.5] [--damping 0.5] [--wet-level 0.33]

limit

sas-processor limit --input <file> --output <file> [--threshold -1]

filter

sas-processor filter --input <file> --output <file> --type highpass|lowpass --cutoff-hz <float>

pitch-shift

sas-processor pitch-shift --input <file> --output <file> --semitones <float>

detect-key

sas-processor detect-key --input <file>

Returns key, mode (major/minor), and confidence score.

loudness

sas-processor loudness --input <file>

Returns integrated LUFS and peak dB.

onset-detect

sas-processor onset-detect --input <file>

Returns onset count and onset times in seconds.

split-bars

sas-processor split-bars --input <file> --output-dir <dir> --bpm <float> [--bars-per-chunk 1] [--meter 4]

melody-to-midi

sas-processor melody-to-midi --input <file> --output <file.mid>

Building from Source

Prerequisites

  • macOS 10.15+
  • Python 3.9+

Build Steps

git clone https://github.com/stevehiehn/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:

Cross-Architecture Builds

Apple Silicon (ARM64):

pyinstaller sas-processor.spec --clean --noconfirm
mv dist/sas-processor dist/sas-processor-arm64

Intel (x86_64):

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

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)

{"type": "<subcommand>", "success": true, "output": "/path/to/output.wav", ...}

Progress Events (stdout, trim only)

{"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)

{"type": "error", "code": "FILE_NOT_FOUND", "message": "Input file not found: /path/to/file.wav", "severity": "fatal"}

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