При восстановлении звука из мелспектрограммы есть обрезка с помощью librosa

Я делаю:


    melspectrogram = librosa.feature.melspectrogram(
        y=samples, sr=sample_rate, window=scipy.signal.hanning, n_fft=n_fft, hop_length=hop_length)

    print('melspectrogram.shape', melspectrogram.shape)
    print(melspectrogram)

    audio_signal = librosa.feature.inverse.mel_to_audio(
        melspectrogram, sr=sample_rate, n_fft=n_fft, hop_length=hop_length, window=scipy.signal.hanning)
    print(audio_signal, audio_signal.shape)

    sf.write('test.wav', audio_signal, sample_rate)

Реконструированный файл wav звучит очень похоже на оригинал, но имеет небольшие обрезки и звуковые артефакты. Есть ли способ реконструировать более совершенно?


person Shamoon    schedule 23.02.2020    source источник


Ответы (1)


Как указано в документации о mel_to_audio:

Это в первую очередь удобная оболочка для:

S = librosa.feature.inverse.mel_to_stft(M)
y = librosa.griffinlim(S)

Другими словами, сгенерированная спектрограмма Mel используется для аппроксимации величины STFT. Затем спектрограмма STFT преобразуется обратно во временную область с помощью Griffin Lim алгоритм.

Преобразование из спектрограммы Mel в STFT не полностью без потерь (могут быть перекрывающиеся диапазоны частот из-за перекрывающиеся треугольные фильтры, используемые при построении спектрограммы Мела), и преобразование из спектрограммы амплитуды STFT во временную область (т. е. в аудио), безусловно, не идеально, поскольку спектрограмма амплитуды STFT отсутствует информация о фазе, которая должна быть аппроксимирована с помощью алгоритма Гриффина Лима. Это приближение никогда не бывает идеальным и приводит к появлению фазовых артефактов (металлической фазности).

Не использование шкалы Mel, а просто использование STFT и обратного STFT приводит к гораздо лучшим результатам. Однако, как только вы начнете манипулировать чем-либо в частотной области перед инверсией, вы столкнетесь с аналогичными проблемами, но, вероятно, не такими большими, как при использовании спектрограммы Mel.

person Hendrik    schedule 24.02.2020
comment
Как я могу инвертировать обычный scipy.spectrogram? - person Shamoon; 24.02.2020
comment
Интересно - так я могу применить тот же алгоритм? Однако форма другая, не правда ли? Обычный scipy.spectogram возвращает times, freqs, spec - person Shamoon; 24.02.2020
comment
Если у вас все еще есть фазы, используйте librosa.core.istft, и он будет звучать лучше, если вы не изменили его. - person Hendrik; 24.02.2020
comment
Я делаю приложение ML, поэтому я работаю с информацией спектрограммы для своих входов (и выходов). Так что я не думаю, что у меня есть фазы, верно? - person Shamoon; 24.02.2020
comment
Ой, подожди. Я недостаточно внимательно прочитал ваши вопросы. Вы можете использовать Griffin Lim для восстановления спектрограммы амплитуды / мощности, не зная фазы. Результаты сосо. Если у вас есть фаза, то есть комплексные значения, используйте librosa.core.istft. При использовании scipy.spectrogram вы получаете тройку: f, t, Sxx. Вам понадобится только Sxx. Как восстановить что-то из Sxx, зависит от mode, который вы выбрали во время создания этой спектрограммы. - person Hendrik; 24.02.2020
comment
Обычно спектрограмма представляет собой мощность или величину, поэтому фаз нет. - person Hendrik; 24.02.2020
comment
Я использую значение по умолчанию mode, которое выглядит как psd. Итак, как мне указать это с помощью librosa.griffinlim? Я не вижу для этого параметра - person Shamoon; 24.02.2020
comment
создал еще один вопрос, чтобы лучше понять то, что я хочу: stackoverflow.com/questions/60377585/ - person Shamoon; 24.02.2020