00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ERB.h"
00021 #include "Series.h"
00022 #include "Filter.h"
00023 #include <sstream>
00024
00025
00026 using std::ostringstream;
00027 using std::stringstream;
00028
00029 using namespace Marsyas;
00030
00031 ERB::ERB(mrs_string name):MarSystem("ERB", name),
00032 filterBank (0)
00033 {
00034
00035
00036
00037 fs = 0;
00038 numChannels = 0;
00039 lowFreq = 0;
00040
00041 addControls();
00042 }
00043
00044
00045 ERB::~ERB()
00046 {
00047 }
00048
00049 MarSystem*
00050 ERB::clone() const
00051 {
00052 return new ERB(*this);
00053 }
00054
00055
00056 void
00057 ERB::addControls()
00058 {
00059 addctrl("mrs_natural/numChannels", 1);
00060 addctrl("mrs_real/lowFreq", 100.0f);
00061
00062 setctrlState("mrs_natural/numChannels", true);
00063 setctrlState("mrs_real/lowFreq", true);
00064 }
00065
00066 void
00067 ERB::myUpdate(MarControlPtr sender)
00068 {
00069 (void) sender;
00070 MRSDIAG("ERB.cpp - ERB:myUpdate");
00071
00072
00073 if (numChannels != getctrl("mrs_natural/numChannels")->to<mrs_natural>()){
00074 numChannels = getctrl("mrs_natural/numChannels")->to<mrs_natural>();
00075 if (filterBank) delete filterBank;
00076 filterBank = new Fanout("filterBank");
00077 stringstream name;
00078 for(mrs_natural i = 0; i < numChannels; ++i){
00079 name << "channel_" << i;
00080 Series* channel = new Series(name.str());
00081 name.str("");
00082 name << "filter_" << i << "_" << 0;
00083 Filter* filter_0 = new Filter(name.str());
00084 name.str("");
00085 name << "filter_" << i << "_" << 1;
00086 Filter* filter_1 = new Filter(name.str());
00087 name.str("");
00088 name << "filter_" << i << "_" << 2;
00089 Filter* filter_2 = new Filter(name.str());
00090 name.str("");
00091 name << "filter_" << i << "_" << 3;
00092 Filter* filter_3 = new Filter(name.str());
00093 name.str("");
00094 channel->addMarSystem(filter_0);
00095 channel->addMarSystem(filter_1);
00096 channel->addMarSystem(filter_2);
00097 channel->addMarSystem(filter_3);
00098 filterBank->addMarSystem(channel);
00099 }
00100 centerFreqs.create(numChannels);
00101 fcoefs.create(numChannels, 10);
00102 }
00103
00104 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00105 setctrl("mrs_natural/onObservations", numChannels*getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00106 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00107
00108
00109 lowFreq = getctrl("mrs_real/lowFreq")->to<mrs_real>();
00110 fs = getctrl("mrs_real/israte")->to<mrs_real>();
00111 highFreq = fs/2;
00112 EarQ = 9.26449f;
00113 minBW = 24.7f;
00114 order = 1;
00115
00116 for (mrs_natural i = 0; i < numChannels; ++i){
00117 centerFreqs(i) = - (EarQ*minBW) + exp((i+1)*(-log(highFreq+EarQ*minBW) + log(lowFreq+EarQ*minBW))/numChannels)*(highFreq + EarQ*minBW);
00118 }
00119
00120 A0 = 1/fs;
00121 A2 = 0.0f;
00122 B0 = 1.0f;
00123
00124 for (mrs_natural i = 0; i < numChannels; ++i){
00125 fcoefs(i,0) = A0;
00126 fcoefs(i,1) = A11(centerFreqs(i), B(E(centerFreqs(i))));
00127 fcoefs(i,2) = A12(centerFreqs(i), B(E(centerFreqs(i))));
00128 fcoefs(i,3) = A13(centerFreqs(i), B(E(centerFreqs(i))));
00129 fcoefs(i,4) = A14(centerFreqs(i), B(E(centerFreqs(i))));
00130 fcoefs(i,5) = A2;
00131 fcoefs(i,6) = B0;
00132 fcoefs(i,7) = B1(centerFreqs(i), B(E(centerFreqs(i))));
00133 fcoefs(i,8) = B2( B(E(centerFreqs(i))));
00134 fcoefs(i,9) = gain(centerFreqs(i), B(E(centerFreqs(i))));
00135 }
00136
00137
00138 stringstream channel,filter,ctrl;
00139 realvec b(1,3),a(1,3);
00140 channel << "Series/channel_0/";
00141 ctrl << channel.str() << "mrs_natural/inSamples";
00142 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inSamples"));
00143 ctrl.str("");
00144 ctrl << channel.str() << "mrs_natural/inObservations";
00145 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations"));
00146 ctrl.str("");
00147 ctrl << channel.str() << "mrs_natural/onObservations";
00148 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations"));
00149 ctrl.str("");
00150 ctrl << channel.str() << "mrs_real/israte";
00151 filterBank->setctrl(ctrl.str(), getctrl("mrs_real/israte"));
00152 for(mrs_natural i = 0; i < numChannels; ++i){
00153
00154 channel.str("");
00155 channel << "Series/channel_" << i << "/";
00156 filter.str("");
00157 filter << channel.str() << "Filter/filter_" << i << "_" << 0 << "/";
00158 ctrl.str("");
00159 ctrl << filter.str() << "mrs_natural/inSamples";
00160 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inSamples"));
00161 ctrl.str("");
00162 ctrl << filter.str() << "mrs_natural/inObservations";
00163 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations"));
00164 ctrl.str("");
00165 ctrl << filter.str() << "mrs_natural/onObservations";
00166 filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations"));
00167 ctrl.str("");
00168 ctrl << filter.str() << "mrs_real/israte";
00169 filterBank->setctrl(ctrl.str(), getctrl("mrs_real/israte"));
00170 a(0) = fcoefs(i,6);
00171 a(1) = fcoefs(i,7);
00172 a(2) = fcoefs(i,8);
00173 b(0) = fcoefs(i,0)/fcoefs(i,9);
00174 b(1) = fcoefs(i,1)/fcoefs(i,9);
00175 b(2) = fcoefs(i,5)/fcoefs(i,9);
00176 ctrl.str("");
00177 ctrl << filter.str() << "mrs_realvec/ncoeffs";
00178 filterBank->setctrl(ctrl.str(), b);
00179 ctrl.str("");
00180 ctrl << filter.str() << "mrs_realvec/dcoeffs";
00181 filterBank->setctrl(ctrl.str(), a);
00182
00183 filter.str("");
00184 filter << channel.str() << "Filter/filter_" << i << "_" << 1 << "/";
00185 a(0) = fcoefs(i,6);
00186 a(1) = fcoefs(i,7);
00187 a(2) = fcoefs(i,8);
00188 b(0) = fcoefs(i,0);
00189 b(1) = fcoefs(i,2);
00190 b(2) = fcoefs(i,5);
00191 ctrl.str("");
00192 ctrl << filter.str() << "mrs_realvec/ncoeffs";
00193 filterBank->setctrl(ctrl.str(), b);
00194 ctrl.str("");
00195 ctrl << filter.str() << "mrs_realvec/dcoeffs";
00196 filterBank->setctrl(ctrl.str(), a);
00197
00198 filter.str("");
00199 filter << channel.str() << "Filter/filter_" << i << "_" << 2 << "/";
00200 a(0) = fcoefs(i,6);
00201 a(1) = fcoefs(i,7);
00202 a(2) = fcoefs(i,8);
00203 b(0) = fcoefs(i,0);
00204 b(1) = fcoefs(i,3);
00205 b(2) = fcoefs(i,5);
00206 ctrl.str("");
00207 ctrl << filter.str() << "mrs_realvec/ncoeffs";
00208 filterBank->setctrl(ctrl.str(), b);
00209 ctrl.str("");
00210 ctrl << filter.str() << "mrs_realvec/dcoeffs";
00211 filterBank->setctrl(ctrl.str(), a);
00212
00213 filter.str("");
00214 filter << channel.str() << "Filter/filter_" << i << "_" << 3 << "/";
00215 a(0) = fcoefs(i,6);
00216 a(1) = fcoefs(i,7);
00217 a(2) = fcoefs(i,8);
00218 b(0) = fcoefs(i,0);
00219 b(1) = fcoefs(i,4);
00220 b(2) = fcoefs(i,5);
00221 ctrl.str("");
00222 ctrl << filter.str() << "mrs_realvec/ncoeffs";
00223 filterBank->setctrl(ctrl.str(), b);
00224 ctrl.str("");
00225 ctrl << filter.str() << "mrs_realvec/dcoeffs";
00226 filterBank->setctrl(ctrl.str(), a);
00227 }
00228
00229 filterBank->update();
00230 }
00231
00232
00233 mrs_real
00234 ERB::E(mrs_real x)
00235 {
00236 return pow(pow(x/EarQ, (mrs_real)order) + pow(minBW, (mrs_real)order), 1/(mrs_real)order);
00237 }
00238
00239 mrs_real
00240 ERB::B(mrs_real x)
00241 {
00242 return 1.019f*2.0f*PI*x;
00243 }
00244
00245 mrs_real
00246 ERB::B1(mrs_real x, mrs_real y)
00247 {
00248 return -2.0f*cos(2.0f*x*PI/fs)/exp(y/fs);
00249 }
00250
00251 mrs_real
00252 ERB::B2(mrs_real x)
00253 {
00254 return exp(-2.0f*x/fs);
00255 }
00256
00257 mrs_real
00258 ERB::A11(mrs_real x, mrs_real y)
00259 {
00260 return -(2.0f/fs*cos(2.0f*x*PI/fs)/exp(y/fs) + 2.0f*sqrt(3.0f+sqrt(8.0f))/fs*sin(2.0f*x*PI/fs)/exp(y/fs))/2.0f;
00261 }
00262
00263
00264 mrs_real
00265 ERB::A12(mrs_real x, mrs_real y)
00266 {
00267 return -(2.0f/fs*cos(2.0f*x*PI/fs)/exp(y/fs) - 2.0f*sqrt(3.0f+sqrt(8.0f))/fs*sin(2.0f*x*PI/fs)/exp(y/fs))/2.0f;
00268 }
00269
00270 mrs_real
00271 ERB::A13(mrs_real x, mrs_real y)
00272 {
00273 return -(2.0f/fs*cos(2.0f*x*PI/fs)/exp(y/fs) + 2.0f*sqrt(3.0f-sqrt(8.0f))/fs*sin(2.0f*x*PI/fs)/exp(y/fs))/2.0f;
00274 }
00275
00276 mrs_real
00277 ERB::A14(mrs_real x, mrs_real y)
00278 {
00279 return -(2.0f/fs*cos(2.0f*x*PI/fs)/exp(y/fs) - 2.0f*sqrt(3.0f-sqrt(8.0f))/fs*sin(2.0f*x*PI/fs)/exp(y/fs))/2.0f;
00280 }
00281
00282 mrs_real
00283 ERB::gain(mrs_real x, mrs_real y)
00284 {
00285 mrs_real r1(2.0f*x*PI/fs);
00286 mrs_real r2(sqrt(3.0f-sqrt(8.0f)));
00287 mrs_real r3(sqrt(3.0f+sqrt(8.0f)));
00288 mrs_real z1r(cos(2.0f*r1)),z1i(sin(2.0f*r1));
00289 mrs_real z2r(cos(r1)),z2i(sin(r1));
00290 mrs_real z3r(-2.0f*z1r/fs),z3i(-2.0f*z1i/fs);
00291 mrs_real z4r(2.0f*exp(-y/fs)*z2r/fs),z4i(2.0f*exp(-y/fs)*z2i/fs);
00292 return abs(z3r + z4r*(cos(r1)-r2*sin(r1)),z3i + z4i*(cos(r1)-r2*sin(r1)))*
00293 abs(z3r + z4r*(cos(r1)+r2*sin(r1)),z3i + z4i*(cos(r1)+r2*sin(r1)))*
00294 abs(z3r + z4r*(cos(r1)-r3*sin(r1)),z3i + z4i*(cos(r1)-r3*sin(r1)))*
00295 abs(z3r + z4r*(cos(r1)+r3*sin(r1)),z3i + z4i*(cos(r1)+r3*sin(r1)))/
00296 pow(abs(-2.0f/exp(2.0f*y/fs) - 2.0f*z1r + 2.0f*(1.0f + z1r)/exp(y/fs),2.0f*z1i*(-1.0f + 1.0f/exp(y/fs))),4);
00297 }
00298
00299 mrs_real
00300 ERB::abs(mrs_real r1, mrs_real r2)
00301 {
00302 return sqrt(r1*r1 + r2*r2);
00303 }
00304
00305 void
00306 ERB::myProcess(realvec& in, realvec& out)
00307 {
00308
00309
00310 if(getctrl("mrs_bool/mute")->to<mrs_bool>()) return;
00311
00312 filterBank->process(in, out);
00313 }