exponenta event banner

Фильтры дробной задержки с использованием структур Farrow

В этом примере показано, как проектировать цифровые фильтры дробной задержки, реализованные с использованием структур Фэрроу. Цифровые фильтры дробной задержки (fracDelay) являются полезными инструментами для точной настройки моментов дискретизации сигналов. Они, например, обычно обнаруживаются в синхронизации цифровых модемов, где параметр задержки изменяется во времени. Этот пример иллюстрирует структуру Фэрроу, популярный способ реализации изменяющихся во времени фильтров FIR fracDelay.

Идеальный фильтр дробной задержки

Идеальным фильтром дробной задержки является фильтр allpass с линейной фазой. Его импульсная характеристика представляет собой сдвинутую во времени дискретную функцию sinc, которая соответствует некаузальному фильтру. Поскольку импульсная характеристика бесконечна, она не может быть причинена конечным сдвигом во времени. Поэтому она не может быть реализована и должна быть аппроксимирована.

Структура Farrow

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

Максимально-плоское приближение КИХ (интерполяция Лагранжа)

Интерполяция Лагранжа - подход во временной области, который приводит к особому случаю фильтров на основе полиномов. Выходной сигнал аппроксимируется многочленом степени М. Простейший случай (М = 1) соответствует линейной интерполяции. Разработаем и проанализируем линейный фильтр дробной задержки, который разделит единичную задержку на различные доли:

Nx = 1024;
Nf = 5;
yw = zeros(Nx,Nf);
transferFuncEstimator = dsp.TransferFunctionEstimator( ...
    'SpectralAverages',25,'FrequencyRange','onesided');
arrPlotPhaseDelay = dsp.ArrayPlot('PlotType','Line','YLimits',[0 1.5], ...
    'YLabel','Phase delay','SampleIncrement',1/512);
arrPlotMag = dsp.ArrayPlot('PlotType','Line','YLimits',[-10 1], ...
    'YLabel','Magnitude (dB)','SampleIncrement',1/512);

fracDelay = dsp.VariableFractionalDelay;

xw = randn(Nx,Nf);
transferFuncEstimator(xw,yw);
w = getFrequencyVector(transferFuncEstimator,2*pi);
w = repmat(w,1,Nf);
tic,
while toc < 2
    yw = fracDelay(xw,[0 0.2 0.4 0.6 0.8]);
    H = transferFuncEstimator(xw,yw);
    arrPlotMag(20*log10(abs(H)))
    arrPlotPhaseDelay(-angle(H)./w)
end
release(transferFuncEstimator)
release(arrPlotMag)
release(arrPlotPhaseDelay)
release(fracDelay)

Для любого значения задержки идеальный фильтр должен иметь как характеристику плоской величины, так и характеристику плоской фазовой задержки. Аппроксимация верна только для самых низких частот. Это означает, что на практике сигналы должны быть избыточно дискретизированы для правильной работы линейной дробной задержки. Здесь к синусоиде применяются две различные дробные задержки, и область времени используется для наложения исходной синусоидальной волны и двух отложенных версий. Задержка 0,2 выборки с частотой выборки 1000 Гц соответствует задержке 0,2 мс.

scope = timescope('SampleRate',1000, ...
                  'YLimits',[-1 1], ...
                  'TimeSpanSource','property',...
                  'TimeSpan',.02);
sine = dsp.SineWave('Frequency',50,'SamplesPerFrame',Nx);
tic,
while toc < 2
    x  = sine();
    y = fracDelay(x,[.2 .8]); % Delay by 0.2 ms and 0.8 ms
    scope([x,y(:,1),y(:,2)])
end
release(scope);
release(fracDelay)

Могут быть сконструированы интерполяторы Лагранжа более высокого порядка. Сравним кубический интерполятор Лагранжа с линейным:

farrowFracDelay = dsp.VariableFractionalDelay( ...
    'InterpolationMethod','Farrow','MaximumDelay',1025);
Nf = 2;
yw = zeros(Nx,Nf);
xw = randn(Nx,Nf);
H = transferFuncEstimator(xw,yw);
w = getFrequencyVector(transferFuncEstimator,2*pi);
w = repmat(w,1,Nf);
tic,
while toc < 2
    % Run for 2 seconds
    yw(:,1) = fracDelay(xw(:,1),0.4);  % Delay by 0.4 ms
    yw(:,2) = farrowFracDelay(xw(:,2),1.4); % Delay by 1.4 ms
    H = transferFuncEstimator(xw,yw);
    arrPlotMag(20*log10(abs(H)))
    arrPlotPhaseDelay(-unwrap(angle(H))./w)
end
release(transferFuncEstimator)
release(arrPlotMag)
release(arrPlotPhaseDelay)
release(fracDelay)

Увеличение порядка многочленов несколько увеличивает полезную полосу пропускания, когда используется приближение Лагранжа, длина дифференцирующих фильтров, то есть количество частей импульсной характеристики (количество строк свойства «Коэффициенты»), равно длине многочленов (количество столбцов свойства «Коэффициенты»). Для преодоления этого ограничения можно использовать другие методы проектирования. Также обратите внимание, как фазовая задержка фильтра третьего порядка сдвигается от 0,4 до 1,4 выборок при постоянном токе. Поскольку интерполятор кубического лагранжа является фильтром 3-го порядка, минимальная задержка, которую он может достичь, равна 1. По этой причине запрашиваемая задержка составляет 1,4 мс вместо 0,4 мс для данного случая.

sine = dsp.SineWave('Frequency',50,'SamplesPerFrame',Nx);
tic,
while toc < 2
       x  = sine();
       y1 = fracDelay(x,0.4);
       y2 = farrowFracDelay(x,1.4);
       scope([x,y1,y2])
end
release(scope);
release(fracDelay)

Изменяющаяся во времени дробная задержка

Преимущество структуры Фэрроу перед FIR прямой формы заключается в ее настраиваемости. Во многих практических применениях задержка изменяется во времени. Для каждой новой задержки нам потребуется новый набор коэффициентов в реализации прямой формы, но при реализации Фэрроу полиномиальные коэффициенты остаются постоянными.

tic,
while toc < 5
    x  = sine();
    if toc < 1
        delay = 1;
    elseif toc < 2
        delay = 1.2;
    elseif toc < 3
        delay = 1.4;
    elseif toc < 4
        delay = 1.6;
    else
        delay = 1.8;
    end
    y = farrowFracDelay(x,delay);
    scope([x,y])
end
release(scope);
release(fracDelay)

Связанные темы