CoProducer Measure a mix
Two brass tuning forks on black marble in a dark studio, a cyan wave above the taller fork flowing into a slightly lower magenta wave above the shorter one

Pitch · 8 October 2026 · 12 min

What 432 Hz actually changes in a finished master

NoDAW Labs · Lacquer Vol. 05

Moving a finished master from A=440 to A=432 multiplies every frequency in the file by 432/440 = 0.981818, which is about 31.77 cents lower, a little under a third of a semitone. Harmony, mix balance, and loudness stay where they were. With plain resampling the track also runs about 1.85% longer, so 120 BPM becomes 117.82.

Somebody always brings it up near the end of a session. The record is done, the master is approved, and then someone asks what it would sound like at 432. Half the room rolls their eyes. The other half has already heard a video saying it’s the frequency of the universe. And the person who actually has to render the file just wants to know what’s going to happen to it.

So let’s skip the mythology and the eye-rolling and look at what really changes in the file. Some of it is exact math. Some of it is measurable but small. Some of it is taste, and taste is a perfectly good reason to make a record. It just isn’t physics.

What “440” actually refers to

When people say a record is “in 440,” they mean the tuning reference: the A above middle C (A4) sits at 440 cycles per second, and every other note in equal temperament is placed relative to it. That reference is the international standard, ISO 16, the standard tuning frequency. It doesn’t mean anything in the song actually is 440 Hz. A finished master holds fundamentals, overtones, kick resonances, room reflections, cymbal noise, and reverb tails spread across the whole audible range. The 440 is just where the grid is anchored.

Retuning a finished master to 432 doesn’t re-pitch notes one at a time the way Auto-Tune would. It slides the entire grid. Every component, from the sub to the hiss, gets multiplied by the same number:

Because every frequency moves by the same ratio, every interval survives. A major third is still a major third. The chord is the same chord, played from a slightly lower floor.

Follow one note through the conversion

Claims are cheap, so here’s a script that renders an exact 432 version and then shows you what moved. It finds the strongest partials before and after so you can watch A4 and its harmonics land where the math says they should. It also measures length, tempo, integrated loudness, and true peak. It writes a new 24-bit WAV and never touches your original.

One detail is worth a sentence. FFmpeg’s asetrate only takes whole numbers, and 48000 × 0.981818 = 47127.27. So the script first upsamples to a rate that divides cleanly by 55 (52.8 kHz for a 48 kHz file, 48.51 kHz for 44.1), relabels it at exactly 54/55 of that rate, and resamples back. That gives the exact ratio and no rounding.

#!/usr/bin/env python3
"""retune_check.py: render an exact 440 -> 432 classic retune and prove what moved.
Usage: python3 retune_check.py in.wav [out_432.wav]
Needs: numpy + ffmpeg on PATH. Works on any sample rate that is a multiple of 50 Hz
(44.1, 48, 88.2, 96 kHz...). Writes a 24-bit WAV; never touches the input.

Prints the ratio math, the strongest partials before and after (so you can follow A4
and its harmonics), duration, tempo, integrated loudness, and true peak."""
import re, subprocess, sys
import numpy as np

SRC, TGT = 440, 432
r = TGT / SRC
src = sys.argv[1]
out = sys.argv[2] if len(sys.argv) > 2 else re.sub(r"\.\w+$", "", src) + "_432.wav"

def probe_sr(path):
    return int(subprocess.run(["ffprobe", "-v", "error", "-select_streams", "a:0", "-show_entries",
                               "stream=sample_rate", "-of", "csv=p=0", path],
                              capture_output=True, text=True, check=True).stdout.strip())

def decode(path, sr):
    raw = subprocess.run(["ffmpeg", "-v", "error", "-i", path, "-ac", "1", "-ar", str(sr), "-f", "f32le", "-"],
                         capture_output=True, check=True).stdout
    return np.frombuffer(raw, dtype=np.float32)

