Automated EQ matching between user audio and reference tracks
Project description
SongMatch
Automated EQ matching between your audio and a reference track.
SongMatch analyzes a reference track to find its loudest segment, splits both tracks into stems (vocals, drums, bass, other), applies per-stem spectral EQ matching, and recombines. It can also perform whole-mix mastering via matchering.
Features
- Per-stem EQ matching (
--stems-match): Separates both tracks into 4 stems, matches the spectral profile of each stem independently, then recombines - Whole-mix matching (
--mix-match): Full-mix frequency response, RMS, stereo width, and peak amplitude matching via matchering - Combined mode: Run both — stems-match first for tonal correction, then mix-match for overall polish
- Automatic loudest segment detection: Finds the chorus/loudest section of the reference using LUFS analysis with beat-aligned cropping
- GPU acceleration: Uses CUDA/MPS when available for faster stem separation
Installation
Requires Python 3.10+ and ffmpeg.
pip install songmatch
Or with uv:
uv pip install songmatch
Note: SongMatch pulls in large dependencies including PyTorch (~75MB) and audio-separator. First run will also download the stem separation model (~340MB).
Usage
# Per-stem EQ match
songmatch my_song.wav reference.wav --stems-match
# Whole-mix match
songmatch my_song.wav reference.wav --mix-match
# Both: per-stem EQ first, then whole-mix polish
songmatch my_song.wav reference.wav --stems-match --mix-match
At least one of --stems-match or --mix-match must be specified.
Options
| Option | Default | Description |
|---|---|---|
--eq-smoothing |
0.33 | EQ smoothing in octave fractions (0 = none) |
--eq-max-gain |
12.0 | Max EQ boost/cut in dB |
--loudness-threshold |
2.0 | dB below peak LUFS for segment detection |
--min-segment |
5.0 | Minimum reference crop duration (seconds) |
--max-segment |
30.0 | Maximum reference crop duration (seconds) |
--dynamic-range-floor |
4.0 | Below this LRA in dB, skip cropping |
--model |
htdemucs_ft.yaml | Stem separation model |
--output-sr |
44100 | Output sample rate (Hz) |
--output-bits |
16 | Output bit depth (16 or 24) |
--keep-ref-stems |
false | Keep reference stem temp files |
-v / --verbose |
false | Debug logging |
Output files
For input my_song.wav:
my_song_stemsmatched.wav # --stems-match result
my_song_mixmatched.wav # --mix-match result
my_song_stems/ # EQ-matched stems (from --stems-match)
vocals.wav
drums.wav
bass.wav
other.wav
How it works
--stems-match pipeline
- Analyze reference loudness (LUFS envelope) and find the loudest segment
- Snap crop boundaries to nearest beats
- Separate both reference segment and user audio into 4 stems (vocals, drums, bass, other)
- For each stem pair: compute PSDs via Welch's method, derive a smoothed transfer function, design a FIR filter, and convolve
- Recombine EQ-matched stems with peak normalization
--mix-match pipeline
- Pass user audio (or stems-match output) and full reference to matchering
- Matchering handles frequency response, RMS, stereo width, peak amplitude, and limiting
Combined mode
Stems-match runs first, then mix-match uses its output as input. Both output files are kept.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file songmatch-0.2.0.tar.gz.
File metadata
- Download URL: songmatch-0.2.0.tar.gz
- Upload date:
- Size: 187.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cdff5016dba9727c6dc7c92b723cd1a56471b4dfd369f0b51c485838550d3a6
|
|
| MD5 |
6e2c92cc976370f3cdd0b5271e4cfc7d
|
|
| BLAKE2b-256 |
e7db6253d9250d3a49961511fa88d9fcee7add29211421fd3c5f2d5f25608796
|
File details
Details for the file songmatch-0.2.0-py3-none-any.whl.
File metadata
- Download URL: songmatch-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
230a63e63fe883a7a501ab4be3a3cedccd8c23cc8be0dd5b39f865b8e88ad08d
|
|
| MD5 |
53cf964c254e97738d33d3c19dc8e465
|
|
| BLAKE2b-256 |
138d823719514798bf7d07aedeb719c33b430573f2752ac18d8591e370cafe9f
|