Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "SVFilter.h" 00020 #include "../common_source.h" 00021 #include <algorithm> 00022 00023 using std::min; 00024 using std::max; 00025 using namespace Marsyas; 00026 00027 00028 SVFilter::SVFilter(mrs_string name): 00029 MarSystem("SVFilter", name), 00030 type_(0), 00031 res_(0.1), 00032 notch(0.0), 00033 low (0.0), 00034 high(0.0), 00035 band(0.0) 00036 { 00037 addControls(); 00038 } 00039 00040 SVFilter::SVFilter( const SVFilter & other ): 00041 MarSystem(other), 00042 type_(0), 00043 res_(0.1), 00044 notch(0.0), 00045 low (0.0), 00046 high(0.0), 00047 band(0.0) 00048 {} 00049 00050 SVFilter::~SVFilter() 00051 { 00052 } 00053 00054 MarSystem* 00055 SVFilter::clone() const 00056 { 00057 return new SVFilter(*this); 00058 } 00059 00060 void 00061 SVFilter::addControls() 00062 { 00063 addctrl("mrs_real/frequency", 440.0); 00064 addctrl("mrs_real/res", 0.2); 00065 addctrl("mrs_bool/freqin", false); 00066 addctrl("mrs_natural/type", 0); 00067 00068 setctrlState("mrs_real/frequency", true); 00069 setctrlState("mrs_real/res", true); 00070 setctrlState("mrs_bool/freqin", true); 00071 setctrlState("mrs_natural/type", true); 00072 } 00073 00074 void 00075 SVFilter::myUpdate(MarControlPtr sender) 00076 { 00077 MRSDIAG("SVFilter.cpp - SVFilter:myUpdate"); 00078 00079 freqIn_ = (getctrl("mrs_bool/freqin")->to<mrs_bool>()); 00080 frequency_ = (getctrl("mrs_real/frequency")->to<mrs_real>()); 00081 res_ = (getctrl("mrs_real/res")->to<mrs_real>()); 00082 israte_ = (getctrl("mrs_real/israte")->to<mrs_real>()); 00083 00084 MarSystem::myUpdate(sender); 00085 } 00086 00087 void 00088 SVFilter::myProcess(realvec& in, realvec& out) 00089 { 00090 mrs_natural t; 00091 mrs_real fc = frequency_; 00092 mrs_real fs = 44100.0; 00093 00094 mrs_real drive = 0.02; // keep between 0.0 and 0.1 00095 mrs_real freq = 2.0*sin(PI*min(0.25, fc/(fs*2))); // the fs*2 is because it's double sampled 00096 mrs_real damp = min(2.0*(1.0 - pow(res_, 0.25)), min(2.0, 2.0/freq - freq*0.5)); 00097 00098 for (t = 0; t < inSamples_; t++) 00099 { 00100 // the fs*2 is because it's double sampled 00101 freq = 2.0*sin(PI*min(0.25, (freqIn_ ? in(1, t)*israte_: fc)/(israte_*2))); 00102 damp = min(2.0*(1.0 - pow(res_, 0.25)), min(2.0, 2.0/freq - freq*0.5)); 00103 00104 notch = in(0, t) - damp*band; 00105 low = low + freq*band; 00106 high = notch - low; 00107 band = freq*high + band - drive*band*band*band; 00108 00109 switch(type_) { 00110 case 0: 00111 out(0, t) = 0.5*low; break; 00112 case 1: 00113 out(0, t) = 0.5*high; break; 00114 case 2: 00115 out(0, t) = 0.5*band; break; 00116 case 3: 00117 out(0, t) = 0.5*notch; break; 00118 } 00119 00120 notch = in(0, t) - damp*band; 00121 low = low + freq*band; 00122 high = notch - low; 00123 band = freq*high + band - drive*band*band*band; 00124 00125 switch(type_) { 00126 case 0: 00127 out(0, t) += 0.5*low; break; 00128 case 1: 00129 out(0, t) += 0.5*high; break; 00130 case 2: 00131 out(0, t) += 0.5*band; break; 00132 case 3: 00133 out(0, t) += 0.5*notch; break; 00134 } 00135 00136 } 00137 }