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

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

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

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