CoProducer Measure a mix
Two gold waveform sculptures side by side on black marble, the second one glowing magenta, a brass toggle switch and studio headphones beside them, studio monitors behind in soft cyan and magenta light

Delivery · 23 October 2026 · 8 min

Making a clean version? Edit the vocals, keep the length, then check it against the explicit

NoDAW Labs · Lacquer Vol. 06

A clean version is the explicit song with only the flagged words changed on the vocal tracks: muted, reversed or replaced, then bounced through the same master chain at exactly the same length. Edit the vocals, not the stereo mix, so the beat never drops out, and chase every copy of the word, including doubles, ad-libs and the reverb and delay tails. Then compare the two bounces. They should match everywhere except your edits.

Someone wants the clean. A radio show, a playlist, a sync brief, a school event, your distributor. The fast way is to drop the whole mix out on every curse, and it sounds exactly like that: the beat cuts out mid-bar, the energy dies, and the edit is louder than the word ever was.

A good clean edit is one where people only notice the word is gone, not that you were there.

Mute, reverse or replace

MethodHow it soundsGood for
Mute (short fades)A gap in the vocal while the beat keeps goingFast verses, where a small gap reads like a breath
ReverseThe word plays backwards, so rhythm and energy stayHip-hop radio edits. Reverse the word, not the phrase
ReplaceA re-sung or alternate word, or an ad-lib over itRadio, sync and anything that should sound unedited
Effect dropA filter, tape stop or sound effect swallows the wordOnce or twice a song, or it starts to draw attention

Whatever you choose, cut from just before the first consonant to just after the last one. The front of a hard consonant is how a listener recognises a word, and a reversed word with the original first letter still in it isn’t clean. Some stations and platforms have their own rules on reversals, so if the edit is for someone specific, ask what they accept.

Where the word is hiding

The lead vocal is the easy part. A word you muted can still be in the song in half a dozen places:

Fade every edit by a few milliseconds so nothing clicks. We measured why in clicks at your edit points.

Same chain, same length

Bounce the clean from the same session, through the same master chain, with the same settings and the same start point. Don’t master it separately. A different chain changes the tone and loudness, and the two versions stop lining up. When they match sample for sample, a DJ can switch between them mid-song, a video editor can drop one in for the other, and any cue points or sync timings work on both.

When you upload, the clean is its own track with its own ISRC, and most distributors ask you to mark it as the clean version of the explicit one. A song that never had explicit lyrics isn’t a clean version, it’s just not explicit.

Check the clean against the explicit

Ears are good at finding the words you missed. They’re bad at noticing that the clean is 40 milliseconds shorter or half a dB louder. A file comparison catches those in a second. This script checks the format and length, then lists every stretch where the two files differ by more than −60 dBFS:

#!/usr/bin/env python3
"""Check a clean (or radio) edit against the explicit bounce: same format, same length, and a list of
every place the two files differ. Outside your edits they should match. Usage:
python3 compare_versions.py explicit.wav clean.wav [threshold dB, default -60]"""
import sys, wave, numpy as np

def load(path):
    with wave.open(path) as w:
        p = (w.getframerate(), w.getnchannels(), w.getsampwidth()); nf = w.getnframes()
        x = np.frombuffer(w.readframes(nf), {2: "<i2", 3: None, 4: "<i4"}[p[2]]).astype(float)
    return x.reshape(-1, p[1]) / (2 ** (8 * p[2] - 1)), p

(a, pa), (b, pb) = load(sys.argv[1]), load(sys.argv[2])
thr = float(sys.argv[3]) if len(sys.argv) > 3 else -60
sr = pa[0]
print(f"format: {pa[0]} Hz / {pa[1]} ch / {8*pa[2]}-bit vs {pb[0]} Hz / {pb[1]} ch / {8*pb[2]}-bit"
      + ("  OK" if pa == pb else "  MISMATCH"))
print(f"length: {len(a)} vs {len(b)} samples ({len(a)/sr:.3f} s vs {len(b)/sr:.3f} s)"
      + ("  OK" if len(a) == len(b) else f"  OFF BY {abs(len(a)-len(b))} samples"))
