Как использовать контекстное окно для сегментирования целого журнала Mel-спектрограммы (обеспечивая одинаковое количество сегментов для всех аудио)? - PullRequest
0 голосов
/ 18 января 2019

У меня есть несколько аудио разной длительности.Поэтому я не знаю, как обеспечить одинаковое количество N сегментов аудио.Я пытаюсь реализовать существующую статью, поэтому сказано, что сначала выполняется Log Mel-Spectrogram во всем аудио с 64 банками Mel-фильтров от 20 до 8000 Гц с использованием окна Хэмминга 25 мс и перекрытия 10 мс,Затем, чтобы получить это, у меня есть следующие строки кода:

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 кадров, чтобы разделить весь журнал Mel-спектрограммы на аудиосегменты размером 64x64.Во время сегментации используется размер сдвига в 30 кадров, т.е. два соседних сегмента перекрываются 30 кадрами.Следовательно, каждый разделенный сегмент имеет длину 64 кадра, а его продолжительность составляет 10 мс x (64-1) + 25 мс = 655 мс.

Итак, я застрял в этой последней части,Я не знаю, как выполнить сегментацию M на 64x64.И как я могу получить одинаковое количество сегментов для всех аудио (с разной длительностью), потому что в финале мне понадобятся функции 64x64xN в качестве входных данных для моей нейронной сети или классификатора?Я буду очень признателен за любую помощь!Я новичок в обработке аудио сигналов.

1 Ответ

0 голосов
/ 23 января 2019

Цикл по кадрам вдоль оси времени, перемещение вперед на 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)

Однако количество окон будет зависеть от длины аудиосэмпла. Так что если важно иметь одинаковое количество окон, вам нужно убедиться, что все аудиосэмплы имеют одинаковую длину.

...