Дробные фильтры задержки Используя неоплодотворенные структуры

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

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

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

Неоплодотворенная структура

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

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

Лагранжева интерполяция является подходом временного интервала, который приводит к особому случаю основанных на полиноме фильтров. Выходной сигнал аппроксимирован полиномом степени 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 выборок с частотой дискретизации 1 000 Гц, соответствует задержке 0,2 мс.

scope = dsp.TimeScope('SampleRate',1000, ...
                      'YLimits',[-1 1], ...
                      'TimeSpan',.02, ...
                      'TimeSpanOverrunAction','Scroll');
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)

Увеличение порядка полиномов немного увеличивает полезную пропускную способность, когда Лагранжево приближение используется, длина дифференцирующихся фильтров т.е. количество частей импульсной характеристики (количество строк свойства 'Coefficients') равны длине полиномов (количество столбцов свойства 'Coefficients'). Другие методы разработки могут использоваться, чтобы преодолеть это ограничение. Также заметьте, как задержка фазы третьего фильтра порядка смещена от 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)

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

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

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)