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 довольно ограничен.

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

4 ответа

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

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

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

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

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

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

Почему ты не используешь 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

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

plot(T,(floor(abs(max(S,[],1)))))
Другие вопросы по тегам