Matlab: поиск доминирующих частот в кадре аудиоданных

Я новичок в Matlab и пытаюсь написать простой алгоритм обнаружения речи на основе частоты. Конечная цель состоит в том, чтобы запустить сценарий в файле wav и вывести время начала/окончания для каждого сегмента речи. Если использовать код:

fr = 128;
[ audio, fs, nbits ] = wavread(audioPath);
spectrogram(audio,fr,120,fr,fs,'yaxis')

Я получаю полезный график зависимости частоты от времени:

введите здесь описание изображения

Глядя на него, очень легко увидеть, когда происходит речь. Я мог бы написать алгоритм для автоматизации процесса обнаружения, просматривая каждый кадр по оси X, выясняя, какие частоты являются доминирующими (имеющими наибольшую интенсивность), проверяя доминирующие частоты, чтобы увидеть, достаточно ли они превышают определенный порог интенсивности ( разница между желтым и красным цветом на графике), а затем пометить этот кадр как речевой или неречевой. После того, как кадры будут помечены, будет просто получить время начала/окончания для каждого речевого сегмента.

Моя проблема в том, что я не знаю, как получить доступ к этим данным. Я могу использовать код:

[S,F,T,P] = spectrogram(audio,fr,120,fr,fs);

чтобы получить все функции спектрограммы, но результаты этого кода не имеют для меня никакого смысла. Границы массивов и матриц S, F, T, P не коррелируют ни с чем, что я вижу на графике. Я просмотрел файлы справки и API, но меня смущает, когда они начинают перебрасывать названия алгоритмов и аббревиатуры - мой опыт работы с DSP довольно ограничен.

Как мне получить массив значений частотной интенсивности для каждого кадра анализа этой спектрограммы? Я могу понять остальное оттуда, мне просто нужно знать, как получить соответствующие данные.


person Cbas    schedule 27.11.2012    source источник


Ответы (4)


То, что вы пытаетесь сделать, называется обнаружение речевой активности. Для этого есть много подходов, самым простым может быть простой полосовой фильтр, который пропускает частоты, где речь наиболее сильна, это между 1 кГц и 8 кГц. Затем вы можете сравнить общую энергию сигнала с ограниченной полосой пропускания и, если большая часть энергии находится в речевой полосе, классифицировать кадр как речь. Это один из вариантов, но есть и другие.

Чтобы получить частоты на пиках, вы можете использовать БПФ для получения спектра, а затем использовать peakdetect.m< /а>. Но это очень наивный подход, так как вы получите много пиков, принадлежащих частотам гармоник основного синуса.

Теоретически вы должны использовать своего рода кепстр (также известный как спектр спектра), который уменьшает периодичность гармоник в спектре до базовой частоты, а затем использовать его с пиковым обнаружением. Или вы можете использовать существующие инструменты, такие как praat.

Имейте в виду, что анализ речи обычно выполняется на кадрах длительностью около 30 мс с шагом 10 мс. Вы можете дополнительно отфильтровать ложное обнаружение, обеспечив обнаружение форманты в N последовательных кадрах.

person hruske    schedule 09.06.2013

Почему бы вам не использовать fft с `fftshift:

  %% Time specifications:
   Fs = 100;                      % samples per second
   dt = 1/Fs;                     % seconds per sample
   StopTime = 1;                  % seconds
   t = (0:dt:StopTime-dt)';
   N = size(t,1);
   %% Sine wave:
   Fc = 12;                       % hertz
   x = cos(2*pi*Fc*t);
   %% Fourier Transform:
   X = fftshift(fft(x));
   %% Frequency specifications:
   dF = Fs/N;                      % hertz
   f = -Fs/2:dF:Fs/2-dF;           % hertz
   %% Plot the spectrum:
   figure;
   plot(f,abs(X)/N);
   xlabel('Frequency (in hertz)');
   title('Magnitude Response');

Почему вы хотите использовать сложные вещи?

хорошее и полное решение можно найти в https://dsp.stackexchange.com/questions/1522/simplest-way-of-detecting-where-audio-envelopes-start-and-stop

person 0x90    schedule 27.11.2012
comment
Я в замешательстве - где в это уравнение входят фактические аудиоданные? - person Cbas; 28.11.2012
comment
Я имею в виду, я понимаю, что могу получить любые данные, которые дает мне это уравнение, выполнив 'q = 10*log(abs(fftshift(fft(audio))));'), но опять же, я не уверен, какие данные является. Это вектор 335570x1 с минимальным значением 0,0218 и максимальным значением 497 — что он должен представлять? - person Cbas; 28.11.2012
comment
вам следует разделить буфер на более мелкие пакеты и проанализировать каждый - person 0x90; 28.11.2012

Взгляните на STFT (кратковременное преобразование Фурье) или (еще лучше) DWT (дискретное вейвлет-преобразование), которые оба будут оценивать частотное содержимое в блоках (окнах) данных, что вам нужно, если вы хотите обнаружить внезапные изменения амплитуды определенных («речевых») частот.

Не используйте БПФ, так как он вычисляет относительную частоту по всей продолжительности сигнала, что делает невозможным определение когда в сигнале появляется определенная частота.

person Fredrik    schedule 23.04.2013

Если вы все еще используете встроенную функцию STFT, то для построения максимума вы можете использовать следующую команду

plot(T,(floor(abs(max(S,[],1)))))
person Sujeet    schedule 14.11.2014