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

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

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

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

Структура Фэрроу

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

Максимально-плоская конечная импульсная характеристика Приближения (интерполяция Лагранжа)

Интерполяция Лагранжа является подходом во временной области, который приводит к частному случаю основанных на полиномах фильтров. Выходной сигнал аппроксимируется полиномом степени M. Самый простой случай (M = 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 выборок в DC. Поскольку кубический интерполятор лагранжа является фильтром 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)

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

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

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)

Похожие темы