1 /* 2 * Author: Harry van Haaren 2014 3 * harryhaaren@gmail.com 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 * MA 02110-1301, USA. 19 */ 20 21 #ifndef OPENAV_DSP_COMPANDER_H 22 #define OPENAV_DSP_COMPANDER_H 23 24 #include <cstring> 25 #include <cmath> 26 #include <math.h> 27 #include <cmath> 28 #include <cstdlib> 29 #include <stdlib.h> 30 #include <iostream> 31 32 using namespace std; 33 34 /** Compander 35 * A compressor/expander combo: a threshold sets the expander/compressor turn 36 * point, while a factor control regulates the amount of compression/expansion. 37 * 38 * Derived from https://github.com/magnetophon/qompander 39 **/ 40 class Compander // : Effect 41 { 42 public: Compander(int sr)43 Compander(int sr) : 44 samplerate( sr ) 45 { 46 _active = true; 47 48 init(); 49 50 attack = 20.f; 51 release = 20; 52 53 threshold = -60.f; 54 factor = 3.f; 55 } 56 getValue()57 float getValue() 58 { 59 return factor; 60 } 61 setValue(float v)62 void setValue(float v) 63 { 64 if ( v < 0.f ) v = 0.f; 65 if ( v > 1.f ) v = 1.f; 66 67 factor = 1 + v * 7; 68 } 69 setThreshold(float v)70 void setThreshold( float v ) 71 { 72 if ( v < 0.f ) v = 0.f; 73 if ( v > 1.f ) v = 1.f; 74 75 // -20 to -80dB range 76 threshold = (v * 60.f) - 80; 77 } 78 setAttack(float v)79 void setAttack( float v ) 80 { 81 if ( v < 0.f ) v = 0.f; 82 if ( v > 1.f ) v = 1.f; 83 attack = v * 18 + 2; 84 } 85 setRelease(float v)86 void setRelease( float v) 87 { 88 if ( v < 0.f ) v = 0.f; 89 if ( v > 1.f ) v = 1.f; 90 release = v * 230 + 20; 91 } 92 93 active(bool a)94 void active(bool a) 95 { 96 _active = a; 97 } 98 getNumInputs()99 int getNumInputs() 100 { 101 return 1; 102 } getNumOutputs()103 int getNumOutputs() 104 { 105 return 1; 106 } 107 process(long count,float * input0,float * output0)108 void process (long count, float* input0, float* output0) 109 { 110 if ( _active ) { 111 float fSlow0 = (0.0010000000000000009f * attack); 112 float fSlow1 = (0.0010000000000000009f * release); 113 float fSlow2 = (0.0010000000000000009f * factor); 114 float fSlow3 = (0.0010000000000000009f * threshold); 115 116 for (int i=0; i<count; i++) { 117 fRec1[0] = (fSlow0 + (0.999f * fRec1[1])); 118 float fTemp0 = expf((0 - (fConst0 / fRec1[0]))); 119 float fTemp1 = (float)input0[i]; 120 fVec0[0] = fTemp1; 121 fRec6[0] = (fVec0[0] + (0.161758f * fRec6[2])); 122 fRec5[0] = (((0.733029f * fRec5[2]) + (0.161758f * fRec6[0])) - fRec6[2]); 123 fRec4[0] = (((0.94535f * fRec4[2]) + (0.733029f * fRec5[0])) - fRec5[2]); 124 fRec3[0] = (((0.990598f * fRec3[2]) + (0.94535f * fRec4[0])) - fRec4[2]); 125 float fTemp2 = ((0.990598f * fRec3[0]) - fRec3[2]); 126 fRec10[0] = ((0.479401f * fRec10[2]) + fVec0[1]); 127 fRec9[0] = (((0.876218f * fRec9[2]) + (0.479401f * fRec10[0])) - fRec10[2]); 128 fRec8[0] = (((0.976599f * fRec8[2]) + (0.876218f * fRec9[0])) - fRec9[2]); 129 fRec7[0] = (((0.9975f * fRec7[2]) + (0.976599f * fRec8[0])) - fRec8[2]); 130 float fTemp3 = ((0.9975f * fRec7[0]) - fRec7[2]); 131 132 //float fTemp4 = fabsf(min((float)100, max(1e-05f, sqrtf( (faustpower<2>(fTemp3) + faustpower<2>(fTemp2)))))); 133 float fTemp4 = fabsf(min((float)100, max(1e-05f, sqrtf( ( pow( fTemp3, 2 ) + pow( fTemp2, 2 ) ) ) ) ) ); 134 135 fRec11[0] = (fSlow1 + (0.999f * fRec11[1])); 136 float fTemp5 = expf((0 - (fConst0 / fRec11[0]))); 137 fRec2[0] = (((1.0f - fTemp5) * fTemp4) + (fTemp5 * max(fTemp4, fRec2[1]))); 138 fRec0[0] = ((fRec2[0] * (1.0f - fTemp0)) + (fTemp0 * fRec0[1])); 139 fRec12[0] = (fSlow2 + (0.999f * fRec12[1])); 140 fRec13[0] = (fSlow3 + (0.999f * fRec13[1])); 141 float fTemp6 = powf(10,(0.05f * fRec13[0])); 142 output0[i] = (float)(0.7071067811865476f * ((powf(min((float)1, max(1e-07f, sinf((1.5707963267948966f * (fRec12[0] * min((1.0f / fRec12[0]), fRec0[0])))))),(logf(fTemp6) / logf(sinf((1.5707963267948966f * (fRec12[0] * fTemp6)))))) * (fTemp3 + fTemp2)) / fRec0[0])); 143 // post processing 144 fRec13[1] = fRec13[0]; 145 fRec12[1] = fRec12[0]; 146 fRec0[1] = fRec0[0]; 147 fRec2[1] = fRec2[0]; 148 fRec11[1] = fRec11[0]; 149 fRec7[2] = fRec7[1]; 150 fRec7[1] = fRec7[0]; 151 fRec8[2] = fRec8[1]; 152 fRec8[1] = fRec8[0]; 153 fRec9[2] = fRec9[1]; 154 fRec9[1] = fRec9[0]; 155 fRec10[2] = fRec10[1]; 156 fRec10[1] = fRec10[0]; 157 fRec3[2] = fRec3[1]; 158 fRec3[1] = fRec3[0]; 159 fRec4[2] = fRec4[1]; 160 fRec4[1] = fRec4[0]; 161 fRec5[2] = fRec5[1]; 162 fRec5[1] = fRec5[0]; 163 fRec6[2] = fRec6[1]; 164 fRec6[1] = fRec6[0]; 165 fVec0[1] = fVec0[0]; 166 fRec1[1] = fRec1[0]; 167 } 168 } else { 169 // set input -> output 170 if( output0 != input0 ) 171 memcpy( output0, input0, count * sizeof(float) ); 172 } 173 } 174 175 private: 176 int samplerate; 177 bool _active; 178 179 float attack; 180 float release; 181 float factor; 182 float fRec1[2]; 183 float fConst0; 184 float fVec0[2]; 185 float fRec6[3]; 186 float fRec5[3]; 187 float fRec4[3]; 188 float fRec3[3]; 189 float fRec10[3]; 190 float fRec9[3]; 191 float fRec8[3]; 192 float fRec7[3]; 193 float fRec11[2]; 194 float fRec2[2]; 195 float fRec0[2]; 196 197 float fRec12[2]; 198 float threshold; 199 float fRec13[2]; 200 init()201 void init() 202 { 203 attack = 2.0f; 204 205 for (int i=0; i<2; i++) fRec1[i] = 0; 206 fConst0 = (1e+03f / float(min(192000, max(1, samplerate)))); 207 for (int i=0; i<2; i++) fVec0[i] = 0; 208 for (int i=0; i<3; i++) fRec6[i] = 0; 209 for (int i=0; i<3; i++) fRec5[i] = 0; 210 for (int i=0; i<3; i++) fRec4[i] = 0; 211 for (int i=0; i<3; i++) fRec3[i] = 0; 212 for (int i=0; i<3; i++) fRec10[i] = 0; 213 for (int i=0; i<3; i++) fRec9[i] = 0; 214 for (int i=0; i<3; i++) fRec8[i] = 0; 215 for (int i=0; i<3; i++) fRec7[i] = 0; 216 release = 2e+01f; 217 for (int i=0; i<2; i++) fRec11[i] = 0; 218 for (int i=0; i<2; i++) fRec2[i] = 0; 219 for (int i=0; i<2; i++) fRec0[i] = 0; 220 factor = 1.0f; 221 for (int i=0; i<2; i++) fRec12[i] = 0; 222 threshold = -4e+01f; 223 for (int i=0; i<2; i++) fRec13[i] = 0; 224 } 225 226 }; 227 228 #endif // OPENAV_DSP_COMPANDER_H 229