Этот пример показывает, как разработать КИХ-полуленточные фильтры. Полуленточные фильтры широко используются в многоскоростных приложениях обработки сигналов при интерполяции/десятикратном уменьшении фактором два. Фильтры полуполосы реализованы эффективно в многофазной форме, потому что приблизительно половина ее коэффициентов равна нулю.
Полуленточные фильтры имеют две важных характеристики, полоса пропускания и пульсации полосы задерживания должны быть тем же самым, и ребро полосы пропускания и частоты ребра полосы задерживания являются равноотстоящими с Фс/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. Различные проекты допускают компромиссы между минимальным затуханием полосы задерживания и более полным затуханием.
fvt = fvtool(equirippleHBFilter,leastSquaresHBFilter,kaiserHBFilter, ... 'Fs',2*Fs,'Color','white'); legend(fvt,'Equiripple design','Least-squares design', ... 'Kaiser-window design')
Также можно задать порядок и затухание полосы задерживания. Это допускает компромиссы между общей шириной затухания и перехода полосы задерживания.
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')
Проекты окна Kaiser могут также использоваться в дополнение к проектам equiripple при разработке фильтра минимального заказа, необходимого, чтобы соответствовать спецификациям проекта. Фактический порядок для проекта окна Kaiser больше, чем необходимый для проекта 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')
Вместо того, чтобы разработать фильтры окна Kaiser, также возможно получить увеличивающееся затухание полосы задерживания с измененными проектами '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')