def loudness(path):
    err = subprocess.run(["ffmpeg", "-nostats", "-hide_banner", "-i", path, "-af",
                          "ebur128=peak=true:framelog=quiet", "-f", "null", "-"],
                         capture_output=True, text=True).stderr
    s = err[err.rfind("Summary:"):]
    return (float(re.search(r"I:\s+(-?[\d.]+) LUFS", s).group(1)),
            float(re.search(r"Peak:\s+(-?[\d.]+) dBFS", s).group(1)))

def partials(x, sr, fmax=2000.0, top=8):
    """Strongest spectral peaks (Hann window, zero-padded FFT, parabolic interpolation)."""
    n = 1 << int(np.ceil(np.log2(len(x)))) + 1
    mag = np.abs(np.fft.rfft(x * np.hanning(len(x)), n))
    lm = 20 * np.log10(mag + 1e-12)
    f = np.fft.rfftfreq(n, 1 / sr)
    k = np.where((f > 30) & (f < fmax))[0]
    pk = k[(lm[k] > lm[k - 1]) & (lm[k] >= lm[k + 1])]
    pk = pk[np.argsort(lm[pk])[::-1]]
    chosen = []
    for p in pk:                                   # skip side lobes within 3 Hz of a stronger peak
        if all(abs(f[p] - f[q]) > 3 for q in chosen):
            chosen.append(p)
        if len(chosen) == top:
            break
    res = []
    for p in sorted(chosen):
        a, b, c = lm[p - 1], lm[p], lm[p + 1]
        d = 0.5 * (a - c) / (a - 2 * b + c)
        res.append((f[p] + d * (f[1] - f[0]), b))
    return res

