Эффективное преобразование частоты дискретизации между произвольными факторами

Этот пример показывает, как эффективно преобразовать частоты дискретизации между произвольными факторами.

Необходимость преобразования частоты дискретизации произвольным фактором возникает во многих приложениях (например, синхронизация символов в цифровых приемниках, кодирование и синтез речи, компьютерная симуляция систем непрерывного времени и т.д.). В этом примере мы рассмотрим пример, где каскады полиномиальных и полифазных фильтров образуют эффективное решение, когда желательно преобразовать частоту дискретизации сигнала с 8 кГц до 44,1 кГц.

Одноступенчатый полифазный подход

Полифазы структуры обычно считаются эффективными реализациями многоскоростных фильтров. Однако в случае преобразования дробной частоты дискретизации количество фаз, и, следовательно, порядок фильтра, может быстро стать чрезмерно высоким. Чтобы переизбрать сигнал с 8 кГц на 44,1 кГц, интерполируем по 441 и децимируем по 80 (8 * 441/80 = 44,1).

sampRateConv = dsp.SampleRateConverter('Bandwidth',6e3, ...
    'InputSampleRate',8e3,'OutputSampleRate',44.1e3, ...
    'StopbandAttenuation',50);

Это может быть сделано относительно эффективным способом в два этапа:

info(sampRateConv)
cost(sampRateConv)
ans =

    'Overall Interpolation Factor    : 441
     Overall Decimation Factor       : 80
     Number of Filters               : 2
     Multiplications per Input Sample: 95.175000
     Number of Coefficients          : 1774
     Filters:                         
        Filter 1:
        dsp.FIRRateConverter - Interpolation Factor: 147
                             - Decimation Factor   : 80 
        Filter 2:
        dsp.FIRInterpolator  - Interpolation Factor: 3 
     '


ans = 

  struct with fields:

                  NumCoefficients: 1774
                        NumStates: 30
    MultiplicationsPerInputSample: 95.1750
          AdditionsPerInputSample: 89.6750

Хотя количество операций на входную выборку разумно (примерно 95 умножений - с учетом того, что скорость увеличивается после первого этапа до 14,7 кГц), 1774 коэффициента должны быть сохранены в памяти в этом случае.

Обеспечение допуска выходной скорости

Один из способов уменьшить большое количество коэффициентов может заключаться в допуске в выходной частоте выборки, если точная частота не является критической. Для примера установка допуска 1% результатов при частоте выходе 44 кГц, а не 44,1 кГц. Теперь это требует интерполяции на 11 и децимации на 2. Это может быть сделано эффективно с одной ступенью.

sampRateConvWithTol = dsp.SampleRateConverter('Bandwidth',6e3, ...
    'InputSampleRate',8e3,'OutputSampleRate',44.1e3, ...
    'StopbandAttenuation',50,'OutputRateTolerance',0.01);
cost(sampRateConvWithTol)
ans = 

  struct with fields:

                  NumCoefficients: 120
                        NumStates: 12
    MultiplicationsPerInputSample: 60
          AdditionsPerInputSample: 55

В этом случае необходимо 120 коэффициентов и количество умножений на входную выборку составляет 60.

Одноступенчатый подход Фэрроу

Полиномиальные фильтры являются другим способом преодоления проблемы необходимости хранения большого количества коэффициентов. Структуры Farrow являются эффективными реализациями для таких фильтров.

farrowSampRateConv_3rd = dsp.FarrowRateConverter('InputSampleRate',8e3, ...
    'OutputSampleRate',44.1e3,'PolynomialOrder',3);

farrowSampRateConv_4th = dsp.FarrowRateConverter('InputSampleRate',8e3, ...
    'OutputSampleRate',44.1e3,'PolynomialOrder',4);

cost(farrowSampRateConv_3rd)
cost(farrowSampRateConv_4th)
ans = 

  struct with fields:

                  NumCoefficients: 16
                        NumStates: 3
    MultiplicationsPerInputSample: 66.1500
          AdditionsPerInputSample: 60.6375


ans = 

  struct with fields:

                  NumCoefficients: 25
                        NumStates: 4
    MultiplicationsPerInputSample: 121.2750
          AdditionsPerInputSample: 99.2250

С полиномами 3-го порядка необходимо 16 коэффициентов и около 66 умножений на входную выборку. Полиномы четвертого порядка обеспечивают немного лучшую lowpass при более высоких затратах: 25 коэффициентов и 121 умножение на входную выборку.

filts = getFilters(sampRateConv);
W = linspace(0,44.1e3,2048);  % Define the frequency range analysis
Fs1 = 8e3*147;  % The equivalent single stage filter is clocked at 3.53 MHz
hfvt = fvtool(filts.Stage1,farrowSampRateConv_3rd, ...
    farrowSampRateConv_4th,'FrequencyRange','Specify freq. vector', ...
    'FrequencyVector',W,'Fs',[Fs1 3*Fs1 3*Fs1], ...
    'NormalizeMagnitudeto1','on','Color','white');
