В этом примере показано, как спроектировать КИХ-полуленточные фильтры. Полуленточные фильтры широко используются в многоскоростных приложениях обработки сигналов при интерполяции/десятикратном уменьшении на коэффициент два. Фильтры полуполосы реализуются эффективно в многофазной форме, потому что приблизительно половина ее коэффициентов равна нулю.
Полуленточные фильтры имеют две важных характеристики, полоса пропускания и пульсации полосы задерживания должны быть тем же самым, и ребро полосы пропускания и частоты ребра полосы задерживания являются равноотстоящими с Фс/4 частоты полуполосы (Или рад/выборка пи/2 в нормированной частоте).
firhalfband
функция возвращает коэффициенты полуполосы FIR equiripple фильтр. Как простой пример, рассмотрите полуленточный фильтр чей, имея дело с данными, произведенными на уровне 96 кГц и частотой полосы пропускания 22 кГц.
Fs = 96e3; Fp = 22e3; N = 100; num = firhalfband(N,Fp/(Fs/2)); fvt = fvtool(num,'Fs',Fs,'Color','white'); fvt.MagnitudeDisplay = 'Zero-phase';
Путем увеличивания масштаб к ответу можно проверить, что полоса пропускания и пульсации от пика к пику полосы задерживания являются тем же самым. Также существует симметрия о Фс/4 точка (на 24 кГц). Полоса пропускания расширяет до 22 кГц, как задано, и полоса задерживания начинается на уровне 26 кГц. Мы можем также проверить, что любой коэффициент равен нулю путем рассмотрения импульсной характеристики. Это делает фильтр очень эффективным, чтобы реализовать для интерполяции/децимации на коэффициент 2.
fvt.Analysis = 'impulse';
dsp.FIRHalfbandInterpolator
и dsp.FIRHalfbandDecimator
firhalfband
функция обеспечивает несколько других проектных решений. Однако для большинства случаев желательно работать непосредственно с dsp.FIRHalfbandInterpolator
и dsp.FIRHalfbandDecimator
. Эти два Системных объекта не только спроектируют коэффициенты, но обеспечат эффективное внедрение многофазного interpolator/decimator. Они поддерживают фильтрующую двойную / одинарную точность данные с плавающей точкой, а также данные фиксированной точки. Они также поддерживают C и генерацию HDL-кода, а также оптимизировали ARM® Cortex® M и Кору генерация кода.
halfbandInterpolator = dsp.FIRHalfbandInterpolator('SampleRate',Fs, ... 'Specification','Filter order and transition width', ... 'FilterOrder',N,'TransitionWidth',4000); fvtool(halfbandInterpolator,'Fs',2*Fs,'Color','white');
Для того, чтобы выполнить интерполяцию, dsp.FIRHalfbandInterpolator
Системный объект используется. Поскольку это - многоскоростной фильтр, важно задать то, что предназначается частотой дискретизации. Для этого и всех других Системных объектов, частота дискретизации относится к частоте дискретизации входного сигнала. Однако FVTool задает частоту дискретизации как уровень, на котором запускается фильтр. В случае интерполяции вы сверхдискретизировали и затем фильтруете (концептуально), поэтому частота дискретизации FVTool должна быть задана как 2*Fs из-за повышающей дискретизации 2.
FrameSize = 256; scope = dsp.SpectrumAnalyzer('SampleRate',2*Fs,'SpectralAverages',5); sine1 = dsp.SineWave('Frequency',10e3','SampleRate',Fs, ... 'SamplesPerFrame',FrameSize); sine2 = dsp.SineWave('Frequency',20e3','SampleRate',Fs, ... 'SamplesPerFrame',FrameSize); tic while toc < 10 x = sine1() + sine2() + 0.01.*randn(FrameSize,1); % 96 kHz y = halfbandInterpolator(x); % 192 kHz scope(y); end release(scope);
Заметьте, что спектральные копии ослабляются приблизительно на 40 дБ, который является примерно затуханием, обеспеченным полуленточным фильтром. Компенсируя групповую задержку фильтра, возможно построить вход и интерполированные наложенные выборки. Заметьте, что входные выборки сохраняются неизменные при выходе фильтра. Это вызвано тем, что одна из многофазных ветвей полуполосы является чистой ветвью задержки, которая не изменяет входные выборки.
grpDel = 50; n = 0:2:511; stem(n(1:end-grpDel/2),x(1:end-grpDel/2),'k','filled') hold on nu = 0:511; stem(nu(1:end-grpDel),y(grpDel+1:end)) legend('Input samples','Interpolated samples')
В случае децимации частота дискретизации задана в dsp.FIRHalfbandDecimator
соответствует частоте дискретизации фильтра, поскольку вы фильтруете и затем прореживаете (концептуально). Таким образом для decimators, Фс, заданная в FVTool, не должна быть умножена ни на какой фактор.
FrameSize = 256; FsIn = 2*Fs; halfbandDecimator = dsp.FIRHalfbandDecimator('SampleRate',FsIn, ... 'Specification','Filter order and transition width', ... 'FilterOrder',N,'TransitionWidth',4000); fvtool(halfbandDecimator,'Fs',FsIn,'Color','white'); scope = dsp.SpectrumAnalyzer('SampleRate',Fs,'SpectralAverages',5); sine1 = dsp.SineWave('Frequency',10e3','SampleRate',Fs, ... 'SamplesPerFrame',FrameSize); sine2 = dsp.SineWave('Frequency',20e3','SampleRate',Fs, ... 'SamplesPerFrame',FrameSize); tic while toc < 10 x = sine1() + sine2() + 0.01.*randn(FrameSize,1); % 96 kHz y = halfbandInterpolator(x); % 192 kHz xd = halfbandDecimator(y); % 96 kHz scope(xd); end release(scope);
Коэффициенты фильтра могут быть извлечены из interpolator/decimator при помощи tf
функция.
num = tf(halfbandInterpolator); % Or num = tf(halfbandDecimator);
Вместо того, чтобы задать порядка фильтра и ширину перехода, можно спроектировать фильтр минимального порядка, который обеспечивает данную ширину перехода, а также данное затухание в полосе задерживания.
Ast = 80; % 80 dB halfbandInterpolator = dsp.FIRHalfbandInterpolator('SampleRate',Fs, ... 'Specification','Transition width and stopband attenuation', ... 'StopbandAttenuation',Ast,'TransitionWidth',4000); fvtool(halfbandInterpolator,'Fs',2*Fs,'Color','white');
Заметьте, что как со всеми интерполяторами, усиление полосы пропускания в абсолютных единицах равно коэффициенту интерполяции (2 в случае полуполос). Это соответствует усилению полосы пропускания 6,02 дБ.
Также возможно задать порядка фильтра и затухание в полосе задерживания.
halfbandDecimator = dsp.FIRHalfbandDecimator('SampleRate',Fs, ... 'Specification','Filter order and stopband attenuation', ... 'StopbandAttenuation',Ast,'FilterOrder',N); fvtool(halfbandDecimator,'Fs',Fs,'Color','white');
В отличие от интерполяторов, decimators имеют усиление 1 (0 дБ) в полосе пропускания.
Интерполяторы полуполосы и decimators могут использоваться, чтобы эффективно реализовать наборы фильтров синтеза/анализа. Фильтры полуполосы, показанные до сих пор, все были фильтрами lowpass. С одним дополнительным сумматором возможно получить highpass ответ в дополнение к ответу lowpass и использовать эти два ответа для реализации набора фильтров.
Следующий код симулирует банк квадратурного фильтра зеркала (QMF). Сигнал на 8 кГц, состоящий из синусоид на 3 кГц и на 1 кГц, разделен на два сигнала на 4 кГц с помощью lowpass/highpass полуполосы decimator. Сигнал lowpass сохраняет синусоиду на 1 кГц, в то время как сигнал highpass сохраняет синусоиду на 3 кГц (который искажается к 1 кГц после субдискретизации). Сигналы затем объединены назад вместе с набором фильтров синтеза с помощью интерполятора полуполосы. highpass переходят upconverts искаженная синусоида на 1 кГц назад к 3 кГц. Интерполированный сигнал имеет частоту дискретизации на 8 кГц.
Fs1 = 8000; % Units = Hz Spec = 'Filter order and transition width'; Order = 52; TW = 4.1e2; % Units = Hz % Construct FIR Halfband Interpolator halfbandInterpolator = dsp.FIRHalfbandInterpolator( ... 'Specification',Spec, ... 'FilterOrder',Order, ... 'TransitionWidth',TW, ... 'SampleRate',Fs1/2, ... 'FilterBankInputPort',true); % Construct FIR Halfband Decimator halfbandDecimator = dsp.FIRHalfbandDecimator( ... 'Specification',Spec, ... 'FilterOrder',Order, ... 'TransitionWidth',TW, ... 'SampleRate',Fs1); % Input f1 = 1000; f2 = 3000; InputWave = dsp.SineWave('Frequency',[f1,f2],'SampleRate',Fs1, ... 'SamplesPerFrame',1024,'Amplitude',[1 0.25]); % Construct Spectrum Analyzer object to view the input and output scope = dsp.SpectrumAnalyzer('SampleRate',Fs1, ... 'PlotAsTwoSidedSpectrum',false,'ShowLegend',true,'YLimits', ... [-120 30], ... 'Title', ... 'Input Signal and Output Signal of Quadrature Mirror Filter'); scope.ChannelNames = {'Input','Output'}; tic while toc < 10 Input = sum(InputWave(),2); NoisyInput = Input+(10^-5)*randn(1024,1); [Lowpass,Highpass] = halfbandDecimator(NoisyInput); Output = halfbandInterpolator(Lowpass,Highpass); scope([NoisyInput,Output]); end release(scope);
Все проекты, представленные до сих пор, были оптимальными проектами equiripple. Используя fdesign.interpolator
и fdesign.decimator
, другие алгоритмы проекта доступны.
Fs = 44.1e3; N = 90; TW = 1000/Fs; % Transition width filtSpecs = fdesign.interpolator(2,'halfband','N,TW',N,TW); equirippleHBFilter = design(filtSpecs,'equiripple','SystemObject',true); leastSquaresHBFilter = design(filtSpecs,'firls','SystemObject',true); kaiserHBFilter = design(filtSpecs,'kaiserwin','SystemObject',true);
Можно сравнить проекты с FVTool. Различные проекты допускают торговлю offs между минимальным затуханием в полосе задерживания и более полным затуханием.
fvt = fvtool(equirippleHBFilter,leastSquaresHBFilter,kaiserHBFilter, ... 'Fs',2*Fs,'Color','white'); legend(fvt,'Equiripple design','Least-squares design', ... 'Kaiser-window design')
В качестве альтернативы можно задать порядок и затухание в полосе задерживания. Это допускает торговлю offs между полным затуханием в полосе задерживания и шириной перехода.
Ast = 60; % Minimum stopband attenuation filtSpecs = fdesign.interpolator(2,'halfband','N,Ast',N,Ast); equirippleHBFilter = design(filtSpecs,'equiripple','SystemObject',true); kaiserHBFilter = design(filtSpecs,'kaiserwin','SystemObject',true); fvt = fvtool(equirippleHBFilter,kaiserHBFilter,'Fs',2*Fs,'Color','white'); legend(fvt,'Equiripple design','Kaiser-window design')
Проекты окна Кайзера могут также использоваться в дополнение к проектам equiripple при разработке фильтра минимального порядка, необходимого, чтобы выполнить техническим требованиям проекта. Фактический порядок для проекта окна Кайзера больше, чем необходимый для проекта equiripple, но полное затухание в полосе задерживания лучше в ответ.
Fs = 44.1e3; TW = 1000/(Fs/2); % Transition width Ast = 60; % 60 dB minimum attenuation in the stopband filtSpecs = fdesign.decimator(2,'halfband','TW,Ast',TW,Ast); equirippleHBFilter = design(filtSpecs,'equiripple','SystemObject',true); kaiserHBFilter = design(filtSpecs,'kaiserwin','SystemObject',true); fvt = fvtool(equirippleHBFilter,kaiserHBFilter,'Fs',Fs,'Color','white'); legend(fvt,'Equiripple Design','Kaiser-window design')
Вместо того, чтобы проектировать фильтры окна Кайзера, также возможно получить увеличивающееся затухание в полосе задерживания с модифицированными проектами 'equiripple'.
equirippleHBFilter1 = design(filtSpecs,'equiripple', ... 'StopbandShape','1/f','StopbandDecay',4,'SystemObject',true); equirippleHBFilter2 = design(filtSpecs,'equiripple', ... 'StopbandShape','linear','StopbandDecay',53.333,'SystemObject',true); fvt = fvtool(equirippleHBFilter1,equirippleHBFilter2, ... 'Fs',Fs,'Color','white'); legend(fvt,'Stopband decaying as (1/f)^4','Stopband decaying linearly')
highpass полуленточный фильтр может быть получен из полуленточного фильтра lowpass путем изменения знака каждого второго коэффициента. В качестве альтернативы можно непосредственно спроектировать highpass полуполосу путем установки свойства 'Type' на 'Highpass'.
filtSpecs = fdesign.decimator(2,'halfband', ... 'Type','Highpass','TW,Ast',TW,Ast); halfbandHPFilter = design(filtSpecs,'equiripple', ... 'StopbandShape','linear','StopbandDecay',53.333,'SystemObject',true); fvt = fvtool(halfbandHPFilter,equirippleHBFilter2,'Fs',Fs,'Color','white'); legend(fvt,'Highpass halfband filter','Lowpass halfband filter')