Использование Cepstrum для КПК - PullRequest
1 голос
/ 07 мая 2010

Эй, в настоящее время я делаю разработку алгоритма для определения, озвучен ли кадр или нет.Я пытаюсь использовать Cepstrum для различения этих двух ситуаций.Я использую MATLAB для своей реализации.

У меня есть некоторые проблемы, я обычно говорю что-то о фрейме, но моя текущая реализация выглядит так (я награждаю MATLAB функцией rceps, но это не сработалодля любого из них):

ceps = abs(ifft(log10(abs(fft(frame.*window')).^2+eps)));

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

fs = 8000;
timelength = 25e-3;
freq = 500;
k = 0:1/fs:timelength-(1/fs);
s = 0.8*sin(2*pi*freq*k);

Спасибо.

1 Ответ

0 голосов
/ 08 мая 2010

Согласно Википедии , кепстр мощности - это (глубокий вдох) квадрат квадрата амплитуды преобразования Фурье логарифма квадрата амплитуды преобразования Фурье сигнала. Так что я думаю, что вы ищете

function c = ceps(frame, win)
    c = abs(fft(log10(abs(fft(frame.*win)).^2+eps))).^2;

Обратите внимание, что я изменил одно из ваших имен переменных, потому что WINDOW - это предопределенная функция в панели инструментов обработки сигналов.

Но ifft и fft отличаются только масштабным коэффициентом, а внешний abs не изменит общую форму, так где же леденец, верно? Смотрите далее на странице Википедия .

Синусоидальный ввод времени не даст вам импульса в кепстре. Синус должен дать импульс в спектре , который все равно будет импульсом после операции логмага, который преобразуется в сдвиг уровня в кепстре. Чтобы получить что-то импульсивное в кепстре, вам нужно что-то периодическое в спектре, что означает, что вам нужно что-то с несколькими гармоническими частотами во временной области. Рассмотрим, например, прямоугольную волну:

N = 1024;
h = hann(N, 'periodic');
f = 10;
x = sin(2*pi*f*((1:N)'-1)/N); %#'# to deal with SO formatting
s = 2*(x > 0) - 1; %# square wave
cx = ceps(x, h);
cs = ceps(s, h);

cs будет иметь ваш желанный леденец, а не cx.

Кажется, в 0-м кепстральном бункере всегда присутствует большой компонент. Я полагаю, это потому, что операция логарифма всегда заставляет вход второго БПФ иметь большой сдвиг уровня? Кроме того, я не понимаю идею quefrency, я бы ожидал, что леденец будет на N/f. Так что, возможно, что-то не так с этим кодом, или (что более вероятно) с моим пониманием.

...