legend(hfvt,'Polyphase Sample-Rate Converter', ...
    '3rd-Order Farrow Interpolator','4th-Order Farrow Interpolator', ...
    'Location','NorthEast')

Обеспечение допуска скорости выхода не оказывает существенного влияния на стоимость реализации фильтра Фэрроу. Однако он изменяет коэффициенты интерполяции и десятикратного уменьшения так же, как для dsp. SampleRateConverter.

farrowSampRateConv_4th = dsp.FarrowRateConverter('InputSampleRate',8e3, ...
    'OutputSampleRate',44.1e3,'PolynomialOrder',4, ...
    'OutputRateTolerance',0.01);
info(farrowSampRateConv_4th)
cost(farrowSampRateConv_4th)
ans =

  12x52 char array

    'Discrete-Time FIR Multirate Filter (real)           '
    '-----------------------------------------           '
    'Filter Structure      : Farrow Sample-Rate Converter'
    'Interpolation Factor  : 11                          '
    'Decimation Factor     : 2                           '
    'Filter Length         : 5                           '
    'Stable                : Yes                         '
    'Linear Phase          : No                          '
    '                                                    '
    'Arithmetic            : double                      '
    'Output Rate Tolerance : 1.000000 %                  '
    'Adjusted Output Rate  : 44000.000000                '


ans = 

  struct with fields:

                  NumCoefficients: 25
                        NumStates: 4
    MultiplicationsPerInputSample: 121
          AdditionsPerInputSample: 99

Каскад Фэрроу и конечная импульсная характеристика Полифазы структур

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

intSampRateConv = dsp.SampleRateConverter('Bandwidth',6e3, ...
    'InputSampleRate',8e3,'OutputSampleRate',32e3, ...
    'StopbandAttenuation',50);
info(intSampRateConv)
ans =

    'Overall Interpolation Factor    : 4
     Overall Decimation Factor       : 1
     Number of Filters               : 1
     Multiplications per Input Sample: 34.000000
     Number of Coefficients          : 34
     Filters:                         
        Filter 1:
        dsp.FIRInterpolator  - Interpolation Factor: 4 
     '

Затем интерполируем промежуточный сигнал 32 кГц на 44,1/32 = 1.378125, чтобы получить желаемую частоту конечной дискретизации 44,1 кГц. Мы используем кубический фильтр на основе полинома Лагранжа для этой цели.

farrowSampRateConv = dsp.FarrowRateConverter('InputSampleRate',32e3, ...
    'OutputSampleRate',44.1e3,'PolynomialOrder',3);

Полный фильтр просто получается путем расположения каскадом двух фильтров.

cost(intSampRateConv)
cost(farrowSampRateConv)
ans = 

  struct with fields:

                  NumCoefficients: 34
                        NumStates: 11
    MultiplicationsPerInputSample: 34
          AdditionsPerInputSample: 31


ans = 

  struct with fields:

                  NumCoefficients: 16
                        NumStates: 3
    MultiplicationsPerInputSample: 16.5375
          AdditionsPerInputSample: 15.1594

Количество коэффициентов этого гибридного проекта относительно мало (36), и количество умножений на вход выборку также относительно мало: 28 + 16 * 4 = 92. Комбинированная частотная характеристика этих двух проектов выше, чем у farrowSampRateConv_3rd или farrowSampRateConv_4th.

[Hsrc,f]     = freqz(intSampRateConv);
Fsfar        = 32e3*441;
Hfsrc        = freqz(farrowSampRateConv,f,Fsfar);
Hhybrid      = Hsrc.*Hfsrc;
Hhybrid_norm = Hhybrid/norm(Hhybrid,inf); % Normalize magnitude to 0 dB
plot(f,20*log10(abs(Hhybrid_norm)));
xlabel('Frequency (Hz)')
ylabel('Magnitude (dB)')
legend('Combined polyphase and Farrow sample rate converters', ...
       'Location','NorthEast')

Теперь мы перекрываем частотные характеристики одноступенчатых и многоступенчатых проектов. Очевидно, что ответы очень сопоставимы.

scope = dsp.SpectrumAnalyzer('SpectralAverages',50, ...
    'SampleRate',44.1e3,'PlotAsTwoSidedSpectrum',false, ...
    'YLimits',[-80 20],'ShowLegend',true, ...
    'ChannelNames',{'Single-stage design','Multi-stage design'});
tic,
while toc < 20
    % Run for 20 seconds
    x = randn(8000,1);

    % Convert rate using multistage FIR filters
    y1 = sampRateConv(x);

    % Convert rate using cascade of multistage FIR and Farrow filter
    ytemp  = intSampRateConv(x);
    y2     = farrowSampRateConv(ytemp);

    % Compare the output from both approaches
    scope([y1,y2])
end