Этот пример показывает, как эффективно преобразовать частоты дискретизации между произвольными факторами.
Необходимость преобразования частоты дискретизации произвольным фактором возникает во многих приложениях (например, синхронизация символов в цифровых приемниках, кодирование и синтез речи, компьютерная симуляция систем непрерывного времени и т.д.). В этом примере мы рассмотрим пример, где каскады полиномиальных и полифазных фильтров образуют эффективное решение, когда желательно преобразовать частоту дискретизации сигнала с 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