如何使用上下文窗口对整个日志梅尔频谱图进行分段(确保所有音频的分段数量相同)?

时间:2019-01-18 20:22:49

标签: audio audio-processing spectrogram librosa windowing

我有几个音频,音频的持续时间不同。因此,我不知道如何确保音频片段的N个相同。我正在尝试实施现有的论文,因此,据说首先通过使用25 ms的汉明窗和10 ms的重叠在整个音频中使用从20到8000 Hz的64个Mel滤波器组在整个音频中执行Log Mel-Spectrogram 。然后,为了得到我有以下代码行:

y, sr = librosa.load(audio_file, sr=None)
#sr = 22050
#len(y) = 237142
#duration = 5.377369614512472

n_mels = 64
n_fft = int(np.ceil(0.025*sr)) ## I'm not sure how to complete this parameter
win_length = int(np.ceil(0.025*sr)) # 0.025*22050
hop_length = int(np.ceil(0.010*sr)) #0.010 * 22050
window = 'hamming'

fmin = 20
fmax = 8000

S = librosa.core.stft(y, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, center=False)
M = np.log(librosa.feature.melspectrogram(y=y, sr=sr, S=S, n_mels=n_mels,fmin=fmin, fmax=fmax)#, kwargs=M)
+ 1e-6)

# M.shape = (64, 532)

(我也不确定如何完成该n_fft参数。) 然后,说:

  

使用64帧的上下文窗口划分整个日志   梅尔频谱图分为大小为64x64的音频段。移位大小为   分割期间使用30帧,即两个相邻的片段   与30帧重叠。因此,每个分割的段都有一个长度   64帧,其持续时间为10毫秒x(64-1)+ 25毫秒= 655毫秒。

因此,我被困在最后一部分,我不知道如何执行64x64的M分割。以及如何为所有音频获得相同数量的片段(具有不同的持续时间),因为最终我将需要64x64xN的特征作为我的神经网络或分类器的输入?我将不胜感激!我是音频信号处理的初学者。

1 个答案:

答案 0 :(得分:0)

沿时间轴翻转帧,一次向前移动30帧,并提取最后64帧的窗口。在开始和结束时,您需要截断或填充数据以获得完整的帧。

import librosa
import numpy as np
import math

audio_file = librosa.util.example_audio_file()
y, sr = librosa.load(audio_file, sr=None, duration=5.0) # only load 5 seconds

n_mels = 64
n_fft = int(np.ceil(0.025*sr))
win_length = int(np.ceil(0.025*sr))
hop_length = int(np.ceil(0.010*sr))
window = 'hamming'

fmin = 20
fmax = 8000

S = librosa.core.stft(y, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, center=False)
frames = np.log(librosa.feature.melspectrogram(y=y, sr=sr, S=S, n_mels=n_mels, fmin=fmin, fmax=fmax) + 1e-6)


window_size = 64
window_hop = 30

# truncate at start and end to only have windows full data
# alternative would be to zero-pad
start_frame = window_size 
end_frame = window_hop * math.floor(float(frames.shape[1]) / window_hop)

for frame_idx in range(start_frame, end_frame, window_hop):

    window = frames[:, frame_idx-window_size:frame_idx]
    assert window.shape == (n_mels, window_size)
    print('classify window', frame_idx, window.shape)

将输出

classify window 64 (64, 64)
classify window 94 (64, 64)
classify window 124 (64, 64)
...
classify window 454 (64, 64)

但是,窗口的数量将取决于音频样本的长度。因此,如果重要的是只有相同数量的窗口,则需要确保所有音频样本的长度均相同。