Splicing a 5-hour set into tracks without clicks at 44.1 kHz

这篇内容暂时只有 English 版本,以下是原文。

Last spring I inherited a 5-hour, 44.1 kHz/16-bit stereo recording of a warehouse party — one WAV, 1.6 GB, no tracklist, and a promoter who wanted per-track files for a digital release. The DJ never stopped the decks, so every transition was a beat-matched overlap. I had no stems and no cue sheet, only the mix itself.

My approach was to find transitions rather than guess track boundaries. I ran a short-time RMS envelope at 100 ms hops and looked for the moments where the spectral centroid changed sharply while the overall energy stayed roughly flat — overlaps, not drops.

import numpy as np
from scipy.io import wavfile

sr, x = wavfile.read('set.wav')
x = x.astype(np.float32).mean(axis=1) / 32768.0
hop = int(sr * 0.1)
frames = len(x) // hop
rms = np.array([np.sqrt(np.mean(x[i*hop:(i+1)*hop]**2)) for i in range(frames)])
centroid = np.array([
    np.sum(np.abs(np.fft.rfft(x[i*hop:(i+1)*hop])) * np.arange(len(np.fft.rfft(x[i*hop:(i+1)*hop]))))
    / (np.sum(np.abs(np.fft.rfft(x[i*hop:(i+1)*hop]))) + 1e-9)
    for i in range(frames)
])
centroid /= sr

I then flagged candidate windows where the 4-second rolling centroid delta exceeded a threshold and RMS stayed within 2 dB. That gave me 61 candidate overlaps in 5 hours. I listened to each at 0.5× speed, kept 47 as real transitions, and cut at the midpoint of each overlap.

Why midpoint? In a 30–60 second beat-matched overlap, the midpoint is usually the only place where both tracks are at similar level, so a hard cut there leaks the least of the outgoing track. The cost: I moved every boundary by up to 20 seconds from where the DJ actually started the next record. For a release that mattered less than clean starts.

Where this fails: ambient breakdowns and vocal-only sections have almost no RMS change, so the detector goes quiet exactly when a transition is most exposed. I missed two long ambient bridges that way. It also fails on sets recorded with a limiter engaged — the RMS stays pinned and the 2 dB rule rejects real transitions. I had to rerun that segment with a 5 dB window and check by ear.

The one thing I’d change: I cut before checking the file for sample-rate drift. Two hours in, the recording had crept by a few samples relative to the timestamps I computed, and three cuts landed 80 ms late. Audible on a hard snare.

If you’ve done this on sets with long ambient sections, how do you catch transitions that barely move the RMS?

0
赞同度 100% · 0 条评论 · 4 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。