m = min(len(a), len(b)); hop = sr // 100
d = (a[:m] - b[:m])[: m // hop * hop].reshape(-1, hop, a.shape[1])
lvl = 20 * np.log10(np.sqrt((d ** 2).mean(axis=(1, 2))) + 1e-12)        # 10 ms RMS of the difference
diff = lvl > thr
regions, i = [], 0
while i < len(diff):
    if diff[i]:
        j = i
        while j < len(diff) and (diff[j] or (j + 5 < len(diff) and diff[j:j + 5].any())): j += 1  # bridge <50 ms gaps
        regions.append((i, j)); i = j
    else: i += 1
same = 100 * (1 - diff.mean())
print(f"identical (difference under {thr:.0f} dBFS) for {same:.1f}% of the song; {len(regions)} edit region(s):")
for k, (i, j) in enumerate(regions[:12], 1):
    print(f"  {k}: {i/100:6.2f}-{j/100:6.2f} s  ({(j-i)*10:4d} ms)  peak difference {lvl[i:j].max():6.1f} dBFS")
if len(regions) > 12 or same < 50:
    print("  -> differs almost everywhere: not the same mix/master chain, or the files are offset")

We built a 12-second test: a beat and a vocal of 13 short sung words, mastered with gain and a simple peak limiter with a 100 ms release. In the clean, the words at 3.10 s and 7.60 s are muted with 5 ms fades and the word at 9.85 s is reversed:

$ python3 compare_versions.py explicit.wav clean.wav
format: 44100 Hz / 2 ch / 16-bit vs 44100 Hz / 2 ch / 16-bit  OK
length: 529200 vs 529200 samples (12.000 s vs 12.000 s)  OK
identical (difference under -60 dBFS) for 90.7% of the song; 3 edit region(s):
  1:   3.10-  3.51 s  ( 410 ms)  peak difference   -6.9 dBFS
  2:   7.60-  8.01 s  ( 410 ms)  peak difference   -7.5 dBFS
  3:   9.85- 10.15 s  ( 300 ms)  peak difference   -2.1 dBFS

Same format, same length, identical for 90.7% of the song, and three edits for the three words we changed. That count is the point: if your list says four words and the script finds three, one slipped through. The two mutes show up as 410 ms for a 300 ms word, because the limiter on the master eased off for its 100 ms release once the word was gone, so the beat under the gap came up slightly. That’s normal with a limiter on the bus. The reversed word changes only its own 300 ms.

Here’s the same check after bouncing the clean through the master 0.5 dB hotter, as if it had been mastered separately:

$ python3 compare_versions.py explicit.wav clean_hot.wav
format: 44100 Hz / 2 ch / 16-bit vs 44100 Hz / 2 ch / 16-bit  OK
length: 529200 vs 529200 samples (12.000 s vs 12.000 s)  OK
identical (difference under -60 dBFS) for 0.2% of the song; 1 edit region(s):
  1:   0.00- 12.00 s  (12000 ms)  peak difference   -2.1 dBFS
  -> differs almost everywhere: not the same mix/master chain, or the files are offset

Half a dB is easy to miss by ear and impossible to miss here. The script can only tell you what changed, not what didn’t, so a word you forgot to edit won’t show up. Listen to every edit plus a second after it for tails, then play the whole clean once from top to bottom. If a plugin in the chain adds noise or random modulation, the files won’t match exactly even where nothing changed. Raise the threshold to around −50 dBFS, or print those tracks first.

When you only have the master

Old song, dead hard drive, a beat from a producer who stopped answering. If all you have is the stereo master, separating it lets you edit the words on the vocal alone and play it back over the instrumental, so the beat keeps running under every edit. Pull the vocal with StemSplit, edit and fade the words on that stem, then sum the two back together. Separated stems rarely add back to the exact master, so run the compare script at a looser threshold, around −40 dBFS, and trust your ears over the numbers around each edit. The bleed caveats are the same as in sampling from separated stems.

Genre notes

How do you make a clean version of a song?
Edit the explicit words on every vocal track (mute, reverse or replace them, with short fades), deal with the reverb and delay tails, then bounce from the same session through the same master chain so the clean is the same length as the explicit.
Should I mute or reverse curse words?
Both are common. Muting leaves a gap that works in fast verses; reversing keeps the rhythm and energy. Cut from just before the first consonant, and ask the station or platform what they accept if the edit is for them.
Why can I still hear the word after I muted it?
It’s usually somewhere else: a double, an ad-lib, a delay or reverb tail fed before your edit, or vocal bleed in other mics. Edit before the sends and check every track that sings the line.
Does a clean version need its own ISRC?
Yes. The clean is a separate recording version, so it gets its own ISRC, and most distributors ask you to mark it as the clean version of the explicit track.

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.