Маскирование частоты времени для гармонически-ударного исходного разделения

Маскирование частоты времени является процессом применения весов к интервалам представления частоты времени, чтобы улучшить, уменьшить, или изолировать фрагменты аудио.

Цель гармонически-ударного исходного разделения (HPSS) состоит в том, чтобы разложить звуковой сигнал на гармонические и ударные компоненты. Приложения HPSS включают аудио делание ремикс, улучшая качество функций цветности, оценки темпа и модификации масштаба времени [1]. Другое использование HPSS как параллельное представление при создании последней системы глубокого обучения сплава. Многие наиболее эффективные системы Обнаружения и Классификация Акустических Сцен и Событий (DCASE) 2 017 и 2 018 проблем использовали HPSS поэтому.

Этот пример идет через алгоритм, описанный в [1], чтобы применить маскирование частоты времени к задаче гармонически-ударного исходного разделения.

Для примера получения масок частоты времени с помощью глубокого обучения смотрите, что Исходное Разделение Приема Использует Нейронные сети для глубокого обучения.

Создайте гармонически-ударную смесь

Читайте в гармонических и ударных звуковых файлах. У обоих есть частота дискретизации 16 кГц.

[harmonicAudio,fs] = audioread("violin.wav");
percussiveAudio = audioread("drums.wav");

Слушайте гармонический сигнал и постройте спектрограмму. Обратите внимание на то, что существует непрерывность вдоль горизонтали (время) ось.

sound(harmonicAudio,fs)

spectrogram(harmonicAudio,1024,512,1024,fs,"yaxis")
title("Harmonic Audio")

Слушайте ударный сигнал и постройте спектрограмму. Обратите внимание на то, что существует непрерывность вдоль вертикали (частота) ось.

sound(percussiveAudio,fs)

spectrogram(percussiveAudio,1024,512,1024,fs,"yaxis")
title("Percussive Audio")

Смешайте гармонические и ударные сигналы. Слушайте гармонически-ударное аудио и постройте спектрограмму.

mix = harmonicAudio + percussiveAudio;

sound(mix,fs)

spectrogram(mix,1024,512,1024,fs,"yaxis")
title("Harmonic-Percussive Audio")

HPSS, предложенный [1], создает две расширенных спектрограммы: улучшенная гармоникой спектрограмма и ударно улучшенная спектрограмма. Улучшенная гармоникой спектрограмма создается путем применения медианной фильтрации вдоль оси времени. Ударно улучшенная спектрограмма создается путем применения медианной фильтрации вдоль оси частоты. Расширенные спектрограммы затем сравнены, чтобы создать гармонические и ударные маски частоты времени. В самой простой форме маски являются двоичным файлом.

HPSS Используя бинарную маску

Преобразуйте смешанный сигнал в полупримкнутое кратковременное преобразование Фурье (STFT) величины.

win = sqrt(hann(1024,"periodic"));
overlapLength = floor(numel(win)/2);
fftLength = 2^nextpow2(numel(win) + 1);
y = stft(mix, ...
        "Window",win, ...
        "OverlapLength",overlapLength, ...
        "FFTLength",fftLength, ...
        "Centered",true);
halfIdx = 1:ceil(size(y,1)/2);
yhalf = y(halfIdx,:);
ymag = abs(yhalf);

Примените среднее сглаживание вдоль оси времени, чтобы улучшить гармоническое аудио и уменьшить ударное аудио. Используйте длину фильтра 200 мс, как предложено [1]. Постройте спектр мощности улучшенного гармоникой аудио.

timeFilterLength = 0.2;
timeFilterLengthInSamples = timeFilterLength/((numel(win) - overlapLength)/fs);
ymagharm = movmedian(ymag,timeFilterLengthInSamples,2);

surf(flipud(log10(ymagharm.^2)),"EdgeColor","none")
title("Harmonic Enhanced Audio")
view([0,90])
axis tight

Примените среднее сглаживание вдоль оси частоты, чтобы улучшить ударное аудио и уменьшить гармоническое аудио. Используйте длину фильтра 500 Гц, как предложено [1]. Постройте спектр мощности ударно улучшенного аудио.

frequencyFilterLength = 500;
frequencyFilterLengthInSamples = frequencyFilterLength/(fs/fftLength);
ymagperc = movmedian(ymag,frequencyFilterLengthInSamples,1);

surf(flipud(log10(ymagperc.^2)),"EdgeColor","none")
title("Percussive Enhanced Audio")
view([0,90])
axis tight

Чтобы создать бинарную маску, сначала суммируйте ударное - и улучшенные гармоникой спектры, чтобы определить общую величину на интервал.

totalMagnitudePerBin = ymagharm + ymagperc;

Если величина в данном улучшенном гармоникой или ударно улучшенном интервале составляет больше чем половину общей величины того интервала, то присвойте тот интервал соответствующей маске.

harmonicMask = ymagharm > (totalMagnitudePerBin*0.5);
percussiveMask = ymagperc > (totalMagnitudePerBin*0.5);

Примените гармонические и ударные маски и затем возвратите аудио маскированное во временной интервал.

yharm = harmonicMask.*yhalf;
yperc = percussiveMask.*yhalf;

Зеркально отразите полупримкнутый спектр, чтобы создать двухсторонний сопряженный симметричный спектр.

yharm = cat(1,yharm,flipud(conj(yharm)));
yperc = cat(1,yperc,flipud(conj(yperc)));

Выполните обратное кратковременное преобразование Фурье, чтобы возвратить сигналы во временной интервал.

h = istft(yharm, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);
p = istft(yperc, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);

Слушайте восстановленное гармоническое аудио и постройте спектрограмму.

sound(h,fs)

spectrogram(h,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic Audio")

Слушайте восстановленное ударное аудио и постройте спектрограмму.

sound(p,fs)

spectrogram(p,1024,512,1024,fs,"yaxis")
title("Recovered Percussive Audio")

Постройте комбинацию восстановленных гармонических и ударных спектрограмм.

sound(h + p,fs)

spectrogram(h + p,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic + Percussive Audio")

HPSS Используя бинарную маску и невязку

Как предложено в [1], разлагая сигнал на гармонические и ударные звуки часто невозможно. Они предлагают добавить параметр пороговой обработки: если интервал спектрограммы не является явно гармоническим или ударным, категоризируйте его как невязку.

Выполните те же шаги, описанные в HPSS Используя Бинарную Маску, чтобы создать улучшенные гармоникой и ударно улучшенные спектрограммы.

win = sqrt(hann(1024,"periodic"));
overlapLength = floor(numel(win)/2);
fftLength = 2^nextpow2(numel(win) + 1);
y = stft(mix, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "Centered",true);
halfIdx = 1:ceil(size(y,1)/2);
yhalf = y(halfIdx,:);
ymag = abs(yhalf);

timeFilterLength = 0.2;
timeFilterLengthInSamples = timeFilterLength/((numel(win) - overlapLength)/fs);
ymagharm = movmedian(ymag,timeFilterLengthInSamples,2);

frequencyFilterLength = 500;
frequencyFilterLengthInSamples = frequencyFilterLength/(fs/fftLength);
ymagperc = movmedian(ymag,frequencyFilterLengthInSamples,1);

totalMagnitudePerBin = ymagharm + ymagperc;

Используя порог, создайте три бинарных маски: гармонический, ударный, и остаточный. Установите порог к 0.65. Это означает, что, если величина интервала улучшенной гармоникой спектрограммы составляет 65% общей величины для того интервала, вы присваиваете тот интервал гармоническому фрагменту. Если величина интервала ударно улучшенной спектрограммы составляет 65% общей величины для того интервала, вы присваиваете тот интервал ударному фрагменту. В противном случае интервал присвоен остаточному фрагменту. Оптимальный параметр пороговой обработки зависит от гармонически-ударного соединения и вашего приложения.

threshold = 0.65;
harmonicMask = ymagharm> (totalMagnitudePerBin*threshold);
percussiveMask = ymagperc> (totalMagnitudePerBin*threshold);
residualMask = ~ (harmonicMask+percussiveMask);

Выполните те же шаги, описанные в HPSS Используя Бинарную Маску, чтобы возвратить сигналы маскированные во временной интервал.

yharm = harmonicMask.*yhalf;
yperc = percussiveMask.*yhalf;
yresi = residualMask.*yhalf;

yharm = cat(1,yharm,flipud(conj(yharm)));
yperc = cat(1,yperc,flipud(conj(yperc)));
yresi = cat(1,yresi,flipud(conj(yresi)));

h = istft(yharm, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);
p = istft(yperc, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);
r = istft(yresi, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);

Слушайте восстановленное гармоническое аудио и постройте спектрограмму.

sound(h,fs)

spectrogram(h,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic Audio")

Слушайте восстановленное ударное аудио и постройте спектрограмму.

sound(p,fs)

spectrogram(p,1024,512,1024,fs,"yaxis")
title("Recovered Percussive Audio")

Слушайте восстановленное остаточное аудио и постройте спектрограмму.

sound(r,fs)

spectrogram(r,1024,512,1024,fs,"yaxis")
title("Recovered Residual Audio")

Слушайте комбинацию гармонических, ударных, и остаточных сигналов и постройте спектрограмму.

sound(h + p + r,fs)

spectrogram(h + p + r,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic + Percussive + Residual Audio")

HPSS Используя мягкую маску

Для маскирования частоты времени маски обычно являются или двоичным файлом или мягкий. Мягкое маскирование разделяет энергию смешанных интервалов в гармонические и ударные фрагменты в зависимости от относительных весов их расширенных спектрограмм.

Выполните те же шаги, описанные в HPSS Используя Бинарную Маску, чтобы создать улучшенные гармоникой и ударно улучшенные спектрограммы.

win = sqrt(hann(1024,"periodic"));
overlapLength = floor(numel(win)/2);
fftLength = 2^nextpow2(numel(win) + 1);
y = stft(mix, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "Centered",true);
halfIdx = 1:ceil(size(y,1)/2);
yhalf = y(halfIdx,:);
ymag = abs(yhalf);

timeFilterLength = 0.2;
timeFilterLengthInSamples = timeFilterLength/((numel(win)-overlapLength)/fs);
ymagharm = movmedian(ymag,timeFilterLengthInSamples,2);

frequencyFilterLength = 500;
frequencyFilterLengthInSamples = frequencyFilterLength/(fs/fftLength);
ymagperc = movmedian(ymag,frequencyFilterLengthInSamples,1);

totalMagnitudePerBin = ymagharm + ymagperc;

Создайте мягкие маски, которые разделяют энергию интервала к гармоническим и ударным фрагментам относительно весов их расширенных спектрограмм.

harmonicMask = ymagharm ./ totalMagnitudePerBin;
percussiveMask = ymagperc ./ totalMagnitudePerBin;

Выполните те же шаги, описанные в HPSS Используя Бинарную Маску, чтобы возвратить сигналы маскированные во временной интервал.

yharm = harmonicMask.*yhalf;
yperc = percussiveMask.*yhalf;

yharm = cat(1,yharm,flipud(conj(yharm)));
yperc = cat(1,yperc,flipud(conj(yperc)));

h = istft(yharm, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);
p = istft(yperc, ...
    "Window",win, ...
    "OverlapLength",overlapLength, ...
    "FFTLength",fftLength, ...
    "ConjugateSymmetric",true);

Слушайте восстановленное гармоническое аудио и постройте спектрограмму.

sound(h,fs)

spectrogram(h,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic Audio")

Слушайте восстановленное ударное аудио и постройте спектрограмму.

sound(p,fs)

spectrogram(p,1024,512,1024,fs,"yaxis")
title("Recovered Percussive Audio")

Функция, взятая в качестве примера,

Функция, взятая в качестве примера, HelperHPSS, предусматривает гармонически-ударные исходные разделительные возможности, описанные в этом примере. Можно использовать его, чтобы быстро исследовать, как параметры производят производительность алгоритма.

help HelperHPSS
  [h,p] = HelperHPSS(x,fs) separates the input signal, x, into harmonic (h)
  and percussive (p) portions. If x is input as a multichannel signal, it
  is converted to mono before processing.
 
  [h,p] = HelperHPSS(...,'TimeFilterLength',TIMEFILTERLENGTH) specifies the
  median filter length along the time dimension of a spectrogram, in
  seconds. If unspecified, TIMEFILTERLENGTH defaults to 0.2 seconds.
 
  [h,p] = HelperHPSS(...,'FrequencyFilterLength',FREQUENCYFILTERLENGTH)
  specifies the median filter length along the frequency dimension of a
  spectrogram, in Hz. If unspecified, FREQUENCYFILTERLENGTH defaults to 500
  Hz.
 
  [h,p] = HelperHPSS(...,'MaskType',MASKTYPE) specifies the mask type as
  'binary' or 'soft'. If unspecified, MASKTYPE defaults to 'binary'.
  
  [h,p] = HelperHPSS(...,'Threshold',THRESHOLD) specifies the threshold of
  the total energy for declaring an element as harmonic, percussive, or
  residual. Specify THRESHOLD as a scalar in the range [0 1]. This
  parameter is only valid if MaskType is set to 'binary'. If unspecified,
  THRESHOLD defaults to 0.5.
 
  [h,p] = HelperHPSS(...,'Window',WINDOW) specifies the analysis window
  used in the STFT. If unspecified, WINDOW defaults to
  sqrt(hann(1024,'periodic')).
 
  [h,p] = HelperHPSS(...,'FFTLength',FFTLENGTH) specifies the number of
  points in the DFT for each analysis window. If unspecified, FFTLENGTH
  defaults to the number of elements in the WINDOW.
 
  [h,p] = HelperHPSS(...,'OverlapLength',OVERLAPLENGTH) specifies the
  overlap length of the analysis windows. If unspecified, OVERLAPLENGTH
  defaults to 512.
 
  [h,p,r] = HelperHPSS(...) returns the residual signal not classified as
  harmonic or percussive.
 
  Example:
    % Load a sound file and listen to it.
      [audio,fs] = audioread('Laughter-16-8-mono-4secs.wav');
      sound(audio,fs)
 
    % Call HelperHPSS to separate the audio into harmonic and percussive
    % portions. Listen to the portions separately.
      [h,p] = HelperHPSS(audio,fs);
      sound(h,fs)
      sound(p,fs)

HPSS Используя итеративное маскирование

[1] наблюдаемый, что большой формат кадра в вычислении STFT перемещает энергию к гармоническому компоненту, в то время как маленький формат кадра перемещает энергию к ударному компоненту. [1] предложенное использование итеративной процедуры, чтобы использовать в своих интересах это понимание. В итеративной процедуре:

  1. Выполните HPSS с помощью большого формата кадра, чтобы изолировать гармонический компонент.

  2. Суммируйте невязку и ударные фрагменты.

  3. Выполните HPSS с помощью маленького формата кадра, чтобы изолировать ударный компонент.

threshold1 = 0.7;
N1 = 4096;
[h1, p1, r1] = HelperHPSS (соединение, фс,"Threshold", threshold1,"Window", sqrt (hann (N1,"periodic")),"OverlapLength", раунд (N1/2));

mix1 = p1 + r1;

threshold2 = 0.6;
N2 = 256;
[h2, p2, r2] = HelperHPSS (mix1, фс,"Threshold", threshold2,"Window", sqrt (hann (N2,"periodic")),"OverlapLength", раунд (N2/2));

h = h1;
p = p2;
r = h2 + r2;

Слушайте восстановленное ударное аудио и постройте спектрограмму.

sound(h,fs)

spectrogram(h,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic Audio")

Слушайте восстановленное ударное аудио и постройте спектрограмму.

sound(p,fs)

spectrogram(p,1024,512,1024,fs,"yaxis")
title("Recovered Percussive Audio")

Слушайте восстановленное остаточное аудио и постройте спектрограмму.

sound(r,fs)

spectrogram(r,1024,512,1024,fs,"yaxis")
title("Recovered Residual Audio")

Слушайте комбинацию гармонических, ударных, и остаточных сигналов и постройте спектрограмму.

sound(h + p + r,fs)

spectrogram(h+p+r,1024,512,1024,fs,"yaxis")
title("Recovered Harmonic + Percussive + Residual Audio")

Расширенная модификация масштаба времени Используя HPSS

[2] предлагает, чтобы модификация масштаба времени (TSM) могла быть улучшена путем первого разделения сигнала в гармонические и ударные фрагменты и затем применения алгоритма TSM, оптимального для фрагмента. После TSM сигнал воссоздается путем подведения итогов расширенного аудио.

Чтобы слушать расширенное аудио без HPSS, примените модификацию масштаба времени с помощью stretchAudio по умолчанию функция. По умолчанию, stretchAudio использует алгоритм вокодера фазы.

alpha = 1.5;
mixStretched = stretchAudio (соединение, альфа);

звук (mixStretched, фс)

Разделите гармонически-ударное соединение на гармонические и ударные фрагменты с помощью HelperHPSS. Как предложено в [2], используйте алгоритм вокодера по умолчанию, чтобы расширить гармонический фрагмент и алгоритм WSOLA, чтобы расширить ударный фрагмент. Суммируйте расширенные фрагменты и слушайте результаты.

[h,p] = HelperHPSS(mix,fs);
hStretched = stretchAudio(h,alpha);
pStretched = stretchAudio(p,alpha,"Method","wsola");

mixStretched = hStretched + pStretched;
sound(mixStretched,fs);

Ссылки

[1] Driedger, J., М. Мюллер и С. Диш. "Расширяя гармонически-ударное разделение звуковых сигналов". Продолжения международного общества Музыкальной Конференции по Информационному поиску. Издание 15, 2014.

[2] Driedger, J., М. Мюллер и С. Юерт. "Улучшая Модификацию Масштаба времени Музыкальных Сигналов Используя Гармонически-ударное Разделение". Буквы Обработки сигналов IEEE. Издание 21. Выпуск 1. стр 105-109, 2014.