annotate examples/10-Instruments/d-box/Biquad.cpp @ 556:ce391098f321 prerelease tip

THIS PROJECT HAS MOVED TO https://github.com/BelaPlatform/bela
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 25 Jun 2016 20:21:00 +0100
parents 8fcfbfb32aa0
children
rev   line source
robert@464 1 //
robert@464 2 // Biquad.cpp
robert@464 3 //
robert@464 4 // Created by Nigel Redmon on 11/24/12
robert@464 5 // EarLevel Engineering: earlevel.com
robert@464 6 // Copyright 2012 Nigel Redmon
robert@464 7 //
robert@464 8 // For a complete explanation of the Biquad code:
robert@464 9 // http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
robert@464 10 //
robert@464 11 // License:
robert@464 12 //
robert@464 13 // This source code is provided as is, without warranty.
robert@464 14 // You may copy and distribute verbatim copies of this document.
robert@464 15 // You may modify and use this source code to create binary code
robert@464 16 // for your own purposes, free or commercial.
robert@464 17 //
robert@464 18
robert@464 19 #include <math.h>
robert@464 20 #include "Biquad.h"
robert@464 21 #include <iostream>
robert@464 22
robert@464 23 Biquad::Biquad() {
robert@464 24 type = bq_type_lowpass;
robert@464 25 a0 = 1.0;
robert@464 26 a1 = a2 = b1 = b2 = 0.0;
robert@464 27 Fc = 0.50;
robert@464 28 Q = 0.707;
robert@464 29 peakGain = 0.0;
robert@464 30 z1 = z2 = 0.0;
robert@464 31 }
robert@464 32
robert@464 33 Biquad::Biquad(int type, double Fc, double Q, double peakGainDB) {
robert@464 34 setBiquad(type, Fc, Q, peakGainDB);
robert@464 35 z1 = z2 = 0.0;
robert@464 36 }
robert@464 37
robert@464 38 Biquad::~Biquad() {
robert@464 39 }
robert@464 40
robert@464 41 void Biquad::setType(int type) {
robert@464 42 this->type = type;
robert@464 43 calcBiquad();
robert@464 44 }
robert@464 45
robert@464 46 void Biquad::setQ(double Q) {
robert@464 47 this->Q = Q;
robert@464 48 calcBiquad();
robert@464 49 }
robert@464 50
robert@464 51 void Biquad::setFc(double Fc) {
robert@464 52 this->Fc = Fc;
robert@464 53 calcBiquad();
robert@464 54 }
robert@464 55
robert@464 56 void Biquad::setPeakGain(double peakGainDB) {
robert@464 57 this->peakGain = peakGainDB;
robert@464 58 calcBiquad();
robert@464 59 }
robert@464 60
robert@464 61 void Biquad::setBiquad(int type, double Fc, double Q, double peakGainDB) {
robert@464 62 this->type = type;
robert@464 63 this->Q = Q;
robert@464 64 this->Fc = Fc;
robert@464 65 startFc = Fc;
robert@464 66 startQ = Q;
robert@464 67 startPeakGain = peakGainDB;
robert@464 68 setPeakGain(peakGainDB);
robert@464 69 }
robert@464 70
robert@464 71 void Biquad::calcBiquad(void) {
robert@464 72 double norm;
robert@464 73 double V = pow(10, fabs(peakGain) / 20.0);
robert@464 74 double K = tan(M_PI * Fc);
robert@464 75 switch (this->type) {
robert@464 76 case bq_type_lowpass:
robert@464 77 norm = 1 / (1 + K / Q + K * K);
robert@464 78 a0 = K * K * norm;
robert@464 79 a1 = 2 * a0;
robert@464 80 a2 = a0;
robert@464 81 b1 = 2 * (K * K - 1) * norm;
robert@464 82 b2 = (1 - K / Q + K * K) * norm;
robert@464 83 break;
robert@464 84
robert@464 85 case bq_type_highpass:
robert@464 86 norm = 1 / (1 + K / Q + K * K);
robert@464 87 a0 = 1 * norm;
robert@464 88 a1 = -2 * a0;
robert@464 89 a2 = a0;
robert@464 90 b1 = 2 * (K * K - 1) * norm;
robert@464 91 b2 = (1 - K / Q + K * K) * norm;
robert@464 92 break;
robert@464 93
robert@464 94 case bq_type_bandpass:
robert@464 95 norm = 1 / (1 + K / Q + K * K);
robert@464 96 a0 = K / Q * norm;
robert@464 97 a1 = 0;
robert@464 98 a2 = -a0;
robert@464 99 b1 = 2 * (K * K - 1) * norm;
robert@464 100 b2 = (1 - K / Q + K * K) * norm;
robert@464 101 break;
robert@464 102
robert@464 103 case bq_type_notch:
robert@464 104 norm = 1 / (1 + K / Q + K * K);
robert@464 105 a0 = (1 + K * K) * norm;
robert@464 106 a1 = 2 * (K * K - 1) * norm;
robert@464 107 a2 = a0;
robert@464 108 b1 = a1;
robert@464 109 b2 = (1 - K / Q + K * K) * norm;
robert@464 110 break;
robert@464 111
robert@464 112 case bq_type_peak:
robert@464 113 if (peakGain >= 0) { // boost
robert@464 114 norm = 1 / (1 + 1/Q * K + K * K);
robert@464 115 a0 = (1 + V/Q * K + K * K) * norm;
robert@464 116 a1 = 2 * (K * K - 1) * norm;
robert@464 117 a2 = (1 - V/Q * K + K * K) * norm;
robert@464 118 b1 = a1;
robert@464 119 b2 = (1 - 1/Q * K + K * K) * norm;
robert@464 120 }
robert@464 121 else { // cut
robert@464 122 norm = 1 / (1 + V/Q * K + K * K);
robert@464 123 a0 = (1 + 1/Q * K + K * K) * norm;
robert@464 124 a1 = 2 * (K * K - 1) * norm;
robert@464 125 a2 = (1 - 1/Q * K + K * K) * norm;
robert@464 126 b1 = a1;
robert@464 127 b2 = (1 - V/Q * K + K * K) * norm;
robert@464 128 }
robert@464 129 break;
robert@464 130 case bq_type_lowshelf:
robert@464 131 if (peakGain >= 0) { // boost
robert@464 132 norm = 1 / (1 + sqrt(2) * K + K * K);
robert@464 133 a0 = (1 + sqrt(2*V) * K + V * K * K) * norm;
robert@464 134 a1 = 2 * (V * K * K - 1) * norm;
robert@464 135 a2 = (1 - sqrt(2*V) * K + V * K * K) * norm;
robert@464 136 b1 = 2 * (K * K - 1) * norm;
robert@464 137 b2 = (1 - sqrt(2) * K + K * K) * norm;
robert@464 138 }
robert@464 139 else { // cut
robert@464 140 norm = 1 / (1 + sqrt(2*V) * K + V * K * K);
robert@464 141 a0 = (1 + sqrt(2) * K + K * K) * norm;
robert@464 142 a1 = 2 * (K * K - 1) * norm;
robert@464 143 a2 = (1 - sqrt(2) * K + K * K) * norm;
robert@464 144 b1 = 2 * (V * K * K - 1) * norm;
robert@464 145 b2 = (1 - sqrt(2*V) * K + V * K * K) * norm;
robert@464 146 }
robert@464 147 break;
robert@464 148 case bq_type_highshelf:
robert@464 149 if (peakGain >= 0) { // boost
robert@464 150 norm = 1 / (1 + sqrt(2) * K + K * K);
robert@464 151 a0 = (V + sqrt(2*V) * K + K * K) * norm;
robert@464 152 a1 = 2 * (K * K - V) * norm;
robert@464 153 a2 = (V - sqrt(2*V) * K + K * K) * norm;
robert@464 154 b1 = 2 * (K * K - 1) * norm;
robert@464 155 b2 = (1 - sqrt(2) * K + K * K) * norm;
robert@464 156 }
robert@464 157 else { // cut
robert@464 158 norm = 1 / (V + sqrt(2*V) * K + K * K);
robert@464 159 a0 = (1 + sqrt(2) * K + K * K) * norm;
robert@464 160 a1 = 2 * (K * K - 1) * norm;
robert@464 161 a2 = (1 - sqrt(2) * K + K * K) * norm;
robert@464 162 b1 = 2 * (K * K - V) * norm;
robert@464 163 b2 = (V - sqrt(2*V) * K + K * K) * norm;
robert@464 164 }
robert@464 165 break;
robert@464 166 }
robert@464 167
robert@464 168 return;
robert@464 169 }