1
$\begingroup$

I am new to DSP and filter design. I have developed a code in C++ to calculate FIR coefficients using Parks-McClellan algorithm. The inputs to calculations are:

  1. Filter type (Low-Pass, High-Pass)
  2. Passband Freq [Hz]
  3. Stopband Freq [Hz]
  4. Passband Ripple [dB]
  5. Stopband Attenuation [dB].

I got a new requirement for inputs, namely to use: 1. Cutoff freq (6dB@1.6kHz) 2. Slope [24dB/octave].

Is there a way to convert these inputs into the inputs I used in my C++ code, as listed above?

Or, more general question, how to design FIR filter with custom slope?

Thank you.

$\endgroup$
  • $\begingroup$ What is the frequency for one octave above 1.6 kHz? $\endgroup$ – jojek May 11 '15 at 15:20
  • $\begingroup$ I don't know, but should it be 3.2kHz? Is the assumption that central frequency is in the middle of transition range correct? $\endgroup$ – Nebojsa May 11 '15 at 15:23
  • $\begingroup$ It is not in the middle of transition band. $\endgroup$ – jojek May 11 '15 at 15:36
  • $\begingroup$ You are right. Is, then, passband frequency at 0.8kHz (one octave below) and stopband frequency at 3.2kHz (one octave above) if central frequency is 1.6kHz? $\endgroup$ – Nebojsa May 11 '15 at 15:42
  • 1
    $\begingroup$ Then I assume that the filter response is supposed to keep on decaying up to the Nyquist frequency. This would mean that you can't use Parks-McClellan because there the response only decays in the transition band, then its maximum error remains constant throughout the stopband ("equiripple design"). You should probably use an IIR Butterworth filter. $\endgroup$ – Matt L. May 11 '15 at 17:44
4
$\begingroup$

As I've mentioned in a comment, the Parks McClellan algorithm is usually used to design frequency selective filters with a fixed maximum stopband error, which results in an equiripple behaviour in the stopband. Note that the algorithm can in principle approximate any desired frequency response shape. However, many implementations just allow for piecewise constant desired responses (which includes all standard frequency selective filters, such as low pass, high pass, etc.).

If you want a frequency response that decays monotonically from the cut-off frequency, you probably want something like a Butterworth filter. This is an IIR filter which is usually designed via the bilinear transform from an analog prototype filter. If you want an FIR filter, then one option would be to truncate (or window) the infinite impulse response of the Butterworth filter.

In Matlab/Octave this can be easily done as follows. First design a digital Butterworth filter with the given specifications, compute its impulse response, and truncate it. Where to truncate depends on the error that you allow. For your example a third order Butterworth filter is sufficient. In the following example I assume a sampling frequency of $8\,\text{kHz}$:

[b,a] = butter(3,1.6/4);    % Butterworth IIR filter
h = impz(b,a,30);           % impulse response (30 coeffs)
f = logspace(0,3.6,400);    % log. frequency grid [1,4000]Hz
H = freqz(b,a,f*pi/4000);   % Butterworth frequency response
Hf = freqz(h,1,f*pi/4000);  % FIR frequency response
semilogx(f,20*log10(abs(H)),f,20*log10(abs(Hf)))
axis([1,4000,-80,5]), grid on

enter image description here

You see just a single curve because both filters (IIR and FIR) have virtually the same magnitude response.

$\endgroup$
  • $\begingroup$ I have typed the code in MATLAB and obtained the same curve. I do have trouble converting data to my FIR specification parameters I outlined in my question. Can you suggest how I can do that, i.e. what will be those parameters? Thank you. $\endgroup$ – Nebojsa May 12 '15 at 14:15
  • $\begingroup$ @Nebojsa: What do you mean by "converting data to my FIR specification parameters"? $\endgroup$ – Matt L. May 12 '15 at 14:31
  • $\begingroup$ My design specification was to design FIR filter with cutoff frequency 1.6kHz and the slope of 24dB/octave. I think your curve satisfies this. Please correct me if I am wrong about that. I need to specify to my C++ program as input the following parameters: Filter type (Low-Pass, High-Pass), Passband Freq [Hz], Stopband Freq [Hz], Passband Ripple [dB], Stopband Attenuation [dB]. I am not sure how I can calculate these parameters from your program and from your curve. $\endgroup$ – Nebojsa May 12 '15 at 14:38
  • $\begingroup$ @Nebojsa: That was the point of my answer: you can't use the Parks McClellan algorithm. You have to design the filter differently, as I showed you. $\endgroup$ – Matt L. May 12 '15 at 15:06
  • $\begingroup$ Matt, I have found from your curve that magnitude is 3dB for cutoff frequency of 1.6kHz. I need 6dB @1.6kHz and 24dB/octave. Does these parameters make sense for IIR filter design? Thanks. $\endgroup$ – Nebojsa May 12 '15 at 17:24
0
$\begingroup$

To do any algorithmic FIR filter design you must specify or assume (or just take some default for) a minimum stop-band attenuation. Once you provide a realistic stopband attenuation, control the transition slope from your generator algorithm by adjusting the FIR filter length and the delta between the pass band and stop band frequencies until you reach the desired result. Perhaps iteratively.

There exist some rule-of-thumb approximations for the minimum FIR filter length that will allow a given transition slope. Perhaps that's what you are looking for?

$\endgroup$
  • $\begingroup$ Thanks, hotpow2, for your answer. Is there any source code in C or C++ that implements that possible iterative procedure? I did not find the relevant code at iowahills.com. My goal is to create C++ code that will iteratively (as you suggested) obtain FIR low-pass filter coefficients from specified cut-off frequency and slope. $\endgroup$ – Nebojsa May 13 '15 at 13:57
  • $\begingroup$ Or, is there a software or code in C or C++ to obtain FIR coefficients from frequency response of the filter? $\endgroup$ – Nebojsa May 13 '15 at 14:17
  • $\begingroup$ For a simple low pass filter, a gradient descent routine from any textbook might work. Maybe even Newton's method. Might be easier to write your own C code than to find something exactly suitable. $\endgroup$ – hotpaw2 May 13 '15 at 16:19
  • $\begingroup$ Thanks, hotpow2, but I will have to ask this as a separate question. I've read on Iowa Hills web site that coefficients can be obtained by Inverse Fourier Transform from frequency response, so I will ask that question. $\endgroup$ – Nebojsa May 13 '15 at 17:28
  • $\begingroup$ Still iterative, as an IFFT derived filter still has to be windowed and retested against the specifications. $\endgroup$ – hotpaw2 May 13 '15 at 17:57

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.