00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "SeneffEar.h"
00020 #include "fft.h"
00021
00022 #include <sstream>
00023
00024 using namespace std;
00025 using namespace Marsyas;
00026
00027 SeneffEar::SeneffEar(mrs_string name):MarSystem("SeneffEar",name)
00028 {
00029
00030
00031
00032 firstUpdate = true;
00033 fs = 0.0f;
00034 stage = 4;
00035
00036 addControls();
00037 }
00038
00039 SeneffEar::~SeneffEar()
00040 {
00041 }
00042
00043 MarSystem*
00044 SeneffEar::clone() const
00045 {
00046 return new SeneffEar(*this);
00047 }
00048
00049 void
00050 SeneffEar::addControls()
00051 {
00052 addctrl("mrs_natural/stage", stage);
00053 }
00054
00055 void
00056 SeneffEar::myUpdate(MarControlPtr sender)
00057 {
00058 (void) sender;
00059 MRSDIAG("SeneffEar.cpp - SeneffEar:myUpdate");
00060
00061 ostringstream name;
00062
00063
00064 if (firstUpdate) {
00065
00066 stringstream matrix;
00067 matrix << "# MARSYAS realvec" << endl;
00068 matrix << "# Size = 8" << endl;
00069 matrix << endl;
00070 matrix << endl;
00071 matrix << "# type: matrix" << endl;
00072 matrix << "# rows: 4" << endl;
00073 matrix << "# columns: 2" << endl;
00074 matrix << "0.86 3.1148863";
00075 matrix << "0.99 0.0";
00076 matrix << "0.5 0.0";
00077 matrix << "0.95 3.14159";
00078 matrix << endl;
00079 matrix << "# Size = 8" << endl;
00080 matrix << "# MARSYAS realvec" << endl;
00081 matrix >> PreemphasisRThetaCoeffs;
00082
00083
00084 matrix.clear();
00085 matrix << "# MARSYAS realvec" << endl;
00086 matrix << "# Size = 200" << endl;
00087 matrix << endl;
00088 matrix << endl;
00089 matrix << "# type: matrix" << endl;
00090 matrix << "# rows: 40" << endl;
00091 matrix << "# columns: 5" << endl;
00092
00093 matrix << "0.0 3.14159 0.740055 2.633909 0.8";
00094 matrix << "0.86 2.997077 0.753637 2.178169 0.8";
00095 matrix << "0.86 2.879267 0.775569 1.856744 0.8";
00096 matrix << "0.86 2.761458 0.798336 1.617919 0.8";
00097 matrix << "0.86 2.643648 0.819169 1.433496 0.8";
00098 matrix << "0.86 2.525839 0.837158 1.286795 0.8";
00099 matrix << "0.8 2.964876 0.852598 1.167321 0.8";
00100 matrix << "0.86 2.408029 0.865429 1.068141 0.8";
00101 matrix << "0.86 2.29022 0.876208 0.984489 0.8";
00102 matrix << "0.86 2.17241 0.885329 0.912985 0.8";
00103 matrix << "0.86 2.054601 0.893116 0.851162 0.8";
00104 matrix << "0.86 1.936791 0.899823 0.797179 0.8";
00105 matrix << "0.8 2.788161 0.906118 0.749633 0.8";
00106 matrix << "0.86 1.818981 0.911236 0.70744 0.8";
00107 matrix << "0.86 1.701172 0.915747 0.669742 0.8";
00108 matrix << "0.86 1.583362 0.919753 0.635858 0.8";
00109 matrix << "0.86 1.465552 0.923335 0.605237 0.8";
00110 matrix << "0.86 1.347743 0.926565 0.57743 0.8";
00111 matrix << "0.8 2.611447 0.929914 0.552065 0.8";
00112 matrix << "0.86 1.229933 0.932576 0.528834 0.8";
00113 matrix << "0.86 1.112123 0.944589 0.487783 0.75";
00114 matrix << "0.86 0.994314 0.957206 0.452645 0.660714";
00115 matrix << "0.86 0.876504 0.956548 0.42223 0.672143";
00116 matrix << "0.86 0.758694 0.956653 0.395644 0.682143";
00117 matrix << "0.8 2.434732 0.956518 0.372208 0.690966";
00118 matrix << "0.86 0.640885 0.956676 0.351393 0.69881";
00119 matrix << "0.86 0.523075 0.956741 0.316044 0.712143";
00120 matrix << "0.8 2.258018 0.956481 0.287157 0.723052";
00121 matrix << "0.8 2.081304 0.956445 0.263108 0.732143";
00122 matrix << "0.8 1.904589 0.956481 0.242776 0.739835";
00123 matrix << "0.86 0.405265 0.958259 0.217558 0.749384";
00124 matrix << "0.8 1.727875 0.963083 0.197086 0.757143";
00125 matrix << "0.8 1.55116 0.969757 0.175115 0.769048";
00126 matrix << "0.8 1.374446 0.97003 0.153697 0.780662";
00127 matrix << "0.8 1.197732 0.970382 0.134026 0.791337";
00128 matrix << "0.8 1.021017 0.970721 0.118819 0.799596";
00129 matrix << "0.8 1.5 0.970985 0.106711 0.8";
00130 matrix << "0.8 1.2 0.971222 0.096843 0.8";
00131 matrix << "0.8 1.0 0.97144 0.088645 0.8";
00132 matrix << "0.8 0.9 0.971645 0.081727 0.8";
00133 matrix << endl;
00134 matrix << "# Size = 200" << endl;
00135 matrix << "# MARSYAS realvec" << endl;
00136 matrix >> FilterBankRThetaCoeffs;
00137
00138 realvec a,b,c;
00139
00140
00141 a.create(3);
00142 b.create(3);
00143 a(0) = PreemphasisRThetaCoeffs(0,0)*PreemphasisRThetaCoeffs(0,0);
00144 a(1) = -2.0f*PreemphasisRThetaCoeffs(0,0)*cos(PreemphasisRThetaCoeffs(0,1));
00145 a(2) = 1.0f;
00146 b(0) = PreemphasisRThetaCoeffs(1,0)*PreemphasisRThetaCoeffs(1,0);
00147 b(1) = -2.0f*PreemphasisRThetaCoeffs(1,0)*cos(PreemphasisRThetaCoeffs(1,1));
00148 b(2) = 1.0f;
00149 polyConv(a, b, a);
00150 b(0) = PreemphasisRThetaCoeffs(2,0)*PreemphasisRThetaCoeffs(2,0);
00151 b(1) = -2.0f*PreemphasisRThetaCoeffs(2,0)*cos(PreemphasisRThetaCoeffs(2,1));
00152 b(2) = 1.0f;
00153 polyConv(a, b, a);
00154 b(0) = PreemphasisRThetaCoeffs(3,0)*PreemphasisRThetaCoeffs(3,0);
00155 b(1) = -2.0f*PreemphasisRThetaCoeffs(3,0)*cos(PreemphasisRThetaCoeffs(3,1));
00156 b(2) = 1.0f;
00157 polyConv(a, b, c);
00158 SeneffPreemphasisCoeffs.create(c.getSize());
00159
00160 for (mrs_natural i = 0; i < c.getSize(); ++i)
00161 SeneffPreemphasisCoeffs(i) = c(c.getSize() - i - 1);
00162
00163
00164 channels = FilterBankRThetaCoeffs.getRows();
00165 SeneffFilterBankCoeffs.create(channels, 5);
00166 mrs_real sum;
00167 for (mrs_natural i = 0; i < channels; ++i) {
00168 SeneffFilterBankCoeffs(i,0) = 1.0f;
00169 SeneffFilterBankCoeffs(i,1) = -2.0f*FilterBankRThetaCoeffs(i,0)*cos(FilterBankRThetaCoeffs(i,1));
00170 SeneffFilterBankCoeffs(i,2) = FilterBankRThetaCoeffs(i,0)*FilterBankRThetaCoeffs(i,0);
00171 sum = SeneffFilterBankCoeffs(i,0) + SeneffFilterBankCoeffs(i,1) + SeneffFilterBankCoeffs(i,2);
00172 SeneffFilterBankCoeffs(i,0) /= sum;
00173 SeneffFilterBankCoeffs(i,1) /= sum;
00174 SeneffFilterBankCoeffs(i,2) /= sum;
00175 }
00176
00177
00178 SeneffForwardCoeffs.create(mrs_natural(5), static_cast<mrs_natural>(channels));
00179 SeneffBackwardCoeffs.create(mrs_natural(5), static_cast<mrs_natural>(channels));
00180 a.create(3),b.create(3);
00181 for (mrs_natural j = 0; j < channels; j++){
00182 a(0) = FilterBankRThetaCoeffs(j,4)*FilterBankRThetaCoeffs(j,4);
00183 a(1) = -2.0f*FilterBankRThetaCoeffs(j,4)*cos(FilterBankRThetaCoeffs(j,3)/2);
00184 a(2) = 1.0f;
00185 polyConv(a, a, c);
00186 for (mrs_natural i = 0; i < 5; ++i) SeneffForwardCoeffs(i,j) = c(5 - i - 1);
00187 b(0) = FilterBankRThetaCoeffs(j,2)*FilterBankRThetaCoeffs(j,2);
00188 b(1) = -2.0f*FilterBankRThetaCoeffs(j,2)*cos(FilterBankRThetaCoeffs(j,3));
00189 b(2) = 1.0f;
00190 polyConv(b, b, c);
00191 for (mrs_natural i = 0; i < 5; ++i) SeneffBackwardCoeffs(i,j) = c(5 - i - 1);
00192 }
00193
00194
00195 SeneffPreemphasisFilter = new Filter("SeneffPreemphasisFilter");
00196 a.create(1);
00197 a(0) = 1.0f;
00198 SeneffPreemphasisFilter->setctrl("mrs_realvec/ncoeffs", SeneffPreemphasisCoeffs);
00199 SeneffPreemphasisFilter->setctrl("mrs_realvec/dcoeffs", a);
00200
00201
00202 SeneffFilterBank = new Cascade("SeneffFilterBank");
00203 Filter* filter;
00204 a.create(3);
00205 b.create(3);
00206 for (mrs_natural i = 0; i < channels; ++i) {
00207 name.clear();
00208 name.str("");
00209 name << "filter_" << i;
00210 filter = new Filter(name.str());
00211 b(0) = SeneffFilterBankCoeffs(i,0);
00212 b(1) = SeneffFilterBankCoeffs(i,1);
00213 b(2) = SeneffFilterBankCoeffs(i,2);
00214 a(0) = 1.0f;
00215 a(1) = SeneffFilterBankCoeffs(i,3);
00216 a(2) = SeneffFilterBankCoeffs(i,4);
00217 filter->setctrl("mrs_realvec/ncoeffs", b);
00218 filter->setctrl("mrs_realvec/dcoeffs", a);
00219 SeneffFilterBank->addMarSystem(filter);
00220 }
00221
00222
00223 resonatorFilter = new Parallel("resonatorFilter");
00224 a.create(5);
00225 b.create(5);
00226 for (mrs_natural i = 0; i < channels; ++i) {
00227 name.clear();
00228 name.str("");
00229 name << "filter_" << i;
00230 filter = new Filter(name.str());
00231 for (mrs_natural j = 0; j < 5; j++) b(j) = SeneffForwardCoeffs(j,i);
00232 for (mrs_natural j = 0; j < 5; j++) a(j) = SeneffBackwardCoeffs(j,i);
00233 filter->setctrl("mrs_realvec/ncoeffs", b);
00234 filter->setctrl("mrs_realvec/dcoeffs", a);
00235 resonatorFilter->addMarSystem(filter);
00236 }
00237
00238
00239 realvec impulse;
00240 impulse.create(mrs_natural(1), mrs_natural(256));
00241 impulse(0) = 1.0f;
00242 realvec y0;
00243 y0.create(impulse.getRows(), impulse.getCols());
00244 SeneffPreemphasisFilter->setctrl("mrs_natural/inSamples", impulse.getCols());
00245 SeneffPreemphasisFilter->setctrl("mrs_natural/inObservations", impulse.getRows());
00246 SeneffPreemphasisFilter->update();
00247 SeneffPreemphasisFilter->process(impulse, y0);
00248
00249
00250 realvec y1;
00251 y1.create(y0.getRows()*channels, y0.getCols());
00252 SeneffFilterBank->setctrl("Filter/filter_0/mrs_natural/inSamples", y0.getCols());
00253 SeneffFilterBank->setctrl("Filter/filter_0/mrs_natural/inObservations", y0.getRows());
00254 SeneffFilterBank->update();
00255 SeneffFilterBank->process(y0, y1);
00256
00257
00258 y.create(y1.getRows(), y1.getCols());
00259 resonatorFilter->setctrl("Filter/filter_0/mrs_natural/inSamples", y1.getCols());
00260 for (mrs_natural i = 0; i < channels; ++i) {
00261 name.clear();
00262 name.str("");
00263 name << "Filter/" << "filter_" << i << "/mrs_natural/inObservations";
00264 resonatorFilter->setctrl(name.str(), y0.getRows());
00265 }
00266 resonatorFilter->update();
00267 resonatorFilter->process(y1, y);
00268
00269
00270 realvec state;
00271 state.create(SeneffPreemphasisFilter->getctrl("mrs_realvec/state")->to<mrs_realvec>().getRows(),SeneffPreemphasisFilter->getctrl("mrs_realvec/state")->to<mrs_realvec>().getCols());
00272 SeneffPreemphasisFilter->setctrl("mrs_natural/stateUpdate", mrs_natural(1));
00273 SeneffPreemphasisFilter->updControl("mrs_realvec/state", state);
00274 SeneffPreemphasisFilter->setctrl("mrs_natural/stateUpdate", mrs_natural(0));
00275
00276 state.create(SeneffFilterBank->getctrl("Filter/filter_0/mrs_realvec/state")->to<mrs_realvec>().getRows(),SeneffFilterBank->getctrl("Filter/filter_0/mrs_realvec/state")->to<mrs_realvec>().getCols());
00277 for (mrs_natural i = 0; i < channels; ++i) {
00278 name.clear();
00279 name.str("");
00280 name << "Filter/" << "filter_" << i << "/mrs_natural/stateUpdate";
00281 SeneffFilterBank->setctrl(name.str(), mrs_natural(1));
00282 name.clear();
00283 name.str("");
00284 name << "Filter/" << "filter_" << i << "/mrs_realvec/state";
00285 SeneffFilterBank->updControl(name.str(), state);
00286 name.clear();
00287 name.str("");
00288 name << "Filter/" << "filter_" << i << "/mrs_natural/stateUpdate";
00289 SeneffFilterBank->setctrl(name.str(), mrs_natural(0));
00290 }
00291
00292 state.create(resonatorFilter->getctrl("Filter/filter_0/mrs_realvec/state")->to<mrs_realvec>().getRows(),resonatorFilter->getctrl("Filter/filter_0/mrs_realvec/state")->to<mrs_realvec>().getCols());
00293 for (mrs_natural i = 0; i < channels; ++i) {
00294 name.clear();
00295 name.str("");
00296 name << "Filter/" << "filter_" << i << "/mrs_natural/stateUpdate";
00297 resonatorFilter->setctrl(name.str(), mrs_natural(1));
00298 name.clear();
00299 name.str("");
00300 name << "Filter/" << "filter_" << i << "/mrs_realvec/state";
00301 resonatorFilter->updControl(name.str(), state);
00302 name.clear();
00303 name.str("");
00304 name << "Filter/" << "filter_" << i << "/mrs_natural/stateUpdate";
00305 resonatorFilter->setctrl(name.str(), mrs_natural(0));
00306 }
00307
00308
00309 hwrA = 10.0f;
00310 hwrB = 65.0f;
00311 hwrG = 2.35f;
00312
00313 Cn.create(channels);
00314
00315
00316 lpAlpha = 0.209611f;
00317 lowPassFilter = new Filter("lowPassFilter");
00318 a.create(2);
00319 a(0) = -lpAlpha;
00320 a(1) = 1.0f;
00321 polyConv(a, a, a);
00322 polyConv(a, a, a);
00323 polyFlip(a);
00324 b.create(1);
00325 b(0) = a.sum();
00326 lowPassFilter->setctrl("mrs_realvec/ncoeffs", b);
00327 lowPassFilter->setctrl("mrs_realvec/dcoeffs", a);
00328
00329
00330 initial_yn = (mrs_real)0.23071276;
00331 alpha_agc = (mrs_real)0.979382181;
00332 kagc = (mrs_real)0.002;
00333 AGCfilter = new Filter("AGCfilter");
00334 a.create(1);
00335 a(0) = alpha_agc;
00336 b.create(2);
00337 b(1) = 1.0f - alpha_agc;
00338 AGCfilter->setctrl("mrs_realvec/ncoeffs", b);
00339 AGCfilter->setctrl("mrs_realvec/dcoeffs", a);
00340 state.create(channels, mrs_natural(1));
00341 state.setval(initial_yn);
00342 AGCfilter->setctrl("mrs_natural/inObservations", channels);
00343 AGCfilter->setctrl("mrs_natural/stateUpdate", mrs_natural(1));
00344 AGCfilter->updControl("mrs_realvec/state", state);
00345 AGCfilter->setctrl("mrs_natural/stateUpdate", mrs_natural(0));
00346
00347 firstUpdate = false;
00348 }
00349
00350
00351
00352 if (fs != getctrl("mrs_real/israte")->to<mrs_real>()) {
00353 fs = getctrl("mrs_real/israte")->to<mrs_real>();
00354 fft fft;
00355 realvec Y(y.getCols());
00356 mrs_real *Yd = Y.getData();
00357 mrs_real abs2(1.0f),maxAbs2(0.0f);
00358 mrs_real gain;
00359 mrs_real rolloff;
00360 SeneffForwardCoeffsNormalized.create(SeneffForwardCoeffs.getRows(), SeneffForwardCoeffs.getCols());
00361 for (mrs_natural i = 0; i < channels; ++i) {
00362 for (mrs_natural j = 0; j < Y.getCols(); j++) Y(j) = y(i,j);
00363 fft.rfft(Yd, Y.getCols()/2, FFT_FORWARD);
00364 maxAbs2 = Y(0)*Y(0);
00365 for (mrs_natural j = 1; j < y.getCols()/2; j++) if ((abs2 = Y(2*j)*Y(2*j) + Y(2*j+1)*Y(2*j+1)) > maxAbs2) maxAbs2 = abs2;
00366 gain = 1/(y.getCols()*sqrt(maxAbs2));
00367 rolloff = min((mrs_real)((FilterBankRThetaCoeffs(i,3)/PI*fs/2)/1600),(mrs_real)1.0);
00368 for (mrs_natural j = 0; j < SeneffForwardCoeffsNormalized.getRows(); j++) SeneffForwardCoeffsNormalized(j,i) = SeneffForwardCoeffs(j,i)*gain*rolloff;
00369 }
00370
00371 realvec b(5);
00372 for (mrs_natural i = 0; i < channels; ++i) {
00373 name.clear();
00374 name.str("");
00375 name << "Filter/" << "filter_" << i << "/mrs_realvec/ncoeffs";
00376 for (mrs_natural j = 0; j < 5; j++) b(j) = SeneffForwardCoeffsNormalized(j,i);
00377 resonatorFilter->setctrl(name.str(), b);
00378 }
00379 resonatorFilter->update();
00380
00381 Tua = (mrs_real)(58.3333/fs);
00382 Tub = (mrs_real)(8.3333/fs);
00383 }
00384
00385
00386
00387 SeneffPreemphasisFilter->setctrl("mrs_natural/inSamples", getctrl("mrs_natural/inSamples"));
00388 SeneffPreemphasisFilter->setctrl("mrs_natural/inObservations", getctrl("mrs_natural/inObservations"));
00389 SeneffPreemphasisFilter->setctrl("mrs_real/israte", getctrl("mrs_real/israte"));
00390 SeneffPreemphasisFilter->update();
00391 if ((int)slice_0.getSize() != SeneffPreemphasisFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>() * SeneffPreemphasisFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) {
00392 slice_0.create(SeneffPreemphasisFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), SeneffPreemphasisFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00393 }
00394
00395
00396 SeneffFilterBank->setctrl("Filter/filter_0/mrs_natural/inSamples", SeneffPreemphasisFilter->getctrl("mrs_natural/onSamples"));
00397 SeneffFilterBank->setctrl("Filter/filter_0/mrs_natural/inObservations", SeneffPreemphasisFilter->getctrl("mrs_natural/onObservations"));
00398 SeneffFilterBank->setctrl("Filter/filter_0/mrs_real/israte", SeneffPreemphasisFilter->getctrl("mrs_real/osrate"));
00399 SeneffFilterBank->update();
00400 if ((int)slice_1.getSize() != SeneffFilterBank->getctrl("mrs_natural/onObservations")->to<mrs_natural>() * SeneffFilterBank->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) {
00401 slice_1.create(SeneffFilterBank->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), SeneffFilterBank->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00402 }
00403
00404
00405 resonatorFilter->setctrl("Filter/filter_0/mrs_natural/inSamples", SeneffFilterBank->getctrl("mrs_natural/onSamples"));
00406 for (mrs_natural i = 0; i < channels; ++i) {
00407 name.clear();
00408 name.str("");
00409 name << "Filter/" << "filter_" << i << "/mrs_natural/inObservations";
00410 resonatorFilter->setctrl(name.str(), SeneffFilterBank->getctrl("Filter/filter_0/mrs_natural/onObservations"));
00411 }
00412 resonatorFilter->setctrl("Filter/filter_0/mrs_real/israte", SeneffFilterBank->getctrl("mrs_real/osrate"));
00413 resonatorFilter->update();
00414 if ((int)slice_2.getSize() != resonatorFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>() * resonatorFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) {
00415 slice_2.create(resonatorFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), resonatorFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00416 }
00417
00418
00419 lowPassFilter->setctrl("mrs_natural/inSamples", resonatorFilter->getctrl("mrs_natural/onSamples"));
00420 lowPassFilter->setctrl("mrs_natural/inObservations", resonatorFilter->getctrl("mrs_natural/onObservations"));
00421 lowPassFilter->setctrl("mrs_real/israte", resonatorFilter->getctrl("mrs_real/osrate"));
00422 lowPassFilter->update();
00423 if ((int)slice_3.getSize() != lowPassFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>() * lowPassFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) {
00424 slice_3.create(lowPassFilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), lowPassFilter->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00425 }
00426
00427
00428 AGCfilter->setctrl("mrs_natural/inSamples", lowPassFilter->getctrl("mrs_natural/onSamples"));
00429 AGCfilter->setctrl("mrs_natural/inObservations", lowPassFilter->getctrl("mrs_natural/onObservations"));
00430 AGCfilter->setctrl("mrs_real/israte", lowPassFilter->getctrl("mrs_real/osrate"));
00431 AGCfilter->update();
00432
00433
00434 setctrl("mrs_natural/onSamples", AGCfilter->getctrl("mrs_natural/onSamples"));
00435 setctrl("mrs_natural/onObservations", AGCfilter->getctrl("mrs_natural/onObservations")->to<mrs_natural>());
00436 setctrl("mrs_real/osrate", AGCfilter->getctrl("mrs_real/osrate"));
00437 }
00438
00439 void
00440 SeneffEar::polyConv(realvec& a, realvec& b, realvec& c)
00441 {
00442 mrs_natural la(a.getSize());
00443 mrs_natural lb(b.getSize());
00444 mrs_natural n = la + lb - 1;
00445
00446 realvec ta(a); ta.stretch(n);
00447 realvec tb(b); tb.stretch(n);
00448 realvec tc; tc.create(n);
00449
00450 for (mrs_natural k = 0; k < n; k++){
00451 for (mrs_natural i = 0; i <= k; ++i){
00452 tc(k) += ta(i)*tb(k-i);
00453 }
00454 }
00455 if ((mrs_natural)c.getSize() != n) c.create(n);
00456 c = tc;
00457 }
00458
00459 void
00460 SeneffEar::polyFlip(realvec& a)
00461 {
00462 mrs_natural la(a.getSize());
00463 realvec ta(a);
00464
00465 for (mrs_natural i = 0; i < la; ++i){
00466 a(i) = ta(la - i - 1);
00467 }
00468 }
00469
00470
00471 void
00472 SeneffEar::myProcess(realvec& in, realvec& out)
00473 {
00474 checkFlow(in, out);
00475
00476 if(getctrl("mrs_bool/mute")->to<mrs_bool>()) return;
00477
00478 mrs_natural s = 0;
00479 stage = getctrl("mrs_natural/stage")->to<mrs_natural>();
00480
00481 SeneffPreemphasisFilter->process(in, slice_0);
00482 SeneffFilterBank->process(slice_0, slice_1);
00483 if (s++ == stage) {out = slice_1; return;}
00484 resonatorFilter->process(slice_1, slice_2);
00485 if (s++ == stage) {out = slice_2; return;}
00486
00487 for (mrs_natural i = 0; i < slice_2.getRows(); ++i) {
00488 for (mrs_natural j = 0; j < slice_2.getCols(); j++) {
00489 slice_2(i,j) = hwrA*atan(hwrB*max((mrs_real)0.0,slice_2(i,j))) + exp(hwrA*hwrB*min((mrs_real)0.0,slice_2(i,j)));
00490 }
00491 }
00492
00493 mrs_real flow;
00494 for (mrs_natural j = 0; j < slice_2.getCols(); j++) {
00495 for (mrs_natural i = 0; i < slice_2.getRows(); ++i) {
00496 flow = max((mrs_real)0.0,Tua*(slice_2(i,j)-Cn(i)));
00497 Cn(i) = Cn(i) + flow - Tub*Cn(i);
00498 slice_2(i,j) = flow;
00499 }
00500 }
00501 if (s++ == stage) {out = slice_2; return;}
00502
00503 lowPassFilter->process(slice_2, slice_3);
00504 if (s++ == stage) {out = slice_3; return;}
00505
00506 AGCfilter->process(slice_3, out);
00507 for (mrs_natural i = 0; i < out.getRows(); ++i) {
00508 for (mrs_natural j = 0; j < out.getCols(); j++) {
00509 out(i,j) = slice_3(i,j)/(1.0f + kagc*out(i,j));
00510 }
00511 }
00512 }