# `Mx.Fit`
[🔗](https://github.com/mx-music/mx/blob/main/lib/mx/fit.ex#L1)

Searches for the values of a synth's controls that bring its held notes closest to recordings of them, as `mix mx.fit` does.

The recordings come in dynamics, each a vel and the files played at it, and each dynamic is measured as `Mx.Measure.Held` measures held notes.
Notes found below the lowest note given are spurious onsets, and stretches whose fundamental stands more than 25 dB below the median fundamental of their dynamic are breaths or key clicks between notes, so both are left out.
The synth renders at every semitone from the lowest note given to the highest found, at each dynamic's vel, without vibrato, held as long as the recordings' notes at that dynamic hold, the median of those kept.
A setting scores how far each band's harmonics and the noise between them, from the lowest frequency given up to 4 kHz, fall more than 4 dB from the recordings', and how far the attack falls more than 20 percent from theirs, at each dynamic.
The search tries each control a step up and a step down, keeps whichever lowers the score, and goes through the controls three times.

# `lowest`

The lowest note of the files given.

# `misses`

Each dynamic's attack ratio less one, or nil when the recordings have no attack, and for each band the level of its harmonics, then of its noise, in the recordings and the difference in dB, the synth's against the recordings', with the given controls.
A band is left out of either list where the recordings or the synth have no figure for it.

# `recordings`

Measures each `{vel, [{path, note}]}` dynamic, and returns `{:ok, dynamics, cached?}` or `{:error, message}` naming the file.

Each dynamic has its vel, attack and band levels, and how many notes it kept, found below the lowest note, and found too quiet.
With `drone` true, each file is measured as one note held from its first sample to its last, and the attack is nil, since a drone's recording starts wherever it was cut.
The figures are kept in the system's temporary folder and reused until a file changes.

# `score`

The score of misses: 0 when every band's harmonics and noise are within 4 dB and every attack within 20 percent.

# `search`

Searches from the controls' starting values, each a map of name, value, step and whether the step is a ratio.

`report` is called with `{:start, score}`, `{:round, number}` and `{:kept, name, value, score}`, and the best values and their score are returned.

# `step`

A value moved a step up, direction 1, or down, -1.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
