我有一个音频信号,我想从中检测大声时刻。
我遇到的问题是我不确定我下面提供的算法/代码是否正确。
我在很多帖子中读到“响度”的概念很复杂并且取决于个人。我还了解到可以使用频谱图、A 加权和 RMS 以某种方式对其进行近似。我是音频处理方面的新手,但根据我所读到的内容,我编写了以下算法:
我使用Librosa编写的对应代码是:
# Load the input audio
y, sr = librosa.load(path, sr=22050)
# Compute the spectrogram (magnitude)
n_fft = 2048
hop_length = 1024
spec_mag = abs(librosa.stft(y, n_fft=n_fft, hop_length=hop_length))
# Convert the spectrogram into dB
spec_db = librosa.amplitude_to_db(spec_mag)
# Compute A-weighting values
freqs = librosa.fft_frequencies(sr=sr, n_fft=n_fft)
a_weights = librosa.A_weighting(freqs)
a_weights = np.expand_dims(a_weights, axis=1)
# Apply the A-weghting to the spectrogram in dB
spec_dba = spec_db + a_weights
# Compute the "loudness" value
loudness = librosa.feature.rms(S=librosa.db_to_amplitude(spec_dba))
我的进展顺利吗? 这个算法正确吗? 我正确使用 Librosa 吗?
谢谢您的帮助。
我不知道你的编程语言,但这个概念似乎几乎是正确的。
尽管由于 a 加权,您不需要转换为 db,因为通常的 a 加权函数已经适用于线性 0-1。
对于LUFS通常的方式如下:
对于每个通道单独,
应用 k 滤波器(fft 后跟 a 加权,但也有使用 HP/LP 滤波器的更简单的实现)
均方
对于 Prologic 或沉浸式音频格式:您可能还需要从后置和天花板扬声器中减去一些 db,例如 5.1 中后置扬声器为 -1.5 db
求和频道
10log10
这是历史/实时。
那么对于 LUFS 你会这样做:
整合结果(累积整个轨道上的值,同时忽略低于-60db的时刻)
对于prologic:LFE通道不是游戏的一部分,你完全忽略它。
您可以尝试PyDub库。为您提供 DB 卷。