def tempo(x, sr):
    """BPM from the autocorrelation of an onset envelope (low band + high band, 2 ms hop).
    The beat-length peak is refined at 8 beats out, which makes the estimate 8x finer."""
    hop = int(0.002 * sr)
    spec = np.fft.rfft(x); f = np.fft.rfftfreq(len(x), 1 / sr)
    onset = 0
    for band in (f < 200, f > 2000):
        b = np.fft.irfft(spec * band, len(x))
        e = np.sqrt(np.mean(b[: len(b) // hop * hop].reshape(-1, hop) ** 2, axis=1))
        o = np.maximum(np.diff(e), 0)
        onset = onset + o / (o.max() + 1e-12)
    ac = np.correlate(onset, onset, "full")[len(onset) - 1:]
    fps = sr / hop
    ok = np.arange(int(fps * 60 / 180), int(fps * 60 / 70))
    i = ok[np.argmax(ac[ok])]                       # one beat
    j = 8 * i + np.argmax(ac[8 * i - 8: 8 * i + 9]) - 8  # eight beats
    d = 0.5 * (ac[j - 1] - ac[j + 1]) / (ac[j - 1] - 2 * ac[j] + ac[j + 1])
    return 60 * 8 / ((j + d) / fps)

sr = probe_sr(src)
if sr % 50:
    sys.exit("sample rate must be a multiple of 50 Hz for the exact chain")
up = sr * 11 // 10                      # 48000 -> 52800, 44100 -> 48510 (both divisible by 55)
chain = f"aresample={up},asetrate={up * 54 // 55},aresample={sr}"   # 54/55 == 432/440 exactly
subprocess.run(["ffmpeg", "-v", "error", "-y", "-i", src, "-af", chain, "-c:a", "pcm_s24le", out], check=True)

x, y = decode(src, sr), decode(out, sr)
print(f"ratio          : {TGT}/{SRC} = {r:.6f}   shift = {1200 * np.log2(r):+.2f} cents")
print(f"ffmpeg chain   : {chain}")
print(f"duration       : {len(x) / sr:.3f} s -> {len(y) / sr:.3f} s  ({100 * (len(y) / len(x) - 1):+.2f}%, expect {100 * (1 / r - 1):+.2f}%)")
print("partials (Hz)  :  before   ->  after     ratio     cents")
after = partials(y, sr, top=16)
for fb, lvl in partials(x, sr):
    fa = min(after, key=lambda p: abs(p[0] - fb * r))[0]
    print(f"                {fb:8.2f} -> {fa:8.2f}   {fa / fb:.6f}  {1200 * np.log2(fa / fb):+7.2f}")
bi, bo = tempo(x, sr), tempo(y, sr)
print(f"tempo          : {bi:.2f} BPM -> {bo:.2f} BPM  (x{bo / bi:.4f}, expect x{r:.4f})")
(li, ti), (lo, to) = loudness(src), loudness(out)
print(f"integrated     : {li:.1f} LUFS -> {lo:.1f} LUFS")
print(f"true peak      : {ti:+.2f} dBTP -> {to:+.2f} dBTP")
print(f"wrote          : {out}")

Run it on your own bounce with python3 retune_check.py mix.wav. It needs Python with numpy, plus ffmpeg on your PATH.

What it printed on a synthetic loop

The test file is synthetic. We built it on the box so the answers are known in advance, and it isn’t anyone’s record. It’s a 17-second, 48 kHz, 120 BPM loop with an A-major pad (A3, A4, C♯5, E5 with overtones), a 55 Hz sub note on every bar, a pitch-swept kick, and short high ticks on every eighth note. Here’s the real output, trimmed to the parts that matter:

ratio          : 432/440 = 0.981818   shift = -31.77 cents
ffmpeg chain   : aresample=52800,asetrate=51840,aresample=48000
duration       : 17.000 s -> 17.315 s  (+1.85%, expect +1.85%)
partials (Hz)  :  before   ->  after     ratio     cents
                   55.00 ->    54.00   0.981819   -31.77
                  220.00 ->   216.00   0.981818   -31.77
                  440.00 ->   432.00   0.981818   -31.77
                  554.37 ->   544.29   0.981818   -31.77
                  659.26 ->   647.27   0.981818   -31.77
                  880.00 ->   864.00   0.981818   -31.77
                 1108.73 ->  1088.57   0.981818   -31.77
tempo          : 120.00 BPM -> 117.82 BPM  (x0.9818, expect x0.9818)
integrated     : -15.1 LUFS -> -15.1 LUFS
true peak      : -3.00 dBTP -> -3.00 dBTP

Every partial moved by the same ratio to six decimal places. A4 landed on 432. Its octave, 880, landed on 864. The 55 Hz sub, which is A1, landed on 54. The third of the chord, C♯5, went from 554.37 to 544.29. Divide each by its A and you get 1.25993 both times, so the interval didn’t move at all. That’s the whole idea in one line: the chord keeps its shape and sits about a third of a semitone lower.

The tempo was measured from the audio, not just calculated: 120.00 BPM went in and 117.82 came out. Loudness and true peak didn’t move at the meter’s resolution.

We also ran the same loop after pushing it 12 dB into a limiter, so it looked more like a modern master. It measured −6.7 LUFS and −0.40 dBTP before, and −6.8 LUFS and −0.40 dBTP after. That’s close to unchanged, but notice we said measured. Resampling rebuilds the waveform, so on a real master inter-sample peaks can land a little differently. Measure the file you’re actually going to ship. It takes ten seconds.

About that rounding detail: if you skip the trick and just write asetrate=47127, the error is −0.01 cents and about one millisecond over a three-minute song. Nobody will hear it. It only matters if you document your masters like an archivist, and some of us do.

What does not change

This is where most of the confusion lives, so here it is plainly. A 432 conversion is one operation. It doesn’t do any of the following.

Where you’ll actually hear it

Thirty-two cents is subtle, but it isn’t nothing. Most trained listeners can tell a shift that size when they A/B it directly. Where it shows up:

MaterialWhat usually changesHow obvious
Exposed lead vocalChest weight drops slightly; bright vowels lose a touch of edgeClear in a synced A/B
Sustained 808 / subThe fundamental moves down (55 → 54 Hz on an A1); on small speakers it slides a bit further toward roll-offFelt more than heard
Piano, pads, stringsThe whole chord sits lower and decays read slightly longer with resamplingClear on held chords
Dense distorted chorusPitch center is masked by saturation and drumsOften hard to call
Groove and pocketWith resampling the tempo drops 1.85%: 120 → 117.82, 140 → 137.45Some feel it as “laid back”
Hats and cymbalsSpectrum moves down by the same ratio and timing stretches slightlyRarely noticed on its own

The sub row deserves a second look if you make 808 records. An 808 tuned to E1 (41.2 Hz) lands around 40.5 Hz after conversion. That won’t matter on a club system. On a phone that’s already rolling off below 100 Hz, you’re hearing harmonics anyway, and they move down by the same ratio. It’s worth one check on the small speaker before you commit.

How to compare without fooling yourself

The fastest way to convince yourself of anything is a bad A/B. Everyone has done it: the new version is half a dB louder, or you restart it from the top while the old one was mid-chorus, and your brain hands you a winner. A few rules make the comparison honest.

  1. Same source, rendered once. Use the approved WAV, not a stream rip. Change only the tuning.
  2. Level-matched. Don’t normalize one side and leave the other. If the files measure differently, it’s because something else in the chain changed.
  3. Same musical position. This is where plain resampling gets tricky. The 432 file is longer, so ten seconds into the original lines up with about 10.185 seconds into the retune. If your player switches by clock time, you drift a little further off the beat with every switch. By the end of a three-minute song you’re off by more than three seconds.
  4. Short loops, reversed order, a break. Fifteen to thirty seconds of something exposed, switched every few bars. Take five minutes away, come back, and run it in the opposite order. If the preference survives that, it’s real for you.

That third rule is the one people trip on, and it’s why reTUNE[432] is built around a synced A/B player. It maps the same musical position between the 440 and 432 versions, so switching lands on the same syllable instead of the same clock reading. The retune happens locally in the browser, so your unreleased master never leaves your machine. When a song earns a full alternate, the $4 system adds full-length export and an offline Windows batch for folders, other reference targets, and optional LUFS delivery copies. If the comparison doesn’t win you over, keep the 440. That’s a perfectly good result.

Shipping a 432 alternate like a professional

If the lower version wins, treat it as its own deliverable, not as a replacement:

If the master is going out anyway, dropping both versions into CoProducer’s analyzer is a quick way to confirm that loudness and true peak are still legal side by side. Pitch is a choice. The delivery rules don’t change.

And if you need the alternate to keep the exact original runtime for picture lock, choreography, or a fixed DJ grid, that’s a different operation with different trade-offs. We measured those trade-offs in Resampling, pitch shifting, and tempo change are three different jobs.

Does converting a song to 432 Hz change its key?
Not by name. The shift is −31.77 cents, less than a third of a semitone, so a song in A minor is still labeled A minor. It just sits lower than a 440-referenced A minor, and it will sound slightly flat next to unshifted instruments.
Does 432 Hz make a song slower?
With plain resampling, yes. Length grows by 1.85% and tempo drops by the same ratio, so 120 BPM becomes 117.82. A time-preserving pitch shift keeps the original tempo but can add artifacts.
Is 432 Hz better for your health or more natural?
There’s no reliable evidence for health benefits. ISO 16 sets A4 at 440 Hz as a shared reference for coordination, and 432 is a valid creative alternative. Prefer it if it sounds better to you. That’s the honest claim.
Does retuning to 432 change LUFS or true peak?
Usually only slightly. On our synthetic loop, integrated loudness and true peak stayed within the meter’s 0.1 resolution. Resampling rebuilds the waveform, so always re-measure the final file before delivery.
What is the exact ratio for 440 to 432?
432/440 = 0.981818, which is exactly 54/55. That works out to −31.77 cents. In FFmpeg you can apply it exactly by upsampling to a rate divisible by 55, relabeling the rate at 54/55, then resampling back.

A free one-pager

The checklist we run before every release.

Loudness, true peak, mono, tails, export settings and the metadata basics, on one page. Leave your email and it opens straight away, or read it here first. No email needed for that.