Частотно-временная маскировка - это процесс применения весов к ячейкам частотно-временного представления для увеличения, уменьшения или выделения частей звука.
Целью гармонически-ударного разделения источников (HPSS) является разложение звукового сигнала на гармоническую и ударную составляющие. Применение HPSS включает в себя аудиоремикширование, повышение качества характеристик цветности, оценку темпа и изменение во времени [1]. Другое использование HPSS заключается в параллельном представлении при создании системы глубокого обучения позднего слияния. Многие из лучших систем обнаружения и классификации акустических сцен и событий (DCASE) 2017 и 2018 годов использовали 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")

ГПСС, предложенная [1], создает две усиленные спектрограммы: спектрограмму с усилением гармоник и спектрограмму с усилением ударных. Гармонически усиленная спектрограмма создается путем применения медианной фильтрации вдоль оси времени. Усиленную ударную спектрограмму создают путем применения медианной фильтрации вдоль частотной оси. Затем сравнивают усиленные спектрограммы для создания гармонических и ударных частотно-временных масок. В простейшем виде маски бинарны.
Преобразование смешанного сигнала в полустороннее кратковременное преобразование Фурье (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")

Как предполагается в [1], разложение сигнала на гармонические и ударные звуки часто невозможно. Они предлагают добавить пороговый параметр: если бункер спектрограммы не является явно гармоническим или ударным, классифицировать его как остаточный.
Выполните шаги, описанные в документе HPSS Using Binary Mask, чтобы создать спектрограммы с усилением гармоник и усилением ударных.
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 Using Binary Mask, чтобы вернуть маскированные сигналы во временную область.
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 Using Binary Mask, чтобы создать спектрограммы с усилением гармоник и усилением ударных.
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 Using Binary Mask, чтобы вернуть маскированные сигналы во временную область.
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)
[1] наблюдали, что большой размер кадра в вычислении STFT перемещает энергию к гармонической составляющей, в то время как малый размер кадра перемещает энергию к ударной составляющей. [1] предложено использовать итеративную процедуру, чтобы воспользоваться этим пониманием. В итеративной процедуре:
Выполните HPSS, используя большой размер кадра, чтобы изолировать гармоническую составляющую.
Суммировать остаточную и ударную части.
Выполните HPSS, используя небольшой размер кадра, чтобы изолировать ударный компонент.
threshold1 =0.7; N1 =
4096; [h1,p1,r1] = HelperHPSS(mix,fs,"Threshold",threshold1,"Window",sqrt(hann(N1,"periodic")),"OverlapLength",round(N1/2)); mix1 = p1 + r1; threshold2 =
0.6; N2 =
256; [h2,p2,r2] = HelperHPSS(mix1,fs,"Threshold",threshold2,"Window",sqrt(hann(N2,"periodic")),"OverlapLength",round(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")

[2] предлагает, что модификация шкалы времени (TSM) может быть улучшена путем сначала разделения сигнала на гармоническую и ударную части, а затем применения алгоритма TSM, оптимального для части. После TSM сигнал восстанавливается путем суммирования растянутого звука.
Для прослушивания растянутого звука без HPSS примените изменение масштаба времени с использованием значения по умолчанию stretchAudio функция. По умолчанию stretchAudio использует алгоритм фазового вокодера.
alpha =
1.5;
mixStretched = stretchAudio(mix,alpha);
sound(mixStretched,fs)Разделение гармонически-ударной смеси на гармоническую и ударную части с помощью 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] Дриджер, Дж., М. Мюллер и С. Диш. «Расширение гармонически-ударного разделения звуковых сигналов». Материалы Конференции Международного общества по поиску музыкальной информации. Том 15, 2014.
[2] Дриджер, Дж., М. Мюллер и С. Эверт. «Улучшение модификации музыкальных сигналов в масштабе времени с использованием гармонического-ударного разделения». Письма обработки сигналов IEEE. Том 21. Выпуск 1. стр. 105-109, 2014.