1
$\begingroup$

Central problem (Abstract):

Using the Matlab filter-designer results in direct-form II transposed coefficients, which i need. However, generating Matlab code from the filter-designer app itself does not yield these coefficients as function-returns.

About:

  • use function to create automated filterbanks
  • Store all coefficients in C-header file
  • Use coefficients in MCUs with ARM CMSIS DSP library
  • Filter type: 3 section biquad IIR Butterworth

Filter designer:

filter

These are the coefficients i need.

Code:

Generated code:

function Hd = gen_iir_osix_bp(Fc1, Fc2, Fs)

% EDITED AUTOGEN FROM FILTER DESIGNER

%GEN_IIR_OSIX_BP Returns a discrete-time filter object.

% MATLAB Code
% Generated by MATLAB(R) 9.10 and Signal Processing Toolbox 8.6.
% Generated on: 18-Nov-2021 12:27:19

% Butterworth Bandpass filter designed using FDESIGN.BANDPASS.
N   = 6;      % Order

% Construct an FDESIGN object and call its BUTTER method.
h  = fdesign.bandpass('N,F3dB1,F3dB2', N, Fc1, Fc2, Fs);
Hd = design(h, 'butter');

% [EOF]

Own code:

fs = 48000;     % [Hz] desired sampling rate of device
fmin = 20;      % [Hz] minimal desired low-end
fmax = 20480;   % [Hz] minimal desired high-end

oct_bw_ratio = 1/3; % [1] desired octave-split

n_octs = log2(fmax/fmin);               % [1] number of octaves from fmin to fmax
n_bands = ceil(n_octs/oct_bw_ratio);    % [1] number of octave divisions from fmin to fmax

fc = fmin*2.^((0:n_bands) * oct_bw_ratio);  % [Hz] center frequencies. 
                                            % "(0:n_bands)" means to iterate from 0 to n_bands 
                                            % and store result in vector
fl = fc*2^(-oct_bw_ratio/2);                % lower cutoffs @ -3dB (required by filter-designer)
fu = fc*2^(+oct_bw_ratio/2);                % upper cutoffs @ -3dB (required by filter-designer)

% test filter with uppermost band
filter = gen_iir_osix_bp(fl(31), fu(31), fs);
display(filter.sosMatrix);

Output:

1.0000         0   -1.0000    1.0000    1.2094    0.6087
1.0000         0   -1.0000    1.0000    1.8842    0.9026
1.0000         0   -1.0000    1.0000    1.4369    0.5143

Not the same coefficients. Which ones represent what exactly?

$\endgroup$
1
  • $\begingroup$ The output of filter.sosMatrix is already a series of three biquad IIR filter and I believe it is the coefficients that you need. You said "not the same coefficients" but I don't know compared with what? If you mean CMSIS uses 5 coefficients but MATLAB gives you 6, check it out here $\endgroup$
    – ZR Han
    Nov 22 '21 at 4:08
1
$\begingroup$

I'm not quite sure what you're asking, but it looks like you have three second order sections. The

[1.0000 0 -1.0000]

are the numerators and the remaining numbers on each line are the denominators.

Does that help?


If I do

[b,a] = sos2tf(filter.sosMatrix)
freqz(b,a)

then I get this plot, which looks right to me, based on your plot above.

freqz output


I've not used the SOS much before, but if I dig into it:

display(filter)

filter =

     FilterStructure: 'Direct-Form II, Second-Order Sections'                  
          Arithmetic: 'double'                                                 
           sosMatrix: [3x6 double]                                             
         ScaleValues: [0.268829511895073;0.268829511895073;0.242859077404354;1]
 OptimizeScaleValues: true                                                     
    PersistentMemory: false                                                    

it looks like the sosMatrix component doesn't scale things properly, and the scale is captured in the ScaleValues component of the designed filter.

If I calculate the attenuation using those scale values:

20*log10(0.268829511895073*0.268829511895073*0.242859077404354)

ans =

-35.1138

then I get something close to your noted 40dB gain.

$\endgroup$
7
  • $\begingroup$ The coefficients seem so "unusual" to me: if i plug them into a visualizer tool then i don't see an expected bandpass form. I get that the coefficients represent 3 different filters of second order in series, but what is the filter designer giving me then? $\endgroup$ Nov 21 '21 at 17:04
  • $\begingroup$ @jake_asks_short_questions This seems all correct to me. What's the problem again? $\endgroup$
    – Peter K.
    Nov 22 '21 at 0:40
  • 1
    $\begingroup$ It seems i just don't know enough about math, i was missing the connection between the output of the filter-designer and the return of the discrete call of the code generated by the designer. But the function "sos2tf" establishes that connection for me $\endgroup$ Nov 22 '21 at 8:15
  • $\begingroup$ @jake_asks_short_questions ok! Great! Let me know if there’s anything I can add. $\endgroup$
    – Peter K.
    Nov 22 '21 at 11:26
  • 1
    $\begingroup$ I'll edit the main question to reference your answer and add my own answer below, as i think this post gives a good example of a filter use-case in the designer and its counterpart in code, thank you for your contribution $\endgroup$ Nov 22 '21 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.