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

Committer:
Padman
Date:
Thu Aug 04 19:56:33 2016 +0000
Revision:
3:495d3542ccb5
Parent:
2:74e41881a5d9
Child:
4:ec48ce56b8c1
Added the example

Who changed what in which revision?

UserRevisionLine numberNew 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 2:74e41881a5d9 44 enum FilterType {
Padman 2:74e41881a5d9 45
Padman 2:74e41881a5d9 46 Peaking,
Padman 2:74e41881a5d9 47 BandPass,
Padman 2:74e41881a5d9 48 BandStop,
Padman 2:74e41881a5d9 49 LowShelf,
Padman 2:74e41881a5d9 50 HighShelf,
Padman 2:74e41881a5d9 51 LowPass,
Padman 2:74e41881a5d9 52 HighPass
Padman 2:74e41881a5d9 53 };
Padman 2:74e41881a5d9 54
Padman 0:2e17a3d6907c 55 /** A fixed point parametric EQ implementing Butterworth coefficients in direct form 2 transposed realisation
Padman 0:2e17a3d6907c 56 *
Padman 0:2e17a3d6907c 57 * Example:
Padman 0:2e17a3d6907c 58 * @code
Padman 0:2e17a3d6907c 59 * #include "mbed.h"
Padman 0:2e17a3d6907c 60 * #include "ParametricEQ.h"
Padman 0:2e17a3d6907c 61 *
Padman 0:2e17a3d6907c 62 * ParametricEQ myEQ;
Padman 0:2e17a3d6907c 63 * Serial pc(USBTX, USBRX);
Padman 0:2e17a3d6907c 64 *
Padman 0:2e17a3d6907c 65 * int main()
Padman 0:2e17a3d6907c 66 * {
Padman 0:2e17a3d6907c 67 * while(1) {
Padman 0:2e17a3d6907c 68 *
Padman 0:2e17a3d6907c 69 * while(pc.readable()) {
Padman 0:2e17a3d6907c 70 *
Padman 3:495d3542ccb5 71 * pc.printf("%d\n", myEQ.filter(pc.getc()));
Padman 0:2e17a3d6907c 72 * }
Padman 0:2e17a3d6907c 73 *
Padman 0:2e17a3d6907c 74 * }
Padman 0:2e17a3d6907c 75 * }
Padman 0:2e17a3d6907c 76 * @endcode
Padman 0:2e17a3d6907c 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