#matlab #audio
#matlab #Аудио
Вопрос:
Я фильтрую аудиофайл с помощью matlab внутри функционального скрипта, в котором есть функция с именем «filtro_pf», созданная мной, которая является полосовым фильтром, а ее выходные данные представляют собой соответствующие коэффициенты IIR:
[b,a] = filtro_pf(Ap,As,fp1,fs1,fp2,fs2,1); //BAND PASS FILTER
b2 = [0.0039,0,-0.0156,0,0.0234,0,-0.0156,0,0.0039];
a2 =[1.0000,-6.2682,17.2660,-27.3421,27.2582,-17.5284,7.0998,-1.6555,0.1701];
wfpf = filter(b,a,audio_stream);
wavplay(wfpf,fs);
Обратите внимание, что вторая и третья строки (b2 и a2) — это значения, которые функция filtro_pb () выдает мне для этих входных данных. Я запустил один раз, а затем скопировал их в эти переменные. Теперь, после запуска этого скрипта, если я запрошу «a» и «a2» в консоли, у меня будет:
a =
1.0000 -6.2682 17.2660 -27.3421 27.2582 -17.5284 7.0998 -1.6555 0.1701
a2 =
1.0000 -6.2682 17.2660 -27.3421 27.2582 -17.5284 7.0998 -1.6555 0.1701
Они практически одинаковы. Но если я использую ‘a2’ вместо ‘a’ в функции filter (), это не сработает. Я слышу какой-то тикающий звук, и все. С помощью ‘a’ я слышу, как звук правильно фильтруется. Этот же код использовался ранее, и он работает:
%[b,a] = filtro_pa(Ap,As,fp,fs,1); //HIGH PASS FILTER
b = [0.5411 -1.6232 1.6232 -0.5411];
a = [1.0000 -1.8062 1.2298 -0.2925];
wfpa = filter(b2, a2, audio_stream);
wavplay(wfpa,fs);
Опять же, я использовал этот скрипт ранее и увидел, что эти значения (из a2 и b2) были выводом на эти входы. Теперь вместо повторного вызова функции (что, кстати, прокомментировано) Я использую векторы ‘a’ и ‘b’ напрямую. Он работает для фильтра нижних частот и для фильтра верхних частот.
Все это предназначено для тестирования, поэтому я не ожидаю предложений типа «зачем тогда использовать вектор вместо вызова функции?».
Я просто хочу знать, как функция может не работать со второй переменной, если они практически одинаковы?
Ответ №1:
В переменных присутствует больше точности, чем отображается, что означает, что ваши a2
b2
векторы and не совпадают с a
and b
. Может показаться удивительным, что ошибки в этом порядке сделают фильтр нестабильным, но, похоже, именно это и происходит. Вы должны быть в состоянии изучить это, посмотрев на ответ фильтра с freqz
помощью и построив результирующий звуковой вектор, а не просто прослушивая его.
Вы можете использовать format long
для печати большей точности, но у них все равно будет некоторая ошибка округления. Чтобы избежать этого, сохраните векторы в файле .mat и перезагрузите его. Файл .mat будет использовать двоичный формат и хранить полную точность ваших векторов.
Причина, по которой это работает для других фильтров, вероятно, заключается в том, что эти фильтры менее чувствительны к ошибкам округления в их коэффициентах: у них меньше коэффициентов, и эти коэффициенты менее экстремальны по значению.
Вот пример сравнения частотной характеристики:
[H W] = freqz(b2, a2); % your filter (with error)
a_error = zeros(size(a2));
a_error(9) = a_error(9) .001; % a little bit of error in a single coefficient
[HE WE] = freqz(b2, a2 a_error); % frequency response of THAT filter
plot(log10(abs([H HE])))
Как вы можете видеть, небольшое изменение имеет большое значение.
Фактический анализ нестабильности происходит при рассмотрении полюсов и нулей фильтра:
[z p k] = tf2zp(b2, a2);
abs(p)
Если какие-либо полюса имеют величину, превышающую 1 (это так), фильтр будет нестабильным. Попробуйте реальные значения, затем ваши «приблизительные» значения и посмотрите, что произойдет.
Комментарии:
1. Я только что использовал vpa (a) для отображения ‘a’ с 20 цифрами, и вот мы идем. Теперь это работает. Невероятно … однажды мне сказали, что эти фильтры могут быть нестабильными с очень небольшими различиями, но я бы никогда не подумал, что это так нестабильно! Спасибо!