КИХ-проект полуленточного фильтра

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

Полуленточные фильтры имеют две важных характеристики, полоса пропускания и пульсации полосы задерживания должны быть тем же самым, и ребро полосы пропускания и частоты ребра полосы задерживания являются равноотстоящими с Фс/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

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')