
Delivery · 23 October 2026 · 8 min
Making a clean version? Edit the vocals, keep the length, then check it against the explicit
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
| Method | How it sounds | Good for |
|---|---|---|
| Mute (short fades) | A gap in the vocal while the beat keeps going | Fast verses, where a small gap reads like a breath |
| Reverse | The word plays backwards, so rhythm and energy stay | Hip-hop radio edits. Reverse the word, not the phrase |
| Replace | A re-sung or alternate word, or an ad-lib over it | Radio, sync and anything that should sound unedited |
| Effect drop | A filter, tape stop or sound effect swallows the word | Once 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:
- Doubles, stacks and harmonies. Every track that sings the line sings the word.
- Ad-libs and hype tracks. They often carry more of it than the lead does.
- Reverb and delay. Mute the word on the dry vocal after the send and the delay throw repeats it a beat later. Edit before the sends, or automate the send down for that word. If the effect returns were printed, edit those too. Throws are covered in setting your delay from the tempo.
- The beat. Vocal chops and samples in the instrumental, or the hook teased in the intro.
- Bleed. On a live-tracked record the vocal is in the drum overheads and room mics too. Muting the vocal track leaves the word under the cymbals.
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
- Hip-hop. Reverses and mutes are both familiar to radio ears. Mute short words in fast verses and reverse longer ones, and check the ad-lib track first.
- Pop and R&B. Replace where you can. Re-singing a word while the session is still open takes minutes and sounds like nothing happened.
- Rock and metal. Gang vocals and room mics carry words. On live-tracked songs, plan to edit several tracks or replace the line.
- Live recordings. The crowd and every open mic can carry the word. A replacement or an effect drop is often the only clean option.
- 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.