A parametric EQ that uses a fixed point, direct form 2 transposed, implementation of a Butterworth filter. The following parameters can be adjusted: Gain (dB), Bandwidth Gain (dB), Centre frequency (Hz), Bandwidth (Hz), Order, Type (Peaking, Bandstop, Bandpass, Low Shelf, High Shelf, Low Pass or High Pass).
ParametricEQ.h@1:0545d8890dc6, 2016-08-04 (annotated)
- Committer:
- Padman
- Date:
- Thu Aug 04 19:47:00 2016 +0000
- Revision:
- 1:0545d8890dc6
- Parent:
- 0:2e17a3d6907c
- Child:
- 2:74e41881a5d9
Made biquad a nested class of ParametricEQ
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Padman | 0:2e17a3d6907c | 1 | /** |
Padman | 0:2e17a3d6907c | 2 | * @file ParametricEQ.h |
Padman | 0:2e17a3d6907c | 3 | * @brief ParametricEQ - fixed point implementation of a Parametric EQ |
Padman | 0:2e17a3d6907c | 4 | * @author Patrick Thomas |
Padman | 0:2e17a3d6907c | 5 | * @version 1.0 |
Padman | 0:2e17a3d6907c | 6 | * @see |
Padman | 0:2e17a3d6907c | 7 | * |
Padman | 0:2e17a3d6907c | 8 | * Copyright (c) 2016 |
Padman | 0:2e17a3d6907c | 9 | * |
Padman | 0:2e17a3d6907c | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Padman | 0:2e17a3d6907c | 11 | * you may not use this file except in compliance with the License. |
Padman | 0:2e17a3d6907c | 12 | * You may obtain a copy of the License at |
Padman | 0:2e17a3d6907c | 13 | * |
Padman | 0:2e17a3d6907c | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
Padman | 0:2e17a3d6907c | 15 | * |
Padman | 0:2e17a3d6907c | 16 | * Unless required by applicable law or agreed to in writing, software |
Padman | 0:2e17a3d6907c | 17 | * distributed under the License is distributed on an "AS IS" BASIS, |
Padman | 0:2e17a3d6907c | 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Padman | 0:2e17a3d6907c | 19 | * See the License for the specific language governing permissions and |
Padman | 0:2e17a3d6907c | 20 | * limitations under the License. |
Padman | 0:2e17a3d6907c | 21 | */ |
Padman | 0:2e17a3d6907c | 22 | |
Padman | 0:2e17a3d6907c | 23 | #ifndef PARAMETRICEQ_H |
Padman | 0:2e17a3d6907c | 24 | #define PARAMETRICEQ_H |
Padman | 0:2e17a3d6907c | 25 | |
Padman | 0:2e17a3d6907c | 26 | #include <math.h> |
Padman | 0:2e17a3d6907c | 27 | |
Padman | 0:2e17a3d6907c | 28 | #define M_PI 3.14159265358979323846 |
Padman | 0:2e17a3d6907c | 29 | |
Padman | 0:2e17a3d6907c | 30 | // Parameter limits |
Padman | 0:2e17a3d6907c | 31 | #define GAIN_DB_MAX 20 |
Padman | 0:2e17a3d6907c | 32 | #define BW_HZ_MIN 20 |
Padman | 0:2e17a3d6907c | 33 | #define GBW_MARGIN 0.01 |
Padman | 0:2e17a3d6907c | 34 | #define MAX_ORDER 4 |
Padman | 0:2e17a3d6907c | 35 | |
Padman | 0:2e17a3d6907c | 36 | // Sampling limits |
Padman | 0:2e17a3d6907c | 37 | #define SAMPLE_RATE_MAX 192000 |
Padman | 0:2e17a3d6907c | 38 | #define SAMPLE_RATE_MIN 32000 |
Padman | 0:2e17a3d6907c | 39 | #define SAMPLE_BITS_MIN 8 |
Padman | 0:2e17a3d6907c | 40 | #define SAMPLE_BITS_MAX 24 |
Padman | 0:2e17a3d6907c | 41 | |
Padman | 0:2e17a3d6907c | 42 | #define PIN(n,min,max) ((n) > (max) ? max : ((n) < (min) ? (min) : (n))) |
Padman | 0:2e17a3d6907c | 43 | |
Padman | 0:2e17a3d6907c | 44 | /** A fixed point parametric EQ implementing Butterworth coefficients in direct form 2 transposed realisation |
Padman | 0:2e17a3d6907c | 45 | * |
Padman | 0:2e17a3d6907c | 46 | * Example: |
Padman | 0:2e17a3d6907c | 47 | * @code |
Padman | 0:2e17a3d6907c | 48 | * #include "mbed.h" |
Padman | 0:2e17a3d6907c | 49 | * #include "ParametricEQ.h" |
Padman | 0:2e17a3d6907c | 50 | * |
Padman | 0:2e17a3d6907c | 51 | * ParametricEQ myEQ; |
Padman | 0:2e17a3d6907c | 52 | * Serial pc(USBTX, USBRX); |
Padman | 0:2e17a3d6907c | 53 | * |
Padman | 0:2e17a3d6907c | 54 | * int main() |
Padman | 0:2e17a3d6907c | 55 | * { |
Padman | 0:2e17a3d6907c | 56 | * while(1) { |
Padman | 0:2e17a3d6907c | 57 | * |
Padman | 0:2e17a3d6907c | 58 | * while(pc.readable()) { |
Padman | 0:2e17a3d6907c | 59 | * |
Padman | 0:2e17a3d6907c | 60 | * pc.printf("(pc.getc()); |
Padman | 0:2e17a3d6907c | 61 | * } |
Padman | 0:2e17a3d6907c | 62 | * |
Padman | 0:2e17a3d6907c | 63 | * } |
Padman | 0:2e17a3d6907c | 64 | * } |
Padman | 0:2e17a3d6907c | 65 | * @endcode |
Padman | 0:2e17a3d6907c | 66 | */ |
Padman | 1:0545d8890dc6 | 67 | |
Padman | 1:0545d8890dc6 | 68 | enum FilterType { |
Padman | 1:0545d8890dc6 | 69 | |
Padman | 1:0545d8890dc6 | 70 | Peaking, |
Padman | 1:0545d8890dc6 | 71 | BandPass, |
Padman | 1:0545d8890dc6 | 72 | BandStop, |
Padman | 1:0545d8890dc6 | 73 | LowShelf, |
Padman | 1:0545d8890dc6 | 74 | HighShelf, |
Padman | 1:0545d8890dc6 | 75 | LowPass, |
Padman | 1:0545d8890dc6 | 76 | HighPass |
Padman | 1:0545d8890dc6 | 77 | }; |
Padman | 1:0545d8890dc6 | 78 | |
Padman | 1:0545d8890dc6 | 79 | class ParametricEQ { |
Padman | 0:2e17a3d6907c | 80 | |
Padman | 0:2e17a3d6907c | 81 | class biquad { |
Padman | 0:2e17a3d6907c | 82 | |
Padman | 0:2e17a3d6907c | 83 | private: |
Padman | 0:2e17a3d6907c | 84 | |
Padman | 0:2e17a3d6907c | 85 | // Local accumulators |
Padman | 0:2e17a3d6907c | 86 | int v1; |
Padman | 0:2e17a3d6907c | 87 | int v2; |
Padman | 0:2e17a3d6907c | 88 | int v3; |
Padman | 0:2e17a3d6907c | 89 | int v4; |
Padman | 0:2e17a3d6907c | 90 | int w1; |
Padman | 0:2e17a3d6907c | 91 | int w2; |
Padman | 0:2e17a3d6907c | 92 | |
Padman | 0:2e17a3d6907c | 93 | public: |
Padman | 0:2e17a3d6907c | 94 | |
Padman | 0:2e17a3d6907c | 95 | // Local coefficients |
Padman | 0:2e17a3d6907c | 96 | int c0; |
Padman | 0:2e17a3d6907c | 97 | int s0; |
Padman | 0:2e17a3d6907c | 98 | int bhat_0; |
Padman | 0:2e17a3d6907c | 99 | int bhat_1; |
Padman | 0:2e17a3d6907c | 100 | int bhat_2; |
Padman | 0:2e17a3d6907c | 101 | int ahat_1; |
Padman | 0:2e17a3d6907c | 102 | int ahat_2; |
Padman | 0:2e17a3d6907c | 103 | |
Padman | 0:2e17a3d6907c | 104 | // Sampling variables |
Padman | 0:2e17a3d6907c | 105 | int scaling_factor; |
Padman | 0:2e17a3d6907c | 106 | int sample_bounds; |
Padman | 0:2e17a3d6907c | 107 | |
Padman | 0:2e17a3d6907c | 108 | int execute(int input); |
Padman | 0:2e17a3d6907c | 109 | }; |
Padman | 0:2e17a3d6907c | 110 | |
Padman | 0:2e17a3d6907c | 111 | // This module's fx blocks |
Padman | 0:2e17a3d6907c | 112 | biquad fx_blocks[(MAX_ORDER + 1)/2]; |
Padman | 0:2e17a3d6907c | 113 | |
Padman | 0:2e17a3d6907c | 114 | // Parameter variables |
Padman | 0:2e17a3d6907c | 115 | float Gain_dB; |
Padman | 0:2e17a3d6907c | 116 | float GBW_dB; |
Padman | 0:2e17a3d6907c | 117 | int F0_Hz; |
Padman | 0:2e17a3d6907c | 118 | int BW_Hz; |
Padman | 0:2e17a3d6907c | 119 | int Order; |
Padman | 0:2e17a3d6907c | 120 | FilterType Type; |
Padman | 0:2e17a3d6907c | 121 | |
Padman | 0:2e17a3d6907c | 122 | // Sampling variables |
Padman | 0:2e17a3d6907c | 123 | int Sample_rate; |
Padman | 0:2e17a3d6907c | 124 | int Sample_bits; |
Padman | 0:2e17a3d6907c | 125 | |
Padman | 0:2e17a3d6907c | 126 | // Intermediary parameter variables |
Padman | 0:2e17a3d6907c | 127 | double Gain_amplitude, Bandwidth_gain_amplitude, G0_amplitude, Normalised_centre_frequency, Normalised_bandwidth, |
Padman | 0:2e17a3d6907c | 128 | g, epsilon, beta, g_squared, beta_squared, f0_cosine, f0_sine, D, phi, si, g0, g0_squared; |
Padman | 0:2e17a3d6907c | 129 | int counter; |
Padman | 0:2e17a3d6907c | 130 | |
Padman | 0:2e17a3d6907c | 131 | // Intermediary sampling variables |
Padman | 0:2e17a3d6907c | 132 | int Scaling_factor, Sample_bounds; |
Padman | 0:2e17a3d6907c | 133 | |
Padman | 0:2e17a3d6907c | 134 | void check_GBW(); |
Padman | 0:2e17a3d6907c | 135 | void calculate(); |
Padman | 0:2e17a3d6907c | 136 | void update_blocks(); |
Padman | 0:2e17a3d6907c | 137 | |
Padman | 0:2e17a3d6907c | 138 | public: |
Padman | 0:2e17a3d6907c | 139 | |
Padman | 0:2e17a3d6907c | 140 | /** Create an EQ |
Padman | 0:2e17a3d6907c | 141 | */ |
Padman | 0:2e17a3d6907c | 142 | ParametricEQ(); |
Padman | 0:2e17a3d6907c | 143 | |
Padman | 0:2e17a3d6907c | 144 | /** Set the Gain |
Padman | 0:2e17a3d6907c | 145 | * @param value The target gain (dB) |
Padman | 0:2e17a3d6907c | 146 | * @return The actual gain (dB) |
Padman | 0:2e17a3d6907c | 147 | */ |
Padman | 0:2e17a3d6907c | 148 | float set_Gain_dB(float value); |
Padman | 0:2e17a3d6907c | 149 | |
Padman | 0:2e17a3d6907c | 150 | /** Set the Bandwidth Gain. NB |GBW_dB| must be less than |Gain_dB| |
Padman | 0:2e17a3d6907c | 151 | * @param value The target bandwidth gain (dB) |
Padman | 0:2e17a3d6907c | 152 | * @return The actual bandwidth gain (dB) |
Padman | 0:2e17a3d6907c | 153 | */ |
Padman | 0:2e17a3d6907c | 154 | float set_GBW_dB(float value); |
Padman | 0:2e17a3d6907c | 155 | |
Padman | 0:2e17a3d6907c | 156 | /** Set the Centre frequency |
Padman | 0:2e17a3d6907c | 157 | * @param value The target centre frequency (Hz) |
Padman | 0:2e17a3d6907c | 158 | * @return The actual centre frequency (Hz) |
Padman | 0:2e17a3d6907c | 159 | */ |
Padman | 0:2e17a3d6907c | 160 | int set_F0_Hz(int value); |
Padman | 0:2e17a3d6907c | 161 | |
Padman | 0:2e17a3d6907c | 162 | /** Set the Bandwidth |
Padman | 0:2e17a3d6907c | 163 | * @param value The target bandwidth (Hz) |
Padman | 0:2e17a3d6907c | 164 | * @return The actual bandwidth (Hz) |
Padman | 0:2e17a3d6907c | 165 | */ |
Padman | 0:2e17a3d6907c | 166 | int set_BW_Hz(int value); |
Padman | 0:2e17a3d6907c | 167 | |
Padman | 0:2e17a3d6907c | 168 | /** Set the Order. Higher order increases cutoff |
Padman | 0:2e17a3d6907c | 169 | * @param value The target order |
Padman | 0:2e17a3d6907c | 170 | * @return The actual order |
Padman | 0:2e17a3d6907c | 171 | */ |
Padman | 0:2e17a3d6907c | 172 | int set_Order(int value); |
Padman | 0:2e17a3d6907c | 173 | |
Padman | 0:2e17a3d6907c | 174 | /** Set the Filter type. |
Padman | 0:2e17a3d6907c | 175 | * @param value The target type: 0 - Peaking, 1 - BandPass, 2 - BandStop, 3 - LowShelf, 4 - HighShelf, 5 - LowPass, 6 - HighPass |
Padman | 0:2e17a3d6907c | 176 | * @return The actual type |
Padman | 0:2e17a3d6907c | 177 | */ |
Padman | 0:2e17a3d6907c | 178 | FilterType set_Type(FilterType type); |
Padman | 0:2e17a3d6907c | 179 | |
Padman | 0:2e17a3d6907c | 180 | /** Set the Sample rate |
Padman | 0:2e17a3d6907c | 181 | * @param value The target sample rate |
Padman | 0:2e17a3d6907c | 182 | * @return The actual sample rate |
Padman | 0:2e17a3d6907c | 183 | */ |
Padman | 0:2e17a3d6907c | 184 | int set_Sample_rate(int value); |
Padman | 0:2e17a3d6907c | 185 | |
Padman | 0:2e17a3d6907c | 186 | /** Set the number of Sample bits |
Padman | 0:2e17a3d6907c | 187 | * @param value The target number of sample bits |
Padman | 0:2e17a3d6907c | 188 | * @return The actual number of sample bits |
Padman | 0:2e17a3d6907c | 189 | */ |
Padman | 0:2e17a3d6907c | 190 | int set_Sample_bits(int value); |
Padman | 0:2e17a3d6907c | 191 | |
Padman | 0:2e17a3d6907c | 192 | /** Pass a sample through the EQ |
Padman | 0:2e17a3d6907c | 193 | * @param input The input sample |
Padman | 0:2e17a3d6907c | 194 | * @return The filtered output |
Padman | 0:2e17a3d6907c | 195 | */ |
Padman | 0:2e17a3d6907c | 196 | int filter(int input); |
Padman | 0:2e17a3d6907c | 197 | }; |
Padman | 0:2e17a3d6907c | 198 | |
Padman | 0:2e17a3d6907c | 199 | #endif |