annotate cpp/chourdakisreiss2016cpp/Parameter.cpp @ 2:c87a9505f294 tip

Added LICENSE for code, removed .wav files
author Emmanouil Theofanis Chourdakis <e.t.chourdakis@qmul.ac.uk>
date Sat, 30 Sep 2017 13:25:50 +0100
parents 144fbd1d29c3
children
rev   line source
e@1 1 /*
e@1 2 * Parameter.cpp
e@1 3 *
e@1 4 * Created on: Dec 14, 2016
e@1 5 * Author: mmxgn
e@1 6 */
e@1 7
e@1 8 #include <cmath>
e@1 9 #include "Parameter.h"
e@1 10 //#include "csv.h"
e@1 11
e@1 12
e@1 13 /*
e@1 14 * Given a k, return g_k and d_k based on
e@1 15 * g_1 and d_1 respectively.
e@1 16 *
e@1 17 */
e@1 18
e@1 19 #define GK(k) powf(G1, powf(1.5, 1-k))
e@1 20 #define _GK(k) powf(_G1, powf(1.5, 1-k))
e@1 21
e@1 22 #define DK(k) (D1*powf(1.5, 1-k))
e@1 23 #define _DK(k) (_D1*powf(1.5, 1-k))
e@1 24
e@1 25 /*
e@1 26 * The parameter class
e@1 27 */
e@1 28
e@1 29 Parameter::Parameter(double _SR,
e@1 30 double _D1,
e@1 31 double _DA,
e@1 32 double _G1,
e@1 33 double _GC,
e@1 34 double _G,
e@1 35 double _T60,
e@1 36 double _ED,
e@1 37 double _C,
e@1 38 double _TC,
e@1 39 double _SC)
e@1 40 :
e@1 41 D1(_D1),
e@1 42 DA(_DA),
e@1 43 G1(_G1),
e@1 44 GC(_GC),
e@1 45 G(_G),
e@1 46 T60(_T60),
e@1 47 ED(_ED),
e@1 48 C(_C),
e@1 49 TC(_TC),
e@1 50 SC(_SC),
e@1 51 SC_MAX(_SR/4.0),
e@1 52 SampleRate(_SR)
e@1 53 {
e@1 54 // pass
e@1 55 }
e@1 56
e@1 57 double Parameter::getC() const {
e@1 58 return C;
e@1 59 }
e@1 60
e@1 61 void Parameter::setC(double c) {
e@1 62 C = c;
e@1 63 }
e@1 64
e@1 65 double Parameter::getD1() const {
e@1 66 return D1;
e@1 67 }
e@1 68
e@1 69 void Parameter::setD1(double d1) {
e@1 70 /* Dependency for:
e@1 71 * T60, ED, TC
e@1 72 */
e@1 73
e@1 74 T60 = compute_T60(d1, G1, GC, G);
e@1 75 ED = compute_ED(d1, DA);
e@1 76 TC = compute_TC(d1, G1, DA);
e@1 77
e@1 78 }
e@1 79
e@1 80 double Parameter::getDa() const {
e@1 81 return DA;
e@1 82
e@1 83 }
e@1 84
e@1 85 void Parameter::setDa(double da) {
e@1 86 /* Dependency for:
e@1 87 * ED, TC
e@1 88 */
e@1 89
e@1 90 ED = compute_ED(D1, da);
e@1 91 TC = compute_TC(D1, G1, da);
e@1 92
e@1 93 }
e@1 94
e@1 95 double Parameter::getEd() const {
e@1 96 return ED;
e@1 97 }
e@1 98
e@1 99 void Parameter::setEd(double ed) {
e@1 100 matrix <double,5,1> est_param = inverse_mapping(T60, ed, C, TC, SC, SampleRate,G1);
e@1 101 D1 = est_param(0);
e@1 102 DA = est_param(1);
e@1 103 G1 = est_param(2);
e@1 104 GC = est_param(3);
e@1 105 G = est_param(4);
e@1 106 T60 = compute_T60(D1, G1, GC, G);
e@1 107 ED = compute_ED(D1, DA);
e@1 108 C = compute_C(G1, GC, G);
e@1 109 TC = compute_TC(D1, G1, DA);
e@1 110 SC = compute_SC(GC, SampleRate);
e@1 111 }
e@1 112
e@1 113 double Parameter::getG() const {
e@1 114 return G;
e@1 115 }
e@1 116
e@1 117 void Parameter::setG(double g) {
e@1 118 /*
e@1 119 * Dependency for:
e@1 120 * T60, C
e@1 121 */
e@1 122
e@1 123 T60 = compute_T60(D1, G1, GC, g);
e@1 124 C = compute_C(G1, GC, g);
e@1 125
e@1 126 }
e@1 127
e@1 128 double Parameter::getG1() const {
e@1 129 return G1;
e@1 130 }
e@1 131
e@1 132 void Parameter::setG1(double g1) {
e@1 133 /*
e@1 134 * Dependency for:
e@1 135 * T60, C, TC
e@1 136 */
e@1 137
e@1 138 T60 = compute_T60(D1, g1, GC, G);
e@1 139 C = compute_C(g1, GC, G);
e@1 140 TC = compute_TC(D1, g1, DA);
e@1 141
e@1 142 }
e@1 143
e@1 144 double Parameter::getGc() const {
e@1 145 return GC;
e@1 146 }
e@1 147
e@1 148 void Parameter::setGc(double gc) {
e@1 149 /*
e@1 150 * Dependency for:
e@1 151 * SC
e@1 152 */
e@1 153
e@1 154 SC = compute_SC(gc, SampleRate);
e@1 155 }
e@1 156
e@1 157 double Parameter::getSampleRate() const {
e@1 158 return SampleRate;
e@1 159 }
e@1 160
e@1 161 void Parameter::setSampleRate(double sampleRate) {
e@1 162 SampleRate = sampleRate;
e@1 163 set_low_and_compute(D1, DA, G1, GC, G);
e@1 164 matrix <double,5,1> est_param = inverse_mapping(T60, ED, C, TC, SC, SampleRate,G1);
e@1 165 D1 = est_param(0);
e@1 166 DA = est_param(1);
e@1 167 G1 = est_param(2);
e@1 168 GC = est_param(3);
e@1 169 G = est_param(4);
e@1 170 T60 = compute_T60(D1, G1, GC, G);
e@1 171 ED = compute_ED(D1, DA);
e@1 172 C = compute_C(G1, GC, G);
e@1 173 TC = compute_TC(D1, G1, DA);
e@1 174 SC = compute_SC(GC, SampleRate);
e@1 175 }
e@1 176
e@1 177 double Parameter::getSc() const {
e@1 178 return SC;
e@1 179 }
e@1 180
e@1 181 void Parameter::setSc(double sc) {
e@1 182 matrix <double,5,1> est_param = inverse_mapping(T60, ED, C, TC, sc, SampleRate,G1);
e@1 183 D1 = est_param(0);
e@1 184 DA = est_param(1);
e@1 185 G1 = est_param(2);
e@1 186 GC = est_param(3);
e@1 187 G = est_param(4);
e@1 188 T60 = compute_T60(D1, G1, GC, G);
e@1 189 ED = compute_ED(D1, DA);
e@1 190 C = compute_C(G1, GC, G);
e@1 191 TC = compute_TC(D1, G1, DA);
e@1 192 SC = compute_SC(GC, SampleRate);
e@1 193 }
e@1 194
e@1 195 double Parameter::getT60() const {
e@1 196 return T60;
e@1 197 }
e@1 198
e@1 199 void Parameter::setT60(double t60) {
e@1 200 matrix <double,5,1> est_param = inverse_mapping(t60, ED, C, TC, SC, SampleRate,G1);
e@1 201 D1 = est_param(0);
e@1 202 DA = est_param(1);
e@1 203 G1 = est_param(2);
e@1 204 GC = est_param(3);
e@1 205 G = est_param(4);
e@1 206 T60 = compute_T60(D1, G1, GC, G);
e@1 207 ED = compute_ED(D1, DA);
e@1 208 C = compute_C(G1, GC, G);
e@1 209 TC = compute_TC(D1, G1, DA);
e@1 210 SC = compute_SC(GC, SampleRate);
e@1 211 }
e@1 212
e@1 213 double Parameter::getTc() const {
e@1 214 return TC;
e@1 215 }
e@1 216
e@1 217 void Parameter::setTc(double tc) {
e@1 218 matrix <double,5,1> est_param = inverse_mapping(T60, ED, C, tc, SC, SampleRate,G1);
e@1 219 D1 = est_param(0);
e@1 220 DA = est_param(1);
e@1 221 G1 = est_param(2);
e@1 222 GC = est_param(3);
e@1 223 G = est_param(4);
e@1 224 T60 = compute_T60(D1, G1, GC, G);
e@1 225 ED = compute_ED(D1, DA);
e@1 226 C = compute_C(G1, GC, G);
e@1 227 TC = compute_TC(D1, G1, DA);
e@1 228 SC = compute_SC(GC, SampleRate);
e@1 229 }
e@1 230
e@1 231 Parameter::~Parameter() {
e@1 232 // TODO Auto-generated destructor stub
e@1 233 }
e@1 234
e@1 235 std::ostream& operator<<(std::ostream &s, const Parameter &p) {
e@1 236 return s << "Parameter({High:<" <<
e@1 237 p.T60 << ", " <<
e@1 238 p.ED << ", " <<
e@1 239 p.C << ", " <<
e@1 240 p.TC << ", " <<
e@1 241 p.SC << ">}, " <<
e@1 242 "{Low: <" <<
e@1 243 p.D1 << ", " <<
e@1 244 p.DA << ", " <<
e@1 245 p.G1 << ", " <<
e@1 246 p.GC << ", " <<
e@1 247 p.G << ">}).";
e@1 248
e@1 249 }
e@1 250
e@1 251 int Parameter::set_low_and_compute(double D1, double DA, double G1, double GC,
e@1 252 double G) {
e@1 253
e@1 254 /* Temporary values */
e@1 255
e@1 256 double _T60, _ED, _C, _TC, _SC;
e@1 257
e@1 258 _T60 = compute_T60(D1, G1, GC, G);
e@1 259 if (_T60 < T60_MIN || _T60 > T60_MAX)
e@1 260 return -1;
e@1 261
e@1 262 _ED = compute_ED(D1, DA);
e@1 263 if (_ED < ED_MIN || _ED > ED_MAX)
e@1 264 return -1;
e@1 265
e@1 266 _C = compute_C(G1, GC, G);
e@1 267
e@1 268 if (_C < C_MIN || _C > C_MAX)
e@1 269 return -1;
e@1 270
e@1 271 _TC = compute_TC(D1, G1, DA);
e@1 272
e@1 273 if (_TC < TC_MIN || _TC > TC_MAX)
e@1 274 return -1;
e@1 275
e@1 276 _SC = compute_SC(GC, SampleRate);
e@1 277
e@1 278 if (_SC < SC_MIN || _SC > SC_MAX)
e@1 279 return -1;
e@1 280
e@1 281 T60 = _T60;
e@1 282 ED = _ED;
e@1 283 C = _C;
e@1 284 TC = _TC;
e@1 285 SC = _SC;
e@1 286
e@1 287 return 0;
e@1 288
e@1 289 }
e@1 290
e@1 291 double Parameter::compute_T60(double _D1, double _G1, double _GC, double _G) {
e@1 292 return -_D1/log(_G1)*(log(_G)+log(1-_GC)+log(GA)+3*log(10));
e@1 293 }
e@1 294
e@1 295 double Parameter::compute_ED(double _D1, double _DA) {
e@1 296 return 2.078125/_D1/_DA;
e@1 297 }
e@1 298
e@1 299 double Parameter::compute_C(double _G1, double _GC, double _G) {
e@1 300 double sum1 = 0;
e@1 301 for (int k=1; k<7; k++){
e@1 302 sum1 += powf(_G1, 2*powf(1.5, 1-k))/(1-powf(_G1, 2*powf(1.5, 1-k)));
e@1 303 }
e@1 304 return -10*log10(_G*_G*(1-_GC)/(1+_GC)*sum1);
e@1 305 }
e@1 306
e@1 307 double Parameter::compute_TC(double _D1, double _G1, double _DA) {
e@1 308 double sum1 = 0, sum2 = 0, s1 = 0;
e@1 309 for (int k=1; k<7; k++){
e@1 310 s1 = powf(_GK(k), 2.0)/(1-powf(_GK(k), 2.0));
e@1 311 sum2 += s1;
e@1 312 sum1 += _DK(k)*s1/(1-powf(_GK(k),2.0));
e@1 313 }
e@1 314
e@1 315 return sum1/sum2 + _DA;
e@1 316 }
e@1 317
e@1 318 double Parameter::compute_SC(double _GC, double _SR) {
e@1 319 double sum1 = 0, sum2 = 0;
e@1 320
e@1 321 for (int k=0; k < int(_SR/2.0); k++){
e@1 322 double lut = 1.0-2.0*_GC*cos(2.0*M_PI*k/_SR)+_GC*_GC;
e@1 323 sum1 += k/lut;
e@1 324 sum2 += 1/lut;
e@1 325 }
e@1 326
e@1 327 return sum1/sum2;
e@1 328 }
e@1 329
e@1 330 int Parameter::get_low_and_computer() {
e@1 331 return 0;
e@1 332 }
e@1 333
e@1 334 int Parameter::set_high_and_compute(double T60, double ED, double C, double TC,
e@1 335 double SC) {
e@1 336 return 0;
e@1 337 }
e@1 338
e@1 339 double Parameter::TC_G1_D1_ED(double _D1, double _G1, double _ED, double t) {
e@1 340 double sum1 = 0, sum2 = 0;
e@1 341
e@1 342 for (int k=1; k<7; k++){
e@1 343 sum1 += powf(1.5, -k+1)*_D1*
e@1 344 powf(_G1, 2*powf(1.5, -k+1))/
e@1 345 powf((-powf(_G1, 2*powf(1.5, -k+1))+1),2);
e@1 346 sum2 += powf(_G1,2*powf(1.5,-k+1))/
e@1 347 (-powf(_G1, 2*powf(1.5,-k+1))+1);
e@1 348 }
e@1 349
e@1 350 return sum1/sum2 + 20.78125*t/(_ED*_D1);
e@1 351 }
e@1 352
e@1 353 double Parameter::T60_D1_G1_C(double _D1, double _G1, double _GC, double _C) {
e@1 354 double sum1 = 0;
e@1 355
e@1 356 for (int k=1; k<7; k++){
e@1 357 sum1 += powf(_G1, 2*powf(1.5, 1-k))/(1-powf(_G1,2*powf(1.5,1-k)));
e@1 358 }
e@1 359
e@1 360 return _D1*log(0.001/GA*exp(_C*log(10)/20)/
e@1 361 (sqrt((1+_GC)/((1-_GC)*sum1))*(1-_GC)))/log(_G1);
e@1 362 }
e@1 363
e@1 364 double Parameter::D1_G1_T60_C(double _G1, double _GC, double _T60, double _C) {
e@1 365 double sum1 = 0;
e@1 366
e@1 367 for (int k=1; k<7; k++){
e@1 368 sum1 += powf(_G1,(2*powf(1.5,1-k)))/(1-powf(_G1,2*powf(1.5,1-k)));
e@1 369 }
e@1 370
e@1 371 return _T60*log(_G1)/log(0.001/GA*exp(_C*log(10)/20)/(sqrt((1+_GC)/((1-_GC)*sum1))*(1-_GC)));
e@1 372 }
e@1 373
e@1 374 double Parameter::G_G1_C(double _G1, double _GC, double _C) {
e@1 375 double sum1 = 0;
e@1 376 for (int k=1; k<7; k++){
e@1 377 sum1 += powf(_G1, 2*powf(1.5, 1-k))/(1-powf(_G1, 2*powf(1.5, 1-k)));
e@1 378 }
e@1 379
e@1 380 return sqrt(exp(-_C/10*log(10))/(1-_GC)*(1+_GC)/sum1);
e@1 381 }
e@1 382
e@1 383 double Parameter::DA_D1_ED(double _D1, double _ED, double t) {
e@1 384 return 20.78125*t/_D1/_ED;
e@1 385 }
e@1 386
e@1 387
e@1 388 double Parameter::GC_SC(double _SC, double SR) {
e@1 389 double p0 = 1.0,
e@1 390 p1 = 1.0,
e@1 391 p2 = 1.0,
e@1 392 p3 = 1.0,
e@1 393 p4 = 1.0;
e@1 394
e@1 395 switch (int(SR)){
e@1 396 case 8000:
e@1 397 p0 = -7.545401867799958007e-15;
e@1 398 p1 = 6.605438530163032344e-11;
e@1 399 p2 = -2.339787304666883204e-07;
e@1 400 p3 = -2.380996920823082359e-04;
e@1 401 p4 = 1.003686549974644349e+00;
e@1 402 break;
e@1 403 case 11025:
e@1 404 p0 = -2.090495384250846006e-15;
e@1 405 p1 = 2.523110858472787412e-11;
e@1 406 p2 = -1.232004017234833354e-07;
e@1 407 p3 = -1.727859517219043628e-04;
e@1 408 p4 = 1.003773048218970398e+00;
e@1 409 break;
e@1 410 case 16000:
e@1 411 p0 = -4.707928872668820147e-16;
e@1 412 p1 = 8.250344830381294683e-12;
e@1 413 p2 = -5.847797160444276075e-08;
e@1 414 p3 = -1.190647306137786752e-04;
e@1 415 p4 = 1.003845141060948354e+00;
e@1 416 break;
e@1 417 case 21000:
e@1 418 p0 = -1.585759862171924958e-16;
e@1 419 p1 = 3.648228536317020713e-12;
e@1 420 p2 = -3.394367375513113085e-08;
e@1 421 p3 = -9.071942141117647239e-05;
e@1 422 p4 = 1.003883355464454619e+00;
e@1 423 break;
e@1 424 case 22050:
e@1 425 p0 = -1.304517046624577766e-16;
e@1 426 p1 = 3.151372288676199373e-12;
e@1 427 p2 = -3.078752354037690531e-08;
e@1 428 p3 = -8.639997174340922025e-05;
e@1 429 p4 = 1.003889194220798364e+00;
e@1 430 break;
e@1 431 case 32000:
e@1 432 p0 = -2.939615050414309854e-17;
e@1 433 p1 = 1.030821612883252373e-12;
e@1 434 p2 = -1.461695000370224873e-08;
e@1 435 p3 = -5.953732000720860076e-05;
e@1 436 p4 = 1.003925597252757207e+00;
e@1 437 break;
e@1 438 case 37800:
e@1 439 p0 = -1.509578131570550335e-17;
e@1 440 p1 = 6.253538622497773237e-13;
e@1 441 p2 = -1.047516110428303656e-08;
e@1 442 p3 = -5.040267062802067523e-05;
e@1 443 p4 = 1.003938012276286873e+00;
e@1 444 break;
e@1 445 case 44056:
e@1 446 p0 = -8.179918755257568798e-18;
e@1 447 p1 = 3.949666985075376660e-13;
e@1 448 p2 = -7.711241596699441441e-09;
e@1 449 p3 = -4.324592160336278773e-05;
e@1 450 p4 = 1.003947751979878067e+00;
e@1 451 break;
e@1 452 case 44100:
e@1 453 p0 = -8.147316012596786372e-18;
e@1 454 p1 = 3.937855238616550567e-13;
e@1 455 p2 = -7.695860699409773702e-09;
e@1 456 p3 = -4.320277669373632828e-05;
e@1 457 p4 = 1.003947810730627443e+00;
e@1 458 break;
e@1 459 case 47250:
e@1 460 p0 = -6.182156102335834534e-18;
e@1 461 p1 = 3.201545709180980074e-13;
e@1 462 p2 = -6.703887839395126650e-09;
e@1 463 p3 = -4.032277597168298445e-05;
e@1 464 p4 = 1.003951733380953559e+00;
e@1 465 break;
e@1 466 case 48000:
e@1 467 p0 = -5.804669671441499519e-18;
e@1 468 p1 = 3.053789928757690291e-13;
e@1 469 p2 = -6.496014866101249794e-09;
e@1 470 p3 = -3.969277247952757479e-05;
e@1 471 p4 = 1.003952591709977415e+00;
e@1 472 break;
e@1 473 case 50000:
e@1 474 p0 = -4.930039877651698485e-18;
e@1 475 p1 = 2.701762164752109105e-13;
e@1 476 p2 = -5.986696651033372113e-09;
e@1 477 p3 = -3.810515833478767255e-05;
e@1 478 p4 = 1.003954755096216900e+00;
e@1 479 break;
e@1 480 case 50400:
e@1 481 p0 = -4.775358854140600092e-18;
e@1 482 p1 = 2.637937027466497354e-13;
e@1 483 p2 = -5.892041055138477995e-09;
e@1 484 p3 = -3.780275477003837485e-05;
e@1 485 p4 = 1.003955167234265478e+00;
e@1 486 break;
e@1 487 case 88200:
e@1 488 p0 = -5.090139768480031043e-19;
e@1 489 p1 = 4.921424693356908116e-14;
e@1 490 p2 = -1.923829523675108346e-09;
e@1 491 p3 = -2.160214687014651151e-05;
e@1 492 p4 = 1.003977276279834019e+00;
e@1 493 break;
e@1 494 case 96000:
e@1 495 p0 = -3.626648836744412987e-19;
e@1 496 p1 = 3.816597595693573777e-14;
e@1 497 p2 = -1.623898000952206408e-09;
e@1 498 p3 = -1.984703070895103917e-05;
e@1 499 p4 = 1.003979674995812754e+00;
e@1 500 break;
e@1 501 case 176400:
e@1 502 p0 = -3.180720104052761169e-20;
e@1 503 p1 = 6.151207927460715513e-15;
e@1 504 p2 = -4.809399117661735116e-10;
e@1 505 p3 = -1.080127073758081756e-05;
e@1 506 p4 = 1.003992048707243789e+00;
e@1 507 break;
e@1 508 case 192000:
e@1 509 p0 = -2.266250752087159745e-20;
e@1 510 p1 = 4.770337959813220317e-15;
e@1 511 p2 = -4.059609201723455372e-10;
e@1 512 p3 = -9.923682425709201677e-06;
e@1 513 p4 = 1.003993250132436454e+00;
e@1 514 break;
e@1 515 case 352800:
e@1 516 p0 = -1.987755090799793513e-21;
e@1 517 p1 = 7.688647436953224411e-16;
e@1 518 p2 = -1.202327621003883834e-10;
e@1 519 p3 = -5.400685657755166908e-06;
e@1 520 p4 = 1.003999444875642189e+00;
e@1 521 break;
e@1 522 case 2822400:
e@1 523 p0 = -4.852498403591686415e-25;
e@1 524 p1 = 1.501626536939688520e-18;
e@1 525 p2 = -1.878606337281021417e-12;
e@1 526 p3 = -6.750912735944337505e-07;
e@1 527 p4 = 1.004005921979573834e+00;
e@1 528 break;
e@1 529 case 5644800:
e@1 530 p0 = -3.032792721276874507e-26;
e@1 531 p1 = 1.877027577372803603e-19;
e@1 532 p2 = -4.696510359527020341e-13;
e@1 533 p3 = -3.375458367765195566e-07;
e@1 534 p4 = 1.004006384824945863e+00;
e@1 535 break;
e@1 536 }
e@1 537
e@1 538 return p0*pow(_SC,4) +
e@1 539 p1*pow(_SC,3)+
e@1 540 p2*pow(_SC,2)+
e@1 541 p3*pow(_SC,1)+
e@1 542 p4;
e@1 543 }
e@1 544
e@1 545 int Parameter::get_high_and_compute() {
e@1 546 }
e@1 547
e@1 548 double Parameter::errorfunc(double _G1, double _GC, const matrix<double, 4, 1> &Target) {
e@1 549 double kT60 = Target(0),
e@1 550 kED = Target(1),
e@1 551 kC = Target(2),
e@1 552 kTC = Target(3);
e@1 553
e@1 554 double G = G_G1_C(_G1, _GC, kC);
e@1 555 double D1 = D1_G1_T60_C(_G1, _GC, kT60, kC);
e@1 556 double DA = DA_D1_ED(D1, kED, 0.1);
e@1 557 double T60est = compute_T60(D1, _G1, _GC, G);
e@1 558 double EDest = compute_ED(D1, DA);
e@1 559 double Cest = compute_C(_G1, _GC, G);
e@1 560 double TCest = compute_TC(D1, _G1, DA);
e@1 561
e@1 562 matrix <double, 4, 1> est_vec, orig_vec, err_vec;
e@1 563
e@1 564 float w0 = 1.0, w1=1.0, w2=1.0, w3=1.0; // Weights for errors.
e@1 565
e@1 566 est_vec(0) = w0*_N(T60est, T60_MIN, T60_MAX);
e@1 567 est_vec(1) = w1*_N(EDest, ED_MIN, ED_MAX);
e@1 568 est_vec(2) = w2*_N(Cest, C_MIN, C_MAX);
e@1 569 est_vec(3) = w3*_N(TCest, TC_MIN, TC_MAX);
e@1 570
e@1 571 orig_vec(0) = w0*_N(Target(0), T60_MIN, T60_MAX);
e@1 572 orig_vec(1) = w1*_N(Target(1), ED_MIN, ED_MAX);
e@1 573 orig_vec(2) = w2*_N(Target(2), C_MIN, C_MAX);
e@1 574 orig_vec(3) = w3*_N(Target(3), TC_MIN, TC_MAX);
e@1 575
e@1 576 err_vec = dlib::abs(est_vec-orig_vec);
e@1 577
e@1 578 return mean(pow(err_vec,2)) + variance(pow(err_vec,2));
e@1 579
e@1 580 }
e@1 581
e@1 582 matrix<double, 5, 1> Parameter::inverse_mapping(double _T60, double _ED,
e@1 583 double _C, double _TC, double _SC, double SampleRate, double _G1) {
e@1 584 /*
e@1 585 * _G1 is a starting point for the search of G1
e@1 586 */
e@1 587
e@1 588 matrix<double, 5, 1> result;
e@1 589 for (int i=0; i<5; i++) result(i) = 0.0;
e@1 590
e@1 591 double GC = GC_SC(_SC, SampleRate);
e@1 592 result(3) = GC;
e@1 593
e@1 594 matrix<double,1,1> starting_point;
e@1 595 matrix<double,4,1> Target;
e@1 596
e@1 597 Target(0) = _T60;
e@1 598 Target(1) = _ED;
e@1 599 Target(2) = _C;
e@1 600 Target(3) = _TC;
e@1 601
e@1 602 starting_point = _G1; // Starting point is current G1, for faster convergence
e@1 603
e@1 604 // Lambda function for objective function to minimize.
e@1 605
e@1 606 auto func = [&] (const matrix<double, 0, 1> &x) { float g1 = x(0); return errorfunc(g1, GC, Target); };
e@1 607
e@1 608 find_min_box_constrained(bfgs_search_strategy(),
e@1 609 objective_delta_stop_strategy(1e-9),
e@1 610 func, derivative(func), starting_point, G1_MIN, G1_MAX);
e@1 611
e@1 612 double G1 = starting_point(0);
e@1 613
e@1 614 result(2) = G1;
e@1 615
e@1 616 double G = G_G1_C(G1,GC,_C);
e@1 617
e@1 618
e@1 619 result(4) = G;
e@1 620
e@1 621 double D1 = D1_G1_T60_C(G1, GC, _T60, _C);
e@1 622
e@1 623
e@1 624 result(0) = D1;
e@1 625
e@1 626 double DA = DA_D1_ED(D1, _ED);
e@1 627 result(1) = DA;
e@1 628
e@1 629 return result;
e@1 630 }