annotate sv/filter/EqualizerFilter.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents 960531792d88
children
rev   line source
lbajardsilogic@223 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@223 2
lbajardsilogic@223 3 /* Sound Access
lbajardsilogic@223 4 EASAIER client application.
lbajardsilogic@223 5 Silogic 2007. Laure Bajard.
lbajardsilogic@223 6
lbajardsilogic@223 7 Integration of the filter provided by:
lbajardsilogic@223 8 Dublin Institute of Technology - Audio Research Group 2007
lbajardsilogic@223 9 www.audioresearchgroup.com
lbajardsilogic@223 10 Author: Dan Barry
lbajardsilogic@223 11
lbajardsilogic@223 12 This program is free software; you can redistribute it and/or
lbajardsilogic@223 13 modify it under the terms of the GNU General Public License as
lbajardsilogic@223 14 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@223 15 License, or (at your option) any later version. See the file
lbajardsilogic@223 16 COPYING included with this distribution for more information.
lbajardsilogic@223 17 */
lbajardsilogic@223 18
lbajardsilogic@223 19 #include <math.h>
lbajardsilogic@223 20 #include <iostream>
lbajardsilogic@223 21
lbajardsilogic@223 22 #include "EqualizerFilter.h"
lbajardsilogic@223 23
lbajardsilogic@223 24 #include "FFTReal.h"
lbajardsilogic@223 25 #include "DSP.h"
lbajardsilogic@223 26
lbajardsilogic@223 27 #include "system/System.h"
lbajardsilogic@223 28 #include "main/MainWindow.h"
lbajardsilogic@223 29
lbajardsilogic@229 30
lbajardsilogic@232 31 EqualizerFilter::EqualizerFilter(size_t framesize, QMutex *mutex) : PropertyContainer() ,
lbajardsilogic@235 32 m_simpleMode(true) ,
lbajardsilogic@232 33 m_nbBand(5),
lbajardsilogic@232 34 m_framesize(framesize),
lbajardsilogic@232 35 m_mutex(mutex),
lbajardsilogic@232 36 m_resolution(400)
lbajardsilogic@223 37 {
lbajardsilogic@232 38 for (int i=0; i<m_nbBand; i++) {
lbajardsilogic@232 39 m_gainband[i] = 0;
lbajardsilogic@232 40 }
lbajardsilogic@232 41
benoitrigolleau@276 42 setObjectName("Audio Equalizer");
lbajardsilogic@225 43
lbajardsilogic@232 44 m_curve = (float *) calloc(m_resolution, sizeof(float));
lbajardsilogic@229 45
lbajardsilogic@232 46 band = (float **)calloc(m_nbBand, sizeof(float*));
lbajardsilogic@232 47 for(int i = 0 ; i < m_nbBand ; i++){
lbajardsilogic@232 48 band[i]=(float *)calloc((m_framesize/2), sizeof(float));
lbajardsilogic@232 49 }
lbajardsilogic@232 50
lbajardsilogic@232 51 m_plotbandcurve=(float *)malloc(sizeof(float)*(m_resolution));
lbajardsilogic@235 52
benoitrigolleau@240 53 m_mutex->lock();
lbajardsilogic@235 54 if (m_simpleMode)
lbajardsilogic@235 55 {
lbajardsilogic@235 56 create_filterbands();
lbajardsilogic@235 57 }
lbajardsilogic@235 58 else
lbajardsilogic@235 59 {
lbajardsilogic@241 60 for(int i = 0 ; i < m_resolution ; i++){
lbajardsilogic@241 61 m_eqcurve.push_back(0);
lbajardsilogic@235 62 }
lbajardsilogic@235 63 }
benoitrigolleau@240 64 m_mutex->unlock();
lbajardsilogic@235 65
lbajardsilogic@229 66 setFilterEnabled(false);
lbajardsilogic@223 67 }
lbajardsilogic@223 68
lbajardsilogic@223 69 EqualizerFilter::~EqualizerFilter()
lbajardsilogic@229 70 {
lbajardsilogic@229 71 m_eqcurve.clear();
lbajardsilogic@241 72
lbajardsilogic@232 73 for(int i = 0 ; i < m_nbBand ; i++){
lbajardsilogic@232 74 delete band[i];
lbajardsilogic@232 75 }
lbajardsilogic@232 76 delete band;
lbajardsilogic@241 77 band = 0;
lbajardsilogic@241 78
lbajardsilogic@241 79 delete m_plotbandcurve;
lbajardsilogic@241 80 m_plotbandcurve = 0;
lbajardsilogic@229 81 }
lbajardsilogic@223 82
lbajardsilogic@223 83 EqualizerFilter::PropertyList EqualizerFilter::getProperties() const
lbajardsilogic@223 84 {
lbajardsilogic@223 85 PropertyList list;
lbajardsilogic@236 86 list.push_back("DrawCurve");
lbajardsilogic@236 87 list.push_back("Equalizer");
lbajardsilogic@236 88 list.push_back("Enable");
lbajardsilogic@232 89 for (int i=0; i<m_nbBand; i++) {
lbajardsilogic@232 90 QString name = "GainBand" + QString::number(i);
lbajardsilogic@232 91 list.push_back(name);
lbajardsilogic@232 92 }
lbajardsilogic@225 93 return list;
lbajardsilogic@223 94 }
lbajardsilogic@223 95
lbajardsilogic@223 96 QString EqualizerFilter::getPropertyLabel(const PropertyName &name) const
lbajardsilogic@223 97 {
lbajardsilogic@223 98 if (name == "Equalizer") return tr("Equalizer");
lbajardsilogic@232 99 if (name == "SimpleMode") return tr("Simple Mode");
lbajardsilogic@235 100 if (name == "DrawCurve") return tr("Draw Curve");
lbajardsilogic@223 101 return "";
lbajardsilogic@223 102 }
lbajardsilogic@223 103
lbajardsilogic@223 104 EqualizerFilter::PropertyType EqualizerFilter::getPropertyType(const PropertyName &name) const
lbajardsilogic@223 105 {
lbajardsilogic@223 106 if (name == "Equalizer") return PlotProperty;
lbajardsilogic@225 107 if (name == "Enable") return InvalidProperty;
lbajardsilogic@235 108 if (name == "DrawCurve") return ToggleProperty;
lbajardsilogic@232 109 if (name.left(8) == "GainBand") return RangeProperty;
lbajardsilogic@225 110 return InvalidProperty;
lbajardsilogic@223 111 }
lbajardsilogic@241 112
lbajardsilogic@241 113 QString EqualizerFilter::getPropertyGroupName(const PropertyName &name) const
lbajardsilogic@241 114 {
benoitrigolleau@277 115 if (name.left(8) == "GainBand") return " ";
lbajardsilogic@235 116 if ((name == "Equalizer") || (name == "DrawCurve")) return "Draw Curve";
lbajardsilogic@241 117 return QString();
lbajardsilogic@241 118 }
lbajardsilogic@223 119
lbajardsilogic@223 120 int EqualizerFilter::getPropertyRangeAndValue(const PropertyName &name,
lbajardsilogic@223 121 int *min, int *max, int *deflt) const
lbajardsilogic@223 122 {
lbajardsilogic@223 123 //!!! factor this colour handling stuff out into a colour manager class
lbajardsilogic@223 124 int val = 0;
lbajardsilogic@223 125
lbajardsilogic@223 126 if (name == "Equalizer") {
lbajardsilogic@223 127 /*if (deflt) *deflt = 0;
lbajardsilogic@223 128 val = (m_peakcheck ? 1 : 0);*/
lbajardsilogic@223 129 }
lbajardsilogic@225 130
lbajardsilogic@225 131 if (name == "Enable") {
lbajardsilogic@225 132 if (deflt) *deflt = 0;
lbajardsilogic@225 133 val = (m_enabled ? 1 : 0);
lbajardsilogic@225 134 }
lbajardsilogic@225 135
lbajardsilogic@235 136 if (name == "DrawCurve") {
lbajardsilogic@232 137 if (deflt) *deflt = 0;
lbajardsilogic@235 138 val = (m_simpleMode ? 0 : 1);
lbajardsilogic@232 139 }
lbajardsilogic@232 140
lbajardsilogic@232 141 if (name.left(8) == "GainBand") {
lbajardsilogic@232 142 if (min) *min = -100;
lbajardsilogic@232 143 if (max) *max = 100;
lbajardsilogic@232 144 if (deflt) *deflt = 0;
lbajardsilogic@232 145 int i = name.right(1).toInt();
lbajardsilogic@232 146 val = m_gainband[i];
lbajardsilogic@232 147 }
lbajardsilogic@232 148
lbajardsilogic@223 149 #ifdef DEBUG_FILTERS
lbajardsilogic@223 150 std::cerr << "EqualizerFilter::getPropertyRangeAndValue = " << val << std::endl;
lbajardsilogic@223 151 #endif
lbajardsilogic@223 152 return val;
lbajardsilogic@223 153 }
lbajardsilogic@223 154
lbajardsilogic@223 155 QString EqualizerFilter::getPropertyValueLabel(const PropertyName &name,
lbajardsilogic@223 156 int value) const
lbajardsilogic@223 157 {
lbajardsilogic@223 158 return tr("<unknown>");
lbajardsilogic@223 159 }
lbajardsilogic@223 160
lbajardsilogic@223 161 void EqualizerFilter::setProperty(const PropertyName &name, int value)
lbajardsilogic@223 162 {
lbajardsilogic@223 163 if (name == "Equalizer"){
lbajardsilogic@223 164
lbajardsilogic@225 165 } else if (name == "Enable"){
lbajardsilogic@225 166 if (value > 0)
lbajardsilogic@225 167 {
lbajardsilogic@225 168 m_enabled = true;
lbajardsilogic@225 169 } else
lbajardsilogic@225 170 {
lbajardsilogic@225 171 m_enabled = false;
lbajardsilogic@225 172 }
lbajardsilogic@225 173 emit propertyChanged("Enable");
lbajardsilogic@235 174 } else if (name == "DrawCurve"){
lbajardsilogic@235 175 m_simpleMode = (value > 0) ? false : true;
benoitrigolleau@240 176 if (!m_simpleMode)
lbajardsilogic@232 177 {
benoitrigolleau@240 178 emit enableDrawCurve(!m_simpleMode);
benoitrigolleau@240 179 }
benoitrigolleau@240 180 else
benoitrigolleau@240 181 {
benoitrigolleau@240 182 m_mutex->lock();
benoitrigolleau@240 183 emit enableDrawCurve(!m_simpleMode);
lbajardsilogic@232 184 create_filterbands();
benoitrigolleau@240 185 m_mutex->unlock();
benoitrigolleau@240 186
lbajardsilogic@232 187 }
lbajardsilogic@232 188 } else if (name.left(8) == "GainBand"){
lbajardsilogic@232 189 int i = name.right(1).toInt();
lbajardsilogic@232 190 m_gainband[i] = value;
benoitrigolleau@240 191 m_mutex->lock();
lbajardsilogic@232 192 create_filterbands();
benoitrigolleau@240 193 m_mutex->unlock();
lbajardsilogic@223 194 }
lbajardsilogic@232 195
lbajardsilogic@223 196 #ifdef DEBUG_FILTERS
lbajardsilogic@223 197 std::cerr << "EqualizerFilter::hopfactor = " << hopfactor << std::endl;
lbajardsilogic@223 198 std::cerr << "EqualizerFilter::m_interpfactor = " << m_interpfactor << std::endl;
lbajardsilogic@223 199 std::cerr << "EqualizerFilter::m_hop = " << m_hop << std::endl;
lbajardsilogic@223 200 std::cerr << "EqualizerFilter::skip = " << getRequiredSkipSamples() << std::endl;
lbajardsilogic@223 201 #endif
lbajardsilogic@223 202
lbajardsilogic@223 203 }
lbajardsilogic@223 204
lbajardsilogic@233 205 void EqualizerFilter::setProperty(const PropertyName &name , QVector<float> value)
lbajardsilogic@229 206 {
benoitrigolleau@240 207
lbajardsilogic@229 208 if (name == "Equalizer"){
benoitrigolleau@240 209 m_mutex->lock();
lbajardsilogic@229 210 m_eqcurve.clear();
lbajardsilogic@229 211 for (int i = 0; i < value.size(); i++)
lbajardsilogic@229 212 {
lbajardsilogic@229 213 m_eqcurve.push_back(value.at(i));
lbajardsilogic@229 214 }
benoitrigolleau@240 215 m_mutex->unlock();
lbajardsilogic@229 216 }
lbajardsilogic@229 217 }
lbajardsilogic@229 218
lbajardsilogic@223 219 void EqualizerFilter::setFilterEnabled(bool b){
lbajardsilogic@223 220 m_enabled=b;
lbajardsilogic@223 221 emit filterEnabled(m_enabled);
lbajardsilogic@223 222 }
lbajardsilogic@223 223
lbajardsilogic@223 224 void EqualizerFilter::setFilterEnabled(int b){
lbajardsilogic@223 225 m_enabled=b;
lbajardsilogic@223 226 emit filterEnabled(m_enabled);
lbajardsilogic@223 227 }
lbajardsilogic@223 228
lbajardsilogic@229 229 void EqualizerFilter::emitPlotFFTArray(float *signal, int framesize)
lbajardsilogic@229 230 {
lbajardsilogic@232 231 log10plot(signal, m_curve, framesize, m_resolution);
lbajardsilogic@229 232
lbajardsilogic@229 233 emit signalChanged(m_curve);
lbajardsilogic@229 234 }
lbajardsilogic@232 235
lbajardsilogic@232 236
lbajardsilogic@232 237 void EqualizerFilter::create_filterbands()
lbajardsilogic@232 238 {
benoitrigolleau@240 239 //m_mutex->lock();
lbajardsilogic@232 240
lbajardsilogic@232 241 float binwidth = 44100/4096;
lbajardsilogic@232 242
lbajardsilogic@232 243 float xover1 = 80; //100
lbajardsilogic@232 244 float xover2 = 700; //700
lbajardsilogic@232 245 float xover3 = 3000; //3000
lbajardsilogic@232 246 float xover4 = 9000; //9000
lbajardsilogic@232 247
lbajardsilogic@232 248 float width1 = 50; //50
lbajardsilogic@232 249 float width2 = 300; //100
lbajardsilogic@232 250 float width3 = 3000; //300
lbajardsilogic@232 251 float width4 = 1900; //900
lbajardsilogic@232 252
lbajardsilogic@232 253 int w;
lbajardsilogic@232 254
lbajardsilogic@232 255 xover1=(xover1/binwidth);
lbajardsilogic@232 256 xover2=(xover2/binwidth);
lbajardsilogic@232 257 xover3=(xover3/binwidth);
lbajardsilogic@232 258 xover4=(xover4/binwidth);
lbajardsilogic@232 259
lbajardsilogic@232 260 width1=(width1/binwidth);
lbajardsilogic@232 261 width2=(width2/binwidth);
lbajardsilogic@232 262 width3=(width3/binwidth);
lbajardsilogic@232 263 width4=(width4/binwidth);
lbajardsilogic@232 264
lbajardsilogic@232 265 int p1 = 0;
lbajardsilogic@232 266 int p2 = floor(xover1-(width1/2));
lbajardsilogic@232 267 int p3 = floor(xover1+(width1/2));
lbajardsilogic@232 268 int p4 = floor(xover2-(width2/2));
lbajardsilogic@232 269 int p5 = floor(xover2+(width2/2));
lbajardsilogic@232 270 int p6 = floor(xover3-(width3/2));
lbajardsilogic@232 271 int p7 = floor(xover3+(width3/2));
lbajardsilogic@232 272 int p8 = floor(xover4-(width4/2));
lbajardsilogic@232 273 int p9 = floor(xover4+(width4/2));
lbajardsilogic@232 274 int p10 = 2048;
lbajardsilogic@232 275
lbajardsilogic@232 276 float maxcut=190; //18db of attenuation
lbajardsilogic@232 277 float inc_cut=(1-(1/maxcut))/100;
lbajardsilogic@232 278
lbajardsilogic@232 279 float maxboost=2; //6 db of gain
lbajardsilogic@232 280 float inc_boost=(maxboost-1)/100;
lbajardsilogic@232 281 float g1=1,g2=1,g3=1,g4=1,g5=1,instgain=1;
lbajardsilogic@232 282
lbajardsilogic@232 283 if (m_gainband[0] < 0){g1=(1/maxcut)+((100+ (float)m_gainband[0])*inc_cut);} //not finished!!!!
lbajardsilogic@232 284 if (m_gainband[0] == 0){g1=1;}
lbajardsilogic@232 285 if (m_gainband[0] > 0){g1=1+(((float)m_gainband[0])*inc_boost);}
lbajardsilogic@232 286
lbajardsilogic@232 287 if (m_gainband[1] < 0){g2=(1/maxcut)+((100+ (float)m_gainband[1])*inc_cut);} //not finished!!!!
lbajardsilogic@232 288 if (m_gainband[1] == 0){g2=1;}
lbajardsilogic@232 289 if (m_gainband[1] > 0){g2=1+(((float)m_gainband[1])*inc_boost);}
lbajardsilogic@232 290
lbajardsilogic@232 291 if (m_gainband[2] < 0){g3=(1/maxcut)+((100+ (float)m_gainband[2])*inc_cut);} //not finished!!!!
lbajardsilogic@232 292 if (m_gainband[2] == 0){g3=1;}
lbajardsilogic@232 293 if (m_gainband[2] > 0){g3=1+(((float)m_gainband[2])*inc_boost);}
lbajardsilogic@232 294
lbajardsilogic@232 295 if (m_gainband[3] < 0){g4=(1/maxcut)+((100+ (float)m_gainband[3])*inc_cut);} //not finished!!!!
lbajardsilogic@232 296 if (m_gainband[3] == 0){g4=1;}
lbajardsilogic@232 297 if (m_gainband[3] > 0){g4=1+(((float)m_gainband[3])*inc_boost);}
lbajardsilogic@232 298
lbajardsilogic@232 299 if (m_gainband[4] < 0){g5=(1/maxcut)+((100+ (float)m_gainband[4])*inc_cut);} //not finished!!!!
lbajardsilogic@232 300 if (m_gainband[4] == 0){g5=1;}
lbajardsilogic@232 301 if (m_gainband[4] > 0){g5=1+(((float)m_gainband[4])*inc_boost);}
lbajardsilogic@232 302
lbajardsilogic@232 303 m_eqcurve.clear();
lbajardsilogic@232 304
lbajardsilogic@232 305
lbajardsilogic@232 306 for (int i=0;i<m_framesize/2;i++)
lbajardsilogic@232 307 {
lbajardsilogic@232 308 if (i < p2)
lbajardsilogic@232 309 {
lbajardsilogic@232 310 band[0][i]=1;
lbajardsilogic@232 311 band[1][i]=0;
lbajardsilogic@232 312 band[2][i]=0;
lbajardsilogic@232 313 band[3][i]=0;
lbajardsilogic@232 314 band[4][i]=0;
lbajardsilogic@232 315 }
lbajardsilogic@232 316
lbajardsilogic@232 317 if (i >= p2 && i <= p3)
lbajardsilogic@232 318 {
lbajardsilogic@232 319 w = p3-p2+1;
lbajardsilogic@232 320 band[0][i]= (0.5*(1-cos(2*PI*((i-p2+w)+1)/((2*w)))));
lbajardsilogic@232 321 band[1][i]= (0.5*(1-cos(2*PI*((i-p2)+1)/((2*w)))));
lbajardsilogic@232 322 band[2][i]=0;
lbajardsilogic@232 323 band[3][i]=0;
lbajardsilogic@232 324 band[4][i]=0;
lbajardsilogic@232 325 }
lbajardsilogic@232 326
lbajardsilogic@232 327
lbajardsilogic@232 328 if (i > p3 && i < p4)
lbajardsilogic@232 329 {
lbajardsilogic@232 330 band[0][i]=0;
lbajardsilogic@232 331 band[1][i]=1;
lbajardsilogic@232 332 band[2][i]=0;
lbajardsilogic@232 333 band[3][i]=0;
lbajardsilogic@232 334 band[4][i]=0;
lbajardsilogic@232 335 }
lbajardsilogic@232 336
lbajardsilogic@232 337 if (i >= p4 && i <= p5)
lbajardsilogic@232 338 {
lbajardsilogic@232 339 w = p4-p5+1;
lbajardsilogic@232 340 band[0][i]=0;
lbajardsilogic@232 341 band[1][i]= (0.5*(1-cos(2*PI*((i-p4+w)+1)/((2*w)))));
lbajardsilogic@232 342 band[2][i]= (0.5*(1-cos(2*PI*((i-p4)+1)/((2*w)))));
lbajardsilogic@232 343 band[3][i]=0;
lbajardsilogic@232 344 band[4][i]=0;
lbajardsilogic@232 345 }
lbajardsilogic@232 346
lbajardsilogic@232 347 if (i > p5 && i < p6)
lbajardsilogic@232 348 {
lbajardsilogic@232 349 band[0][i]=0;
lbajardsilogic@232 350 band[1][i]=0;
lbajardsilogic@232 351 band[2][i]=1;
lbajardsilogic@232 352 band[3][i]=0;
lbajardsilogic@232 353 band[4][i]=0;
lbajardsilogic@232 354 }
lbajardsilogic@232 355
lbajardsilogic@232 356 if (i >= p6 && i <= p7)
lbajardsilogic@232 357 {
lbajardsilogic@232 358 w = p6-p7+1;
lbajardsilogic@232 359 band[0][i]=0;
lbajardsilogic@232 360 band[1][i]=0;
lbajardsilogic@232 361 band[2][i]= (0.5*(1-cos(2*PI*((i-p6+w)+1)/((2*w)))));
lbajardsilogic@232 362 band[3][i]= (0.5*(1-cos(2*PI*((i-p6)+1)/((2*w)))));
lbajardsilogic@232 363 band[4][i]=0;
lbajardsilogic@232 364 }
lbajardsilogic@232 365
lbajardsilogic@232 366 if (i > p7 && i < p8)
lbajardsilogic@232 367 {
lbajardsilogic@232 368 band[0][i]=0;
lbajardsilogic@232 369 band[1][i]=0;
lbajardsilogic@232 370 band[2][i]=0;
lbajardsilogic@232 371 band[3][i]=1;
lbajardsilogic@232 372 band[4][i]=0;
lbajardsilogic@232 373 }
lbajardsilogic@232 374
lbajardsilogic@232 375 if (i >= p8 && i <= p9)
lbajardsilogic@232 376 {
lbajardsilogic@232 377 w = p8-p9+1;
lbajardsilogic@232 378 band[0][i]=0;
lbajardsilogic@232 379 band[1][i]=0;
lbajardsilogic@232 380 band[2][i]=0;
lbajardsilogic@232 381 band[3][i]= (0.5*(1-cos(2*PI*((i-p8+w)+1)/((2*w)))));
lbajardsilogic@232 382 band[4][i]= (0.5*(1-cos(2*PI*((i-p8)+1)/((2*w)))));
lbajardsilogic@232 383
lbajardsilogic@232 384 }
lbajardsilogic@232 385
lbajardsilogic@232 386 if (i > p9 && i < p10)
lbajardsilogic@232 387 {
lbajardsilogic@232 388 band[0][i]=0;
lbajardsilogic@232 389 band[1][i]=0;
lbajardsilogic@232 390 band[2][i]=0;
lbajardsilogic@232 391 band[3][i]=0;
lbajardsilogic@232 392 band[4][i]=1;
lbajardsilogic@232 393 }
lbajardsilogic@232 394
lbajardsilogic@232 395 instgain=(g1*band[0][i])+(g2*band[1][i])+(g3*band[2][i])+(g4*band[3][i])+(g5*band[4][i]);
lbajardsilogic@233 396 m_eqcurve.push_back(instgain);
lbajardsilogic@232 397 }
lbajardsilogic@232 398
lbajardsilogic@232 399 log10plot2(m_eqcurve,m_plotbandcurve, m_framesize, m_resolution);
lbajardsilogic@232 400
lbajardsilogic@232 401 emit filterChanged(m_plotbandcurve);
benoitrigolleau@240 402
benoitrigolleau@240 403 //m_mutex->unlock();
lbajardsilogic@232 404
lbajardsilogic@232 405 }