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 }
|