kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

biquads.cpp (11242B)


      1 /**
      2  * KFR (https://www.kfrlib.com)
      3  * Copyright (C) 2016-2023 Dan Cazarin
      4  * See LICENSE.txt for details
      5  */
      6 
      7 #include <kfr/base.hpp>
      8 #include <kfr/dsp/biquad.hpp>
      9 #include <kfr/dsp/biquad_design.hpp>
     10 #include <kfr/dsp/special.hpp>
     11 #include <kfr/io.hpp>
     12 
     13 using namespace kfr;
     14 
     15 int main()
     16 {
     17     // Print the version of the KFR library being used
     18     println(library_version());
     19 
     20     // Define options for plotting DSP data
     21     const std::string options = "phaseresp=True";
     22 
     23     // Define a buffer for storing the filter output
     24     univector<fbase, 128> output;
     25 
     26     // --------------------------------------------------------------------------------------
     27     // ------------------------- Biquad Notch Filters Example -------------------------------
     28     // --------------------------------------------------------------------------------------
     29     {
     30         // Initialize an array of biquad notch filters with different center frequencies
     31         // biquad_notch(frequency, Q) where the frequency is relative to the sample rate
     32         biquad_section<fbase> bq[] = {
     33             biquad_notch(0.1, 0.5),
     34             biquad_notch(0.2, 0.5),
     35             biquad_notch(0.3, 0.5),
     36             biquad_notch(0.4, 0.5),
     37         };
     38         // Apply the biquad filters to a unit impulse signal and store the result in 'output'
     39         output = iir(unitimpulse(), iir_params{ bq });
     40     }
     41     // Save the plot of the filter responses
     42     plot_save("biquad_notch", output, options + ", title='Four Biquad Notch filters'");
     43 
     44     // --------------------------------------------------------------------------------------
     45     // ------------------------- Biquad Lowpass Filter Example ------------------------------
     46     // --------------------------------------------------------------------------------------
     47     {
     48         // Initialize a biquad lowpass filter with specific parameters
     49         // biquad_lowpass(frequency, Q) where the frequency is relative to the sample rate
     50         biquad_section<fbase> bq[] = { biquad_lowpass(0.2, 0.9) };
     51         // Apply the biquad lowpass filter to a unit impulse signal and store the result in 'output'
     52         output = iir(unitimpulse(), iir_params{ bq });
     53     }
     54     // Save the plot of the filter response
     55     plot_save("biquad_lowpass", output, options + ", title='Biquad Low pass filter (0.2, 0.9)'");
     56 
     57     // --------------------------------------------------------------------------------------
     58     // ------------------------- Biquad Highpass Filter Example -----------------------------
     59     // --------------------------------------------------------------------------------------
     60     {
     61         // Initialize a biquad highpass filter with specific parameters
     62         // biquad_highpass(frequency, Q) where the frequency is relative to the sample rate
     63         biquad_section<fbase> bq[] = { biquad_highpass(0.3, 0.1) };
     64         // Apply the biquad highpass filter to a unit impulse signal and store the result in 'output'
     65         output = iir(unitimpulse(), iir_params{ bq });
     66     }
     67     // Save the plot of the filter response
     68     plot_save("biquad_highpass", output, options + ", title='Biquad High pass filter (0.3, 0.1)'");
     69 
     70     // --------------------------------------------------------------------------------------
     71     // -------------------------- Biquad Peak Filter Example --------------------------------
     72     // --------------------------------------------------------------------------------------
     73     {
     74         // Initialize a biquad peak filter with specific parameters
     75         // biquad_peak(frequency, Q, gain) where the frequency is relative to the sample rate and the gain is
     76         // in decibels
     77         biquad_section<fbase> bq[] = { biquad_peak(0.3, 0.5, +9.0) };
     78         // Apply the biquad peak filter to a unit impulse signal and store the result in 'output'
     79         output = iir(unitimpulse(), iir_params{ bq });
     80     }
     81     // Save the plot of the filter response
     82     plot_save("biquad_peak", output, options + ", title='Biquad Peak filter (0.2, 0.5, +9)'");
     83 
     84     // --------------------------------------------------------------------------------------
     85     // -------------------------- Biquad Peak Filter Example (2) ----------------------------
     86     // --------------------------------------------------------------------------------------
     87     {
     88         // Initialize another biquad peak filter with different parameters
     89         // biquad_peak(frequency, Q, gain) where the frequency is relative to the sample rate and the gain is
     90         // in decibels
     91         biquad_section<fbase> bq[] = { biquad_peak(0.3, 3.0, -2.0) };
     92         // Apply the biquad peak filter to a unit impulse signal and store the result in 'output'
     93         output = iir(unitimpulse(), iir_params{ bq });
     94     }
     95     // Save the plot of the filter response
     96     plot_save("biquad_peak2", output, options + ", title='Biquad Peak filter (0.3, 3, -2)'");
     97 
     98     // --------------------------------------------------------------------------------------
     99     // -------------------------- Biquad Low Shelf Filter Example ---------------------------
    100     // --------------------------------------------------------------------------------------
    101     {
    102         // Initialize a biquad low shelf filter with specific parameters
    103         // biquad_lowshelf(frequency, gain) where the frequency is relative to the sample rate and the gain is
    104         // in decibels
    105         biquad_section<fbase> bq[] = { biquad_lowshelf(0.3, -1.0) };
    106         // Apply the biquad low shelf filter to a unit impulse signal and store the result in 'output'
    107         output = iir(unitimpulse(), iir_params{ bq });
    108     }
    109     // Save the plot of the filter response
    110     plot_save("biquad_lowshelf", output, options + ", title='Biquad low shelf filter (0.3, -1)'");
    111 
    112     // --------------------------------------------------------------------------------------
    113     // -------------------------- Biquad High Shelf Filter Example --------------------------
    114     // --------------------------------------------------------------------------------------
    115     {
    116         // Initialize a biquad high shelf filter with specific parameters
    117         // biquad_highshelf(frequency, gain) where the frequency is relative to the sample rate and the gain
    118         // is in decibels
    119         biquad_section<fbase> bq[] = { biquad_highshelf(0.3, +9.0) };
    120         // Apply the biquad high shelf filter to a unit impulse signal and store the result in 'output'
    121         output = iir(unitimpulse(), iir_params{ bq });
    122     }
    123     // Save the plot of the filter response
    124     plot_save("biquad_highshelf", output, options + ", title='Biquad high shelf filter (0.3, +9)'");
    125 
    126     // --------------------------------------------------------------------------------------
    127     // ------------------------- Biquad Bandpass Filter Example -----------------------------
    128     // --------------------------------------------------------------------------------------
    129     {
    130         // Initialize a biquad bandpass filter with specific parameters
    131         // biquad_bandpass(frequency, Q) where the frequency is relative to the sample rate
    132         biquad_section<fbase> bq[] = { biquad_bandpass(0.25, 0.2) };
    133         // Apply the biquad bandpass filter to a unit impulse signal and store the result in 'output'
    134         output = iir(unitimpulse(), iir_params{ bq });
    135     }
    136     // Save the plot of the filter response
    137     plot_save("biquad_bandpass", output, options + ", title='Biquad band pass (0.25, 0.2)'");
    138 
    139     // --------------------------------------------------------------------------------------
    140     // ----------------- Biquad Bandpass Filter Example with std::vector --------------------
    141     // --------------------------------------------------------------------------------------
    142     {
    143         // Initialize a biquad bandpass filter with specific parameters
    144         biquad_section<fbase> bq[] = { biquad_bandpass(0.25, 0.2) };
    145         // Create a std::vector for the input data and set the first element to 1 (unit impulse)
    146         std::vector<fbase> data(output.size(), 0.f);
    147         data[0] = 1.f;
    148         // Apply the biquad bandpass filter to the input data and store the result in 'output'
    149         output = iir(make_univector(data), iir_params{ bq });
    150     }
    151     // Save the plot of the filter response
    152     plot_save("biquad_bandpass_stdvector", output, options + ", title='Biquad band pass (0.25, 0.2)'");
    153 
    154     // --------------------------------------------------------------------------------------
    155     // ------------------- Biquad Bandpass Filter Example with C array ----------------------
    156     // --------------------------------------------------------------------------------------
    157     {
    158         // Initialize a biquad bandpass filter with specific parameters
    159         biquad_section<fbase> bq[] = { biquad_bandpass(0.25, 0.2) };
    160         // Create a C array for the input data and set the first element to 1 (unit impulse)
    161         fbase data[output.size()] = { 0 }; // .size() is constexpr
    162         data[0]                   = 1.f;
    163         // Apply the biquad bandpass filter to the input data and store the result in 'output'
    164         output = iir(make_univector(data), iir_params{ bq });
    165     }
    166     // Save the plot of the filter response
    167     plot_save("biquad_bandpass_carray", output, options + ", title='Biquad band pass (0.25, 0.2)'");
    168 
    169     // --------------------------------------------------------------------------------------
    170     // ----------------- Custom Biquad Lowpass Filter using expression_filter ---------------
    171     // --------------------------------------------------------------------------------------
    172     {
    173         // Initialize a biquad lowpass filter with specific parameters
    174         biquad_section<fbase> bq[] = { biquad_lowpass(0.2, 0.9) };
    175         // Create a type-erased expression filter for the biquad lowpass filter
    176         expression_filter<fbase> filter = to_filter(iir(placeholder<fbase>(), iir_params{ bq }));
    177 
    178         // Prepare a unit impulse signal
    179         output = unitimpulse();
    180 
    181         // Apply the expression filter to the unit impulse signal
    182         filter.apply(output);
    183     }
    184     // Save the plot of the filter response
    185     plot_save("biquad_custom_filter_lowpass", output,
    186               options + ", title='Biquad Low pass filter (0.2, 0.9) (using expression_filter)'");
    187 
    188     // --------------------------------------------------------------------------------------
    189     // ---------------------- Custom Biquad Lowpass Filter using iir_filter -----------------
    190     // --------------------------------------------------------------------------------------
    191     {
    192         // Initialize a biquad lowpass filter with specific parameters
    193         biquad_section<fbase> bq[] = { biquad_lowpass(0.2, 0.9) };
    194         // Create an IIR filter for the biquad lowpass filter
    195         iir_filter<fbase> filter(bq);
    196 
    197         // Prepare a unit impulse signal
    198         output = unitimpulse();
    199 
    200         // Apply the IIR filter to the unit impulse signal
    201         filter.apply(output);
    202     }
    203     // Save the plot of the filter response
    204     plot_save("biquad_filter_lowpass", output,
    205               options + ", title='Biquad Low pass filter (0.2, 0.9) (using iir_filter)'");
    206 
    207     println("SVG plots have been saved to svg directory");
    208 
    209     return 0;
    210 }