Lab · Audio ML · Apache 2.0

Sound like
the record.

ToneMatch matches a guitar tone from a song's real audio. Give it the recording and your own dry guitar, and it returns the amp settings that make you sound like the record.

58%less tone error than noon knobs 24 / 24held-out cases improved 3.4 MBCore ML, runs on iPhone
How it works

Two stages.
A fast guess, then a careful search.

The matcher only gets what a guitarist actually has: the song, and a recording of their own guitar plugged straight in (a DI). It never sees the original amp or its settings.

The songstudio or phone mic Your DIdry guitar 1 · Tone encoderlog-mel conv net 2 · CMA-ES search render DI at candidatescompare with the songmove toward the best Settings7 knobs

The encoder guesses

A small convolutional network listens to the song's log-mel spectrum and predicts seven amp knobs directly, plus a 128-d tone embedding. It is 3.4 MB as Core ML and runs on an iPhone, so the first answer is almost instant.

gainbassmidtreblepresencecab tonecab resonance

The search refines

Starting from that guess, CMA-ES (an evolution strategy) renders your DI through the amp at candidate settings, measures how far each one is from the song, and moves the knobs toward the closest. The guess means it starts near the answer instead of at noon.

Results

Measured on real amps.
Lower is better.

Median tone error in dB on 24 real mic'd-amp recordings per condition, each matched from a different take of the player's DI and scored on a held-out passage, so it measures tone rather than which notes were played. The baseline sets every knob to noon.

Studio file, guitar only

Knobs at noon3.68
Encoder1.81
Encoder + search1.54

58% less error · 24 / 24 wins

Studio file, full band mix

Knobs at noon3.68
Encoder1.84
Encoder + search1.60

57% less error · 24 / 24 wins

Phone mic in a room, guitar only

Knobs at noon3.68
Encoder1.91
Encoder + search1.96

Here the search is slightly worse than the encoder alone · 21 / 24 wins

Phone mic in a room, full band mix

Knobs at noon3.68
Encoder1.94
Encoder + search1.72

53% less error · 22 / 24 wins

ConditionBaselineEncoder onlyEncoder + searchWins (encoder + search)
Studio file, guitar only3.681.811.5424 / 24
Studio file, full band mix3.681.841.6024 / 24
Phone mic in a room, guitar only3.681.911.9621 / 24
Phone mic in a room, full band mix3.681.941.7222 / 24

The encoder's prediction alone beats the baseline on 24 / 24 cases in every condition. In the hardest setting, a band playing through a phone speaker into a room and heard by a phone mic, encoder + search cuts tone error by 53%. The test set is small, 24 real cases per condition, so the medians come with bootstrap intervals in the run output. Released encoder: run 3, step 15,723. Error is a multi-resolution STFT log-magnitude distance.

The benchmark

tonebench.
How we kept ourselves honest.

The repo includes the benchmark we used to build ToneMatch. Every matcher gets the same targets, DIs and scoring passages, so runs compare case by case, and every one has to beat knobs at noon.

Synthetic track

Targets made with known settings through the bench's own amp model, so knob error can be measured as well as tone.

Real track

Guitar-TECHS mic'd-amp recordings, scored against the real amp on a passage the matcher never heard.

Production levels

None, a mix (EQ and bus compression), full (plus reverb and MP3), or room: a phone speaker, room reflections, noise, a phone mic and AGC.

Band and separation

The guitar alone, inside a synthetic band mix, or separated back out with an oracle, Demucs or Spleeter.

Your take

A different DI take, or a play-along with timing drift and a few wrong notes, like a real player.

Matchers

Noon knobs, spectrum fitting, AFx-Rep embedding search, the encoder alone, and encoder + search.

Quick start

Run it yourself.

Needs Python 3.11+ and uv. The audio isn't included: download Guitar-TECHS and put it in data/guitar-techs/ at the repo root.

# Baselines (numpy only)
cd bench
uv run python run.py

# The released encoder, with and without search (needs torch)
uv run --group afx python run.py --matchers default pred_only pred_then_search
uv run --group afx python run.py --level room --band mix --matchers default pred_only pred_then_search

# Re-print tables from saved results
uv run python report.py results/run-*.json

Train your own

train_encoder.py trains on an Apple Silicon GPU (about 6.5 hours for run 3, also using GuitarSet), select_encoder.py picks a checkpoint and export_coreml.py exports it.

On device

The Swift code from the app is included for reference: the log-mel front end, the Core ML runner, CMA-ES and the matcher.

License

Apache 2.0. The released weights were trained on Guitar-TECHS and GuitarSet (CC BY 4.0); credit them if you use the weights. Full credits are in NOTICE.

Free to read, run
and build on.