A CLI audio analysis tool that tells you what's wrong with your mix — and what to do about it.
Bounce House runs 26 metrics across loudness, spectral balance, stereo imaging, tuning, and perceptual quality. Every metric gets a pass/warn/fail assessment with plain-English advice. Nine diagnostic patterns catch common mixing problems (muddy low end, crushed dynamics, mono-incompatible stereo) by combining evidence across modules. Compare against a reference track, batch-analyze an album, or pipe --json into your CI pipeline.
I made this while working on a new DIY aggressive guitar-and-synth music project, listening to my first round of mixes on a car stereo and being utterly dismayed with bounces gone wrong. There was so much to fix. I wondered if I should create a tool to save some time and be more goal-directed in my mixing and mastering process (you obviously still have to listen to your mixes). I bit the bullet and made the bulk of bounce-house across just a few days while in Albany, NY visiting family. The more you know 🌈
# Install with uv (recommended)
uv sync
# Analyze a mix
bounce-house analyze mix.wav
# Short alias
bh analyze mix.wavcd bounce-house
uv synccd bounce-house
pip install .pip install git+https://github.com/abehmiel/bounce-house.gitPerceptual analysis — install timbral_models for AudioCommons perceptual metrics (brightness, warmth, hardness, roughness) instead of proxy calculations:
uv sync --extra perceptual
# or: pip install ".[perceptual]"True peak measurement — install ffmpeg for inter-sample true peak detection via the loudnorm filter. Without ffmpeg, bounce-house falls back to sample peak measurement.
bounce-house analyze mix.wavRun a single analysis module when you only care about one domain:
bounce-house loudness mix.wav # EBU R128 loudness, dynamics, crest factor
bounce-house spectrum mix.wav # Spectral centroid, bandwidth, band energies
bounce-house stereo mix.wav # Phase correlation, M/S ratio, stereo width
bounce-house perceptual mix.wav # Brightness, warmth (proxy or timbral_models)
bounce-house tuning mix.wav # Tuning deviation, pitch drift, chroma sharpnessbounce-house compare mix.wav reference.wavShows all metrics for your mix alongside band-by-band energy differences against the reference track. Useful for matching tonal balance to a commercially released track in your genre.
Built-in documentation for every metric — what it measures, why it matters, good ranges, and genre-specific context:
bounce-house explain # Overview of all metrics
bounce-house explain loudness # All metrics in a module
bounce-house explain crest # Single metric (fuzzy matched)
bounce-house explain lra --technical # Include measurement standardsAnalyze all WAV files in a directory at once — great for checking an album, stems folder, or CI pipeline:
bounce-house dir ./masters/ # All WAVs in directory
bounce-house dir ./masters/ --recursive # Include subdirectories
bounce-house dir ./masters/ --json # Machine-readable output
bounce-house dir ./masters/ --reference ref.wav # Compare all against referenceEach file gets a full report, followed by a summary table:
════════════════════════════════════════════════════════════
DIRECTORY SUMMARY (3 files)
════════════════════════════════════════════════════════════
File LUFS Peak Crest W F Status
────────────────────────────────────────────────────────
track_01.wav -13.2 -1.0 10.2 0 0 PASS
track_02.wav -11.8 -0.5 8.1 1 0 WARN
track_03.wav -7.4 -0.1 5.2 1 2 FAIL
════════════════════════════════════════════════════════════
2 warning(s), 2 failure(s) across 3 files
════════════════════════════════════════════════════════════
Exit codes for CI/CD gating: 0 = all pass, 1 = warnings, 2 = failures. Corrupt files are logged to stderr without stopping the batch.
By default, bounce-house analyzes audio as a finished master. For pre-master
mixes, use --stage mix to get thresholds calibrated for mixing:
bounce-house analyze my_mix.wav --stage mix
bounce-house dir ./mixes --stage mixMix mode adjusts:
- LUFS targets (-24 to -14 instead of -16 to -8)
- Peak thresholds (warns at -3 dBFS instead of -1 dBTP)
- Crest factor tolerance (more lenient for unmixed dynamics)
- Disables streaming-readiness checks
- Adds headroom and bus limiter diagnostics
All analysis commands support --json for machine-readable output:
bounce-house analyze mix.wav --json
bounce-house loudness mix.wav --json
bounce-house dir ./masters/ --json════════════════════════════════════════════════════════════
BOUNCE HOUSE — Mix Analysis Report
mix.wav (44100 Hz, stereo, 0:03)
════════════════════════════════════════════════════════════
── Loudness & Dynamics ────────────────────────────────────
Integrated LUFS -7.8 WARN
Loudness Range +2.6 FAIL
Sample Peak -5.5
True Peak -5.5 PASS
RMS Level -10.0
Crest Factor +4.6 FAIL
── Spectral Balance ───────────────────────────────────────
Centroid 624 Hz
Bandwidth 774 Hz
Rolloff (85%) 891 Hz
Flatness 0.0000
sub-bass 7.0 dB
bass 40.9 dB
low-mid 34.3 dB
mid 22.2 dB
upper-mid 9.4 dB
presence -30.7 dB
brilliance -43.4 dB
── Stereo & Phase ─────────────────────────────────────────
Phase Correlation 0.9813 PASS
Mid RMS -10.1
Side RMS -29.7
M/S Ratio +19.6
Stereo Width 0.0950
Balance +0.7 WARN
Min Block Corr 0.9813 PASS
Frequency-dependent correlation:
sub-bass +0.999
low-mid +0.990
mid +0.940
upper-mid +0.697
air +1.000
── Perceptual Quality ─────────────────────────────────────
Brightness 0.0000
Warmth 0.9184
── Suggestions ────────────────────────────────────────────
FAIL Loudness range is 2.6 LU — extreme dynamics, review compressor/limiter settings
FAIL Crest factor is 4.6 dB — heavily squashed, reduce limiting or compression
WARN Integrated loudness is -7.8 LUFS — outside typical -16 to -8 range
WARN Channel balance is +0.7 dB — slight imbalance, check panning
── Mix Diagnostics ────────────────────────────────────────
FAIL Over-Compressed — Over-compressed master; dynamics crushed
Reduce bus compressor ratio or increase threshold. Ease off the
limiter — aim for at least 8 dB crest factor.
════════════════════════════════════════════════════════════
2 warning(s), 2 failure(s)
════════════════════════════════════════════════════════════
Bounce House measures 26 metrics across 5 analysis modules. Run bounce-house explain for full documentation including genre-specific context and measurement standards.
| Metric | What it measures | Good range |
|---|---|---|
| Integrated LUFS | Perceived loudness (ITU-R BS.1770) | -16 to -8 LUFS |
| Loudness Range (LRA) | Dynamic spread, quiet to loud (EBU R128) | 5 to 15 LU |
| True Peak | Maximum reconstructed waveform level | Below -1.0 dBTP |
| Sample Peak | Maximum digital sample value | Below -0.3 dBFS |
| RMS Level | Average signal power | -20 to -10 dB |
| Crest Factor | Peak-to-RMS ratio (transient headroom) | 8 to 14 dB |
| PLR | Peak-to-Loudness Ratio — over-compression indicator | Above 10 dB |
| Metric | What it measures | Good range |
|---|---|---|
| Spectral Centroid | Center of mass — correlates with brightness | 1500 to 3500 Hz |
| Spectral Bandwidth | Energy spread around centroid | 1500 to 4000 Hz |
| Spectral Rolloff (85%) | Upper edge of significant energy | 4000 to 8000 Hz |
| Spectral Flatness | Tonality vs. noise (0.0 = tone, 1.0 = noise) | 0.1 to 0.4 |
| Band Energies | Energy in 7 frequency bands (sub-bass through brilliance) | Relative |
| Metric | What it measures | Good range |
|---|---|---|
| Phase Correlation | L/R correlation — mono compatibility | +0.3 to +0.7 |
| Mid RMS | Center channel energy (M/S) | Relative |
| Side RMS | Difference channel energy (M/S) | Relative |
| M/S Ratio | Mid-to-side balance | 3 to 12 dB |
| Stereo Width | Side-to-total energy ratio | 0.2 to 0.4 |
| Channel Balance | L/R level difference | Within +/- 0.5 dB |
| Min Block Correlation | Worst-case phase in any 50ms window | Above 0.0 |
| Frequency-Dependent Correlation | Per-band stereo correlation | Sub-bass >0.9 |
| Metric | What it measures | Good range |
|---|---|---|
| Brightness | High-frequency energy ratio | 0.1 to 0.3 |
| Warmth | Low-mid energy ratio | 0.1 to 0.3 |
| Metric | What it measures | Good range |
|---|---|---|
| Tuning Deviation | Offset from A440 concert pitch | Within ±8 cents |
| Concert Pitch (A) | Estimated frequency of concert A | 435 to 445 Hz |
| Pitch Drift Range | Total pitch excursion over time | Under 8 cents |
| Chroma Sharpness | How well-defined pitch content is (0-1) | Above 0.6 |
Beyond per-metric pass/warn/fail assessments, Bounce House includes a multi-metric diagnostic engine that detects 9 common mixing problems by combining evidence across modules. Diagnostics appear in a dedicated section at the bottom of the report when triggered.
Each pattern uses soft-AND logic: a problem fires when enough conditions match (e.g., 2 of 3), so a single borderline metric won't produce a false alarm.
| Pattern | Severity | What it detects |
|---|---|---|
| Muddy Mix | warn | Low-mid buildup — centroid too low, warmth too high |
| Harsh / Brittle | warn | Excessive high-mid energy — bright, fatiguing |
| Thin / Weak | warn | Missing low-frequency body — HPFs too aggressive |
| Over-Compressed | fail | Dynamics crushed — low crest factor, hot LUFS, low LRA |
| Flat / Lifeless | warn | No stereo width or dynamic variation |
| Mono Incompatible | fail | Wide stereo with phase cancellation in mono |
| Wide Bass | warn | Stereo bass losing energy on mono playback |
| Detuned Mix | warn | Pitch instability or non-standard tuning |
| Streaming-Unfriendly | fail | Too hot for platform normalization (-14 LUFS target) |
Diagnostics layer on top of individual metric rules — they don't replace them. A mix can have clean per-metric scores but still trigger a diagnostic (e.g., "streaming-unfriendly" combines LUFS, true peak, and LRA).
Bounce House follows a pipeline: load → analyze → assess → diagnose → format.
wav file
│
▼
audio.py Load via soundfile → AudioData (samples, sr, channels)
│
▼
analyzers/ Each analyzer extends BaseAnalyzer
├── loudness EBU R128 via pyloudnorm, crest factor, true peak (ffmpeg)
├── spectrum librosa spectral features + 7-band energy via STFT
├── stereo Phase correlation, M/S decomposition, frequency-dependent width
├── perceptual Brightness/warmth (proxy or timbral_models)
└── tuning Pitch deviation, drift, chroma sharpness (librosa)
│
▼
rules.py Data-driven pass/warn/fail rules per metric
│
▼
diagnostics.py Multi-metric pattern engine (9 mixing problems)
│
▼
report.py Terminal (ANSI) or JSON formatter
│
▼
cli.py argparse dispatch, entry point: bounce-house / bh
Key design decisions:
- Analyzers are stateless — each takes
AudioDataand returnsAnalysisResultwith a metrics dict - Rules are data, not code — adding a new assessment rule means adding a dict entry, not writing a function
- Metric docs live in code —
metric_docs.pycontains all 26 metric explanations, used by both theexplaincommand and (potentially) report tooltips - Diagnostics combine metrics —
diagnostics.pydefines pattern conditions as data, evaluated with soft-AND logic across modules
Most audio measurement tools are either GUI plugins or single-purpose CLI utilities:
- bx_meter, Youlean, Insight — DAW plugins with visual meters. Great for real-time monitoring during mixing, but can't be scripted, automated, or run in CI.
- EXPOSE — batch loudness scanner. Focuses on loudness compliance (LUFS, true peak) for delivery. Doesn't cover spectral balance, stereo imaging, or actionable mix advice.
- loudness-scanner — CLI for EBU R128 loudness only. Single metric, no spectral or stereo analysis.
Bounce House combines multi-domain analysis (loudness + spectrum + stereo + perceptual) with a rule engine that produces actionable mixing advice — all from the command line. Pipe --json output into your own scripts or CI workflows.
Core: soundfile, numpy, scipy, pyloudnorm, librosa, rich
Optional: timbral_models (perceptual analysis), ffmpeg (true peak measurement)
# Clone and install dev dependencies
git clone https://github.com/abehmiel/bounce-house.git
cd bounce-house
uv sync --extra dev
# Set up pre-commit hooks
uv run pre-commit install
# Run tests
uv run pytest
# Run linter
uv run ruff check src/ tests/
# Run type checker
uv run mypy src/src/bounce_house/
├── __init__.py Version
├── audio.py Audio loading (soundfile → AudioData)
├── cli.py CLI entry point and argparse setup
├── rules.py Pass/warn/fail assessment rules
├── report.py Terminal and JSON formatters
├── metric_docs.py Metric documentation for explain command
├── diagnostics.py Multi-metric diagnostic pattern engine
├── profiles.py Stage profiles (mix vs. master thresholds)
└── analyzers/
├── base.py BaseAnalyzer, AnalysisResult, Assessment
├── loudness.py EBU R128, dynamics, true peak
├── spectrum.py Spectral features, band energies
├── stereo.py Phase, M/S, stereo width
├── perceptual.py Brightness, warmth
└── tuning.py Tuning deviation, pitch drift, chroma sharpness
tests/
├── conftest.py Synthetic audio fixtures
├── test_audio.py
├── test_cli.py
├── test_diagnostics.py
├── test_explain.py
├── test_loudness.py
├── test_perceptual.py
├── test_profiles.py
├── test_report.py
├── test_rules.py
├── test_spectrum.py
├── test_stereo.py
└── test_tuning.py
MIT