comparison FChTransformF0gram.cpp @ 0:d912b9d53e50

Import original code from the downloaded VampFChTCore-v1.1beta archive
author Chris Cannam
date Tue, 02 Oct 2018 10:44:42 +0100
parents
children cdf7cb06049c
comparison
equal deleted inserted replaced
-1:000000000000 0:d912b9d53e50
1 /*
2 copyright (C) 2011 I. Irigaray, M. Rocamora
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "FChTransformF0gram.h"
19 #include "FChTransformUtils.h"
20 #include <math.h>
21 #include <float.h>
22 //#define DEBUG
23 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
24
25 FChTransformF0gram::FChTransformF0gram(float inputSampleRate) :
26 Plugin(inputSampleRate),
27 m_currentProgram("default"),
28 m_stepSize(0), // We are using 0 for step and block size to indicate "not yet set".
29 m_blockSize(0) {
30
31 printf("FUNCTION CALL: %s\n", __FUNCTION__);
32
33 m_fs = inputSampleRate;
34 // max frequency of interest (Hz)
35 m_fmax = 10000.f;
36 // warping parameters
37 m_warp_params.nsamps_twarp = 2048;
38 //m_warp_params.nsamps_twarp = 8;
39 m_warp_params.alpha_max = 4;
40 m_warp_params.num_warps = 21;
41 //m_warp_params.num_warps = 11;
42 m_warp_params.fact_over_samp = 2;
43 m_warp_params.alpha_dist = 0;
44 // f0 parameters
45 m_f0_params.f0min = 80.0;
46 m_f0_params.num_octs = 4;
47 m_f0_params.num_f0s_per_oct = 192;
48 m_f0_params.num_f0_hyps = 5;
49 m_f0_params.prefer = true;
50 m_f0_params.prefer_mean = 60;
51 m_f0_params.prefer_stdev = 18;
52 // glogs parameters
53 m_glogs_params.HP_logS = true;
54 m_glogs_params.att_subharms = 1;
55 // display parameters
56 m_f0gram_mode = true;
57
58 m_glogs_params.median_poly_coefs[0] = -0.000000058551680;
59 m_glogs_params.median_poly_coefs[1] = -0.000006945207775;
60 m_glogs_params.median_poly_coefs[2] = 0.002357223226588;
61
62 m_glogs_params.sigma_poly_coefs[0] = 0.000000092782308;
63 m_glogs_params.sigma_poly_coefs[1] = 0.000057283574898;
64 m_glogs_params.sigma_poly_coefs[2] = 0.022199903714288;
65
66 // number of fft points (controls zero-padding)
67 m_nfft = m_warp_params.nsamps_twarp;
68 // hop in samples
69 m_hop = m_warp_params.fact_over_samp * 256;
70
71 m_num_f0s = 0;
72
73 }
74
75 FChTransformF0gram::~FChTransformF0gram() {
76 // remeber to delete everything that deserves to
77 }
78
79 string
80 FChTransformF0gram::getIdentifier() const {
81 return "fchtransformf0gram";
82 }
83
84 string
85 FChTransformF0gram::getName() const {
86 return "Fan Chirp Transform F0gram";
87 }
88
89 string
90 FChTransformF0gram::getDescription() const {
91 // Return something helpful here!
92 return "This plug-in produces a representation, called F0gram, which exhibits the salience of the fundamental frequency of the sound sources in the audio file. The computation of the F0gram makes use of the Fan Chirp Transform analysis. It is based on the article \"Fan chirp transform for music representation\" P. Cancela, E. Lopez, M. Rocamora, International Conference on Digital Audio Effects, 13th. DAFx-10. Graz, Austria - 6-10 Sep 2010.";
93 }
94
95 string
96 FChTransformF0gram::getMaker() const {
97 // Your name here
98 return "Audio Processing Group \n Universidad de la Republica";
99 }
100
101 int
102 FChTransformF0gram::getPluginVersion() const {
103 // Increment this each time you release a version that behaves
104 // differently from the previous one
105 //
106 // 0 - initial version from scratch
107 return 0;
108 }
109
110 string
111 FChTransformF0gram::getCopyright() const {
112 // This function is not ideally named. It does not necessarily
113 // need to say who made the plugin -- getMaker does that -- but it
114 // should indicate the terms under which it is distributed. For
115 // example, "Copyright (year). All Rights Reserved", or "GPL"
116 return "copyright (C) 2011 GPL - Audio Processing Group, UdelaR";
117 }
118
119 FChTransformF0gram::InputDomain
120 FChTransformF0gram::getInputDomain() const {
121 return TimeDomain;
122 }
123
124 size_t FChTransformF0gram::getPreferredBlockSize() const {
125 return 8192; // 0 means "I can handle any block size"
126 }
127
128 size_t
129 FChTransformF0gram::getPreferredStepSize() const {
130 return 256; // 0 means "anything sensible"; in practice this
131 // means the same as the block size for TimeDomain
132 // plugins, or half of it for FrequencyDomain plugins
133 }
134
135 size_t
136 FChTransformF0gram::getMinChannelCount() const {
137 return 1;
138 }
139
140 size_t
141 FChTransformF0gram::getMaxChannelCount() const {
142 return 1;
143 }
144
145 FChTransformF0gram::ParameterList
146 FChTransformF0gram::getParameterDescriptors() const {
147 ParameterList list;
148
149 // If the plugin has no adjustable parameters, return an empty
150 // list here (and there's no need to provide implementations of
151 // getParameter and setParameter in that case either).
152
153 // Note that it is your responsibility to make sure the parameters
154 // start off having their default values (e.g. in the constructor
155 // above). The host needs to know the default value so it can do
156 // things like provide a "reset to default" function, but it will
157 // not explicitly set your parameters to their defaults for you if
158 // they have not changed in the mean time.
159
160 // ============= WARPING PARAMETERS =============
161
162 ParameterDescriptor fmax;
163 fmax.identifier = "fmax";
164 fmax.name = "Maximum frequency";
165 fmax.description = "Maximum frequency of interest for the analysis.";
166 fmax.unit = "Hz";
167 fmax.minValue = 2000;
168 fmax.maxValue = 22050;
169 fmax.defaultValue = 10000;
170 fmax.isQuantized = true;
171 fmax.quantizeStep = 1.0;
172 list.push_back(fmax);
173
174 ParameterDescriptor nsamp;
175 nsamp.identifier = "nsamp";
176 nsamp.name = "Number of samples";
177 nsamp.description = "Number of samples of the time warped frame";
178 nsamp.unit = "samples";
179 nsamp.minValue = 128;
180 nsamp.maxValue = 4096;
181 nsamp.defaultValue = 2048;
182 nsamp.isQuantized = true;
183 nsamp.quantizeStep = 1.0;
184 list.push_back(nsamp);
185
186 ParameterDescriptor nfft;
187 nfft.identifier = "nfft";
188 nfft.name = "FFT number of points";
189 nfft.description = "Number of FFT points (controls zero-padding)";
190 nfft.unit = "samples";
191 nfft.minValue = 0;
192 nfft.maxValue = 4;
193 nfft.defaultValue = 3;
194 nfft.isQuantized = true;
195 nfft.quantizeStep = 1.0;
196 nfft.valueNames.push_back("256");
197 nfft.valueNames.push_back("512");
198 nfft.valueNames.push_back("1024");
199 nfft.valueNames.push_back("2048");
200 nfft.valueNames.push_back("4096");
201 nfft.valueNames.push_back("8192");
202 list.push_back(nfft);
203
204 ParameterDescriptor alpha_max;
205 alpha_max.identifier = "alpha_max";
206 alpha_max.name = "Maximum alpha value";
207 alpha_max.description = "Maximum value for the alpha parameter of the transform.";
208 alpha_max.unit = "Hz/s";
209 alpha_max.minValue = -10;
210 alpha_max.maxValue = 10;
211 alpha_max.defaultValue = 5;
212 alpha_max.isQuantized = true;
213 alpha_max.quantizeStep = 1.0;
214 list.push_back(alpha_max);
215
216 ParameterDescriptor num_warps;
217 num_warps.identifier = "num_warps";
218 num_warps.name = "Number of warpings";
219 num_warps.description = "Number of different warpings in the specified range (must be odd).";
220 num_warps.unit = "";
221 num_warps.minValue = 1;
222 num_warps.maxValue = 101;
223 num_warps.defaultValue = 21;
224 num_warps.isQuantized = true;
225 num_warps.quantizeStep = 2.0;
226 list.push_back(num_warps);
227
228 ParameterDescriptor alpha_dist;
229 alpha_dist.identifier = "alpha_dist";
230 alpha_dist.name = "alpha distribution";
231 alpha_dist.description = "Type of distribution of alpha values (linear or log).";
232 alpha_dist.unit = "";
233 alpha_dist.minValue = 0;
234 alpha_dist.maxValue = 1;
235 alpha_dist.defaultValue = 1;
236 alpha_dist.isQuantized = true;
237 alpha_dist.quantizeStep = 1.0;
238 // lin (0), log (1)
239 alpha_dist.valueNames.push_back("lin");
240 alpha_dist.valueNames.push_back("log");
241 list.push_back(alpha_dist);
242
243 // ============= F0-GRAM PARAMETERS =============
244
245 ParameterDescriptor f0min;
246 f0min.identifier = "f0min";
247 f0min.name = "min f0";
248 f0min.description = "Minimum fundamental frequency (f0) value.";
249 f0min.unit = "Hz";
250 f0min.minValue = 1;
251 f0min.maxValue = 500;
252 f0min.defaultValue = 80;
253 f0min.isQuantized = true;
254 f0min.quantizeStep = 1.0;
255 list.push_back(f0min);
256
257 ParameterDescriptor num_octs;
258 num_octs.identifier = "num_octs";
259 num_octs.name = "number of octaves";
260 num_octs.description = "Number of octaves for F0gram computation.";
261 num_octs.unit = "";
262 num_octs.minValue = 1;
263 num_octs.maxValue = 10;
264 num_octs.defaultValue = 4;
265 num_octs.isQuantized = true;
266 num_octs.quantizeStep = 1.0;
267 list.push_back(num_octs);
268
269 ParameterDescriptor num_f0_hyps;
270 num_f0_hyps.identifier = "num_f0_hyps";
271 num_f0_hyps.name = "number of f0 hypotesis";
272 num_f0_hyps.description = "Number of f0 hypotesis to extract.";
273 num_f0_hyps.unit = "";
274 num_f0_hyps.minValue = 1;
275 num_f0_hyps.maxValue = 100;
276 num_f0_hyps.defaultValue = 10;
277 num_f0_hyps.isQuantized = true;
278 num_f0_hyps.quantizeStep = 1.0;
279 list.push_back(num_f0_hyps);
280
281 ParameterDescriptor f0s_per_oct;
282 f0s_per_oct.identifier = "f0s_per_oct";
283 f0s_per_oct.name = "f0 values per octave";
284 f0s_per_oct.description = "Number of f0 values per octave.";
285 f0s_per_oct.unit = "";
286 f0s_per_oct.minValue = 12;
287 f0s_per_oct.maxValue = 768;
288 f0s_per_oct.defaultValue = 192;
289 f0s_per_oct.isQuantized = true;
290 f0s_per_oct.quantizeStep = 1.0;
291 list.push_back(f0s_per_oct);
292
293 ParameterDescriptor f0_prefer_fun;
294 f0_prefer_fun.identifier = "f0_prefer_fun";
295 f0_prefer_fun.name = "f0 preference function";
296 f0_prefer_fun.description = "Whether to use a f0 weighting function.";
297 f0_prefer_fun.unit = "";
298 f0_prefer_fun.minValue = 0;
299 f0_prefer_fun.maxValue = 1;
300 f0_prefer_fun.defaultValue = 1;
301 f0_prefer_fun.isQuantized = true;
302 f0_prefer_fun.quantizeStep = 1.0;
303 list.push_back(f0_prefer_fun);
304
305 ParameterDescriptor f0_prefer_mean;
306 f0_prefer_mean.identifier = "f0_prefer_mean";
307 f0_prefer_mean.name = "mean f0 preference function";
308 f0_prefer_mean.description = "Mean value for f0 weighting function (MIDI number).";
309 f0_prefer_mean.unit = "";
310 f0_prefer_mean.minValue = 1;
311 f0_prefer_mean.maxValue = 127;
312 f0_prefer_mean.defaultValue = 60;
313 f0_prefer_mean.isQuantized = true;
314 f0_prefer_mean.quantizeStep = 1.0;
315 list.push_back(f0_prefer_mean);
316
317 ParameterDescriptor f0_prefer_stdev;
318 f0_prefer_stdev.identifier = "f0_prefer_stdev";
319 f0_prefer_stdev.name = "stdev of f0 preference function";
320 f0_prefer_stdev.description = "Stdev for f0 weighting function (MIDI number).";
321 f0_prefer_stdev.unit = "";
322 f0_prefer_stdev.minValue = 1;
323 f0_prefer_stdev.maxValue = 127;
324 f0_prefer_stdev.defaultValue = 18;
325 f0_prefer_stdev.isQuantized = true;
326 f0_prefer_stdev.quantizeStep = 1.0;
327 list.push_back(f0_prefer_stdev);
328
329 ParameterDescriptor f0gram_mode;
330 f0gram_mode.identifier = "f0gram_mode";
331 f0gram_mode.name = "display mode of f0gram";
332 f0gram_mode.description = "Display all bins of the best direction, or the best bin for each direction.";
333 f0gram_mode.unit = "";
334 f0gram_mode.minValue = 0;
335 f0gram_mode.maxValue = 1;
336 f0gram_mode.defaultValue = 1;
337 f0gram_mode.isQuantized = true;
338 f0gram_mode.quantizeStep = 1.0;
339 list.push_back(f0gram_mode);
340
341 return list;
342 }
343
344 float
345 FChTransformF0gram::getParameter(string identifier) const {
346
347 printf("FUNCTION CALL: %s(%s)\n", __FUNCTION__, identifier.c_str());
348
349 if (identifier == "fmax") {
350 return m_fmax;
351 } else if (identifier == "nsamp") {
352 return m_warp_params.nsamps_twarp;
353 } else if (identifier == "alpha_max") {
354 return m_warp_params.alpha_max;
355 } else if (identifier == "num_warps") {
356 return m_warp_params.num_warps;
357 } else if (identifier == "alpha_dist") {
358 return m_warp_params.alpha_dist;
359 } else if (identifier == "nfft") {
360 return m_nfft;
361 } else if (identifier == "f0min") {
362 return m_f0_params.f0min;
363 } else if (identifier == "num_octs") {
364 return m_f0_params.num_octs;
365 } else if (identifier == "f0s_per_oct") {
366 return m_f0_params.num_f0s_per_oct;
367 } else if (identifier == "num_f0_hyps") {
368 return m_f0_params.num_f0_hyps;
369 } else if (identifier == "f0_prefer_fun") {
370 return m_f0_params.prefer;
371 } else if (identifier == "f0_prefer_mean") {
372 return m_f0_params.prefer_mean;
373 } else if (identifier == "f0_prefer_stdev") {
374 return m_f0_params.prefer_stdev;
375 } else if (identifier == "f0gram_mode") {
376 return m_f0gram_mode;
377 } else {
378 return 0.f;
379 }
380
381 }
382
383 void FChTransformF0gram::setParameter(string identifier, float value) {
384
385 printf("FUNCTION CALL: %s(%s) = %f.\n", __FUNCTION__, identifier.c_str(), value);
386
387 if (identifier == "fmax") {
388 m_fmax = value;
389 } else if (identifier == "nsamp") {
390 m_warp_params.nsamps_twarp = value;
391 } else if (identifier == "alpha_max") {
392 m_warp_params.alpha_max = value;
393 } else if (identifier == "num_warps") {
394 m_warp_params.num_warps = value;
395 } else if (identifier == "alpha_dist") {
396 m_warp_params.alpha_dist = value;
397 } else if (identifier == "nfft") {
398 m_nfft = value;
399 } else if (identifier == "f0min") {
400 m_f0_params.f0min = value;
401 } else if (identifier == "num_octs") {
402 m_f0_params.num_octs = value;
403 } else if (identifier == "f0s_per_oct") {
404 m_f0_params.num_f0s_per_oct = value;
405 } else if (identifier == "num_f0_hyps") {
406 m_f0_params.num_f0_hyps = value;
407 } else if (identifier == "f0_prefer_fun") {
408 m_f0_params.prefer = value;
409 } else if (identifier == "f0_prefer_mean") {
410 m_f0_params.prefer_mean = value;
411 } else if (identifier == "f0_prefer_stdev") {
412 m_f0_params.prefer_stdev = value;
413 } else if (identifier == "f0gram_mode") {
414 m_f0gram_mode = value;
415 }
416
417 }
418
419 FChTransformF0gram::ProgramList
420 FChTransformF0gram::getPrograms() const {
421 ProgramList list;
422
423 list.push_back("default");
424
425 return list;
426 }
427
428 string
429 FChTransformF0gram::getCurrentProgram() const {
430 return m_currentProgram;
431 }
432
433 void
434 FChTransformF0gram::selectProgram(string name) {
435
436 printf("FUNCTION CALL: %s\n", __FUNCTION__);
437
438 m_currentProgram = name;
439
440 if (name == "default") {
441 m_fmax = 10000.f;
442
443 m_warp_params.nsamps_twarp = 2048;
444 m_warp_params.alpha_max = 4;
445 m_warp_params.num_warps = 21;
446 m_warp_params.fact_over_samp = 2;
447 m_warp_params.alpha_dist = 0;
448
449 m_f0_params.f0min = 80.0;
450 m_f0_params.num_octs = 4;
451 m_f0_params.num_f0s_per_oct = 192;
452 m_f0_params.num_f0_hyps = 5;
453 m_f0_params.prefer = true;
454 m_f0_params.prefer_mean = 60;
455 m_f0_params.prefer_stdev = 18;
456
457 m_glogs_params.HP_logS = true;
458 m_glogs_params.att_subharms = 1;
459
460 m_glogs_params.median_poly_coefs[0] = -0.000000058551680;
461 m_glogs_params.median_poly_coefs[1] = -0.000006945207775;
462 m_glogs_params.median_poly_coefs[2] = 0.002357223226588;
463
464 m_glogs_params.sigma_poly_coefs[0] = 0.000000092782308;
465 m_glogs_params.sigma_poly_coefs[1] = 0.000057283574898;
466 m_glogs_params.sigma_poly_coefs[2] = 0.022199903714288;
467
468 m_nfft = m_warp_params.nsamps_twarp;
469 m_hop = m_warp_params.fact_over_samp * 256;
470
471 m_num_f0s = 0;
472
473 m_f0gram_mode = 1;
474
475 }
476 }
477
478 FChTransformF0gram::OutputList
479 FChTransformF0gram::getOutputDescriptors() const {
480
481 printf("FUNCTION CALL: %s\n", __FUNCTION__);
482
483 OutputList list;
484
485 // See OutputDescriptor documentation for the possibilities here.
486 // Every plugin must have at least one output.
487
488 /* f0 values of F0gram grid as string values */
489 vector<string> f0values;
490 size_t ind = 0;
491 char f0String[10];
492 while (ind < m_num_f0s) {
493 sprintf(f0String, "%4.2f", m_f0s[ind]);
494 f0values.push_back(f0String);
495 ind++;
496 }
497
498 /* The F0gram */
499 OutputDescriptor d;
500 d.identifier = "f0gram";
501 d.name = "F0gram: salience of f0s";
502 d.description = "This representation show the salience of the different f0s in the signal.";
503 d.unit = "Hertz";
504 d.hasFixedBinCount = true;
505 //d.binCount = m_num_f0s;
506 //d.binCount = m_blockSize/2+1;
507 //d.binCount = m_warp_params.nsamps_twarp/2+1;
508 //d.binCount = m_warpings.nsamps_torig;
509 d.binCount = m_f0_params.num_octs*m_f0_params.num_f0s_per_oct;
510 d.binNames = f0values;
511 d.hasKnownExtents = false;
512 d.isQuantized = false;
513 d.sampleType = OutputDescriptor::OneSamplePerStep;
514 d.hasDuration = false;
515 list.push_back(d);
516
517 return list;
518 }
519
520 bool
521 FChTransformF0gram::initialise(size_t channels, size_t stepSize, size_t blockSize) {
522 if (channels < getMinChannelCount() ||
523 channels > getMaxChannelCount()) return false;
524
525 printf("FUNCTION CALL: %s\n", __FUNCTION__);
526
527 // set blockSize and stepSize (but changed below)
528 m_blockSize = blockSize;
529 m_stepSize = stepSize;
530
531 // WARNING !!!
532 // these values in fact are determined by the sampling frequency m_fs
533 // the parameters used below correspond to default values i.e. m_fs = 44.100 Hz
534 //m_blockSize = 4 * m_warp_params.nsamps_twarp;
535 m_stepSize = floor(m_hop / m_warp_params.fact_over_samp);
536
537 /* initialise m_warp_params */
538 // FChTF0gram:warping_design m_warpings = new warping_design;
539 /* initialise m_f0_params */
540
541 /* initialise m_glogs_params */
542 design_GLogS();
543
544 /* design of FChT */
545 // design_fcht(m_warps, m_accums, m_f0s)
546 design_FChT();
547
548 design_FFT();
549
550 design_LPF();
551
552 design_time_window();
553
554 // Create Hanning window for warped signals
555 mp_HanningWindow = new double[m_warp_params.nsamps_twarp];
556 bool normalize = false;
557 hanning_window(mp_HanningWindow, m_warp_params.nsamps_twarp, normalize);
558
559 printf(" End of initialise().\n");
560 return true;
561 }
562
563 void
564 FChTransformF0gram::design_GLogS() {
565 printf(" Running design_GLogS().\n");
566
567 // total number & initial quantity of f0s
568 m_glogs_init_f0s = (size_t)(((double)m_f0_params.num_f0s_per_oct)*log2(5.0))+1;
569 m_glogs_num_f0s = (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct + m_glogs_init_f0s;
570
571 // Initialize arrays
572 m_glogs_f0 = new double[m_glogs_num_f0s];
573 m_glogs = new double[m_glogs_num_f0s*m_warp_params.num_warps];
574 m_glogs_n = new size_t[m_glogs_num_f0s];
575 m_glogs_index = new size_t[m_glogs_num_f0s];
576
577 // Compute f0 values
578 m_glogs_harmonic_count = 0;
579 double factor = (double)(m_warp_params.nsamps_twarp/2)/(double)(m_warp_params.nsamps_twarp/2+1);
580 for (size_t i = 0; i < m_glogs_num_f0s; i++) {
581 m_glogs_f0[i] = (m_f0_params.f0min/5.0)*pow(2.0,(double)i/(double)m_f0_params.num_f0s_per_oct);
582 // for every f0 compute number of partials less or equal than m_fmax.
583 m_glogs_n[i] = m_fmax*factor/m_glogs_f0[i];
584 m_glogs_index[i] = m_glogs_harmonic_count;
585 m_glogs_harmonic_count += m_glogs_n[i];
586 }
587
588 // Initialize arrays for interpolation
589 m_glogs_posint = new size_t[m_glogs_harmonic_count];
590 m_glogs_posfrac = new double[m_glogs_harmonic_count];
591 m_glogs_interp = new double[m_glogs_harmonic_count];
592
593 // Compute int & frac of interpolation positions
594 size_t aux_index = 0;
595 double aux_pos;
596 for (size_t i = 0; i < m_glogs_num_f0s; i++) {
597 for (size_t j = 1; j <= m_glogs_n[i]; j++) {
598 // indice en el vector de largo t_warp/2+1 donde el ultimo valor corresponde a f=m_fmax
599 aux_pos = ((double)j*m_glogs_f0[i])*((double)(m_warp_params.nsamps_twarp/2+1))/m_fmax;
600 m_glogs_posint[aux_index] = (size_t)aux_pos;
601 m_glogs_posfrac[aux_index] = aux_pos - (double)m_glogs_posint[aux_index];
602 aux_index++;
603 }
604 }
605
606 // Third harmonic attenuation
607 double aux_third_harmonic;
608 m_glogs_third_harmonic_posint = new size_t[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
609 m_glogs_third_harmonic_posfrac = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
610 for (size_t i = 0; i < (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct; i++) {
611 aux_third_harmonic = (double)i + (double)m_glogs_init_f0s - ((double)m_f0_params.num_f0s_per_oct)*log2(3.0);
612 //printf(" aux_third_harmonic = %f.\n", aux_third_harmonic);
613 m_glogs_third_harmonic_posint[i] = (size_t)aux_third_harmonic;
614 m_glogs_third_harmonic_posfrac[i] = aux_third_harmonic - (double)(m_glogs_third_harmonic_posint[i]);
615 }
616 m_glogs_third_harmonic = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
617
618 // Fifth harmonic attenuation
619 double aux_fifth_harmonic;
620 m_glogs_fifth_harmonic_posint = new size_t[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
621 m_glogs_fifth_harmonic_posfrac = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
622 for (size_t i = 0; i < (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct; i++) {
623 aux_fifth_harmonic = (double)i + (double)m_glogs_init_f0s - ((double)m_f0_params.num_f0s_per_oct)*log2(5.0);
624 //printf(" aux_fifth_harmonic = %f.\n", aux_fifth_harmonic);
625 m_glogs_fifth_harmonic_posint[i] = (size_t)aux_fifth_harmonic;
626 m_glogs_fifth_harmonic_posfrac[i] = aux_fifth_harmonic - (double)(m_glogs_fifth_harmonic_posint[i]);
627 }
628 m_glogs_fifth_harmonic = new double[(m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct];
629
630 // Normalization & attenuation windows
631 m_glogs_f0_preference_weights = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct];
632 m_glogs_median_correction = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct];
633 m_glogs_sigma_correction = new double[m_f0_params.num_octs*m_f0_params.num_f0s_per_oct];
634 m_glogs_hf_smoothing_window = new double[m_warp_params.nsamps_twarp/2+1];
635 double MIDI_value;
636 for (size_t i = 0; i < m_f0_params.num_octs*m_f0_params.num_f0s_per_oct; i++) {
637 MIDI_value = 69.0 + 12.0 * log2(m_glogs_f0[i + m_glogs_init_f0s]/440.0);
638 m_glogs_f0_preference_weights[i] = 1.0/sqrt(2.0*M_PI*m_f0_params.prefer_stdev*m_f0_params.prefer_stdev)*exp(-(MIDI_value-m_f0_params.prefer_mean)*(MIDI_value-m_f0_params.prefer_mean)/(2.0*m_f0_params.prefer_stdev*m_f0_params.prefer_stdev));
639 m_glogs_f0_preference_weights[i] = (0.01 + m_glogs_f0_preference_weights[i]) / (1.01);
640
641 m_glogs_median_correction[i] = m_glogs_params.median_poly_coefs[0]*(i+1.0)*(i+1.0) + m_glogs_params.median_poly_coefs[1]*(i+1.0) + m_glogs_params.median_poly_coefs[2];
642 m_glogs_sigma_correction[i] = 1.0 / (m_glogs_params.sigma_poly_coefs[0]*(i+1.0)*(i+1.0) + m_glogs_params.sigma_poly_coefs[1]*(i+1.0) + m_glogs_params.sigma_poly_coefs[2]);
643 }
644
645 double smooth_width = 1000.0; // hertz.
646 double smooth_aux = (double)(m_warp_params.nsamps_twarp/2+1)*(m_fmax-smooth_width)/m_fmax;
647 for (size_t i = 0; i < m_warp_params.nsamps_twarp/2+1; i++) {
648 if (i < smooth_aux) {
649 m_glogs_hf_smoothing_window[i] = 1.0;
650 } else {
651 m_glogs_hf_smoothing_window[i] = ((double)i - (double)m_warp_params.nsamps_twarp/2.0)*(-1.0/((double)(m_warp_params.nsamps_twarp/2+1)-smooth_aux));
652 }
653 }
654
655 printf(" End of design_GLogS().\n");
656
657 }
658
659 void
660 FChTransformF0gram::design_FFT() {
661 printf(" Running design_FFT().\n");
662
663 in = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * m_nfft);
664 out = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * m_nfft);
665 //TODO verificar que el tipo de datos de in_window es del tipo double, era float.
666 in_window = (double*) fftw_malloc(sizeof (double) * m_nfft);
667 planFFT = fftw_plan_dft_1d(m_nfft, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
668
669 //TODO hacer diseño del FFT para el filtrado pasabajos.
670
671 }
672
673 void
674 FChTransformF0gram::design_FChT() {
675
676 printf(" Running design_FChT().\n");
677 /*
678 * FILES FOR DEBUGGING
679 */
680
681 //ofstream output("output.txt");
682
683
684 /* ============= WARPING DESIGN ============= */
685
686 // sampling frequency after oversampling
687 m_warpings.fs_orig = m_warp_params.fact_over_samp * m_fs;
688
689 // number of samples of the original signal frame
690 m_warpings.nsamps_torig = 4 * m_warp_params.fact_over_samp * m_warp_params.nsamps_twarp;
691 // equivalent to: m_warpings.nsamps_torig = m_warp_params.fact_over_samp * m_blockSize;
692
693 // time instants of the original signal frame
694 double t_orig[m_warpings.nsamps_torig];
695 //float * t_orig = new float [m_warpings.nsamps_torig];
696 for (size_t ind = 0; ind < m_warpings.nsamps_torig; ind++) {
697 t_orig[ind] = ((double)(ind + 1) - (double)m_warpings.nsamps_torig / 2.0) / m_warpings.fs_orig;
698 }
699
700 // linear chirps warping definition as relative frequency deviation
701 //double * freq_relative = new double [m_warpings.nsamps_torig * m_warp_params.num_warps];
702 //TODO
703 double *freq_relative = new double [m_warpings.nsamps_torig * m_warp_params.num_warps];
704 define_warps_linear_chirps(freq_relative, t_orig);
705
706 // maximum relative frequency deviation
707 double freq_relative_max = 0;
708 for (size_t i = 0; i < m_warpings.nsamps_torig; i++)
709 for (size_t j = 0; j < m_warp_params.num_warps; j++)
710 if (freq_relative_max < freq_relative[j * m_warpings.nsamps_torig + i])
711 freq_relative_max = freq_relative[j * m_warpings.nsamps_torig + i];
712
713 // sampling frequency of warped signal to be free of aliasing up to fmax
714 m_warpings.fs_warp = 2 * m_fmax * freq_relative_max;
715
716 // time instants of the warped signal frame
717 double t_warp[m_warp_params.nsamps_twarp];
718 for (size_t ind = 0; ind < m_warp_params.nsamps_twarp; ind++) {
719 t_warp[ind] = ((double)((int)(ind + 1)- (int)m_warp_params.nsamps_twarp / 2)) / (double)m_warpings.fs_warp;
720 }
721
722 // design of warpings for efficient interpolation
723 design_warps(freq_relative, t_orig, t_warp);
724
725
726 /*
727 * FILES FOR DEBUGGING
728 */
729
730 /*
731 output << "chirp_rates" << endl;
732 for (size_t j = 0; j < m_warp_params.num_warps; j++){
733 output << m_warpings.chirp_rates[j];
734 output << " ";
735 }
736 output << endl << "freq_relative" << endl;
737
738 for (size_t i = 0; i < m_warpings.nsamps_torig; i++){
739 for (size_t j = 0; j < m_warp_params.num_warps; j++){
740 output << freq_relative[j * m_warpings.nsamps_torig + i];
741 output << " ";
742 }
743 output << endl;
744 }
745
746 output << endl << "t_orig" << endl;
747
748 for (size_t i = 0; i < m_warpings.nsamps_torig; i++){
749 output << t_orig[i] << endl ;
750 }
751 */
752
753 delete [] freq_relative;
754 //output.close();
755
756 /* ============= FFTW PLAN DESIGN ============= */
757 // Initialize 2-d array for warped signals
758 x_warping = new double[m_warp_params.nsamps_twarp];
759 m_absFanChirpTransform = (double*)fftw_malloc(sizeof (double) * m_warp_params.num_warps * (m_warp_params.nsamps_twarp/2 + 1));
760 m_auxFanChirpTransform = (fftw_complex*)fftw_malloc(sizeof ( fftw_complex) * (m_warp_params.nsamps_twarp/2 + 1));
761 plan_forward_xwarping = fftw_plan_dft_r2c_1d(m_warp_params.nsamps_twarp, x_warping, m_auxFanChirpTransform, FFTW_ESTIMATE);
762
763 printf(" End of design_FChT().\n");
764
765 }
766
767 void
768 FChTransformF0gram::design_warps(double * freq_relative, double * t_orig, double * t_warp) {
769 /* the warping is done by interpolating the original signal in time instants
770 given by the desired frequency deviation, to do this, the interpolation
771 instants are stored in a structure as an integer index and a fractional value
772 hypothesis: sampling frequency at the central point equals the original
773 */
774 printf(" Running design_warps().\n");
775
776 m_warpings.pos_int = new size_t[m_warp_params.num_warps * m_warp_params.nsamps_twarp];
777 m_warpings.pos_frac = new double[m_warp_params.num_warps * m_warp_params.nsamps_twarp];
778
779 // vector of phase values
780 double *phi = new double[m_warpings.nsamps_torig];
781 double aux;
782
783 // warped positions
784 double *pos1 = new double[m_warp_params.nsamps_twarp*m_warp_params.num_warps];
785
786 for (size_t i = 0; i < m_warp_params.num_warps; i++) {
787 // vector of phase values
788 // float * phi;
789 // integration of relative frequency to obtain phase values
790 // phi = cumtrapz(t_orig,freq_relative(:,i)');
791 // centering of phase values to force original frequency in the middle
792 //phi = phi - phi(end/2);
793 // interpolation of phase values to obtain warped positions
794 //pos1(i,:) = interp1(phi,t_orig,t_warp)*fs_orig + length(t_orig)/2;
795
796 // integration of relative frequency to obtain phase values
797 cumtrapz(t_orig, freq_relative + i*(m_warpings.nsamps_torig), m_warpings.nsamps_torig, phi);
798
799 // centering of phase values to force original frequency in the middle
800 aux = phi[m_warpings.nsamps_torig/2];
801 for (size_t j = 0; j < m_warpings.nsamps_torig; j++) {
802 phi[j] -= aux;
803 } //for
804
805 // interpolation of phase values to obtain warped positions
806 interp1(phi, t_orig, m_warpings.nsamps_torig, t_warp, pos1 + i*m_warp_params.nsamps_twarp, m_warp_params.nsamps_twarp);
807
808 }
809
810 // % previous sample index
811 // pos1_int = uint32(floor(pos1))';
812 // % integer corresponding to previous sample index in "c"
813 // warps.pos1_int = (pos1_int - uint32(1));
814 // % fractional value that defines the warped position
815 // warps.pos1_frac = (double(pos1)' - double(pos1_int));
816
817 // m_warpings.pos_int = new size_t[m_warp_params.num_warps * m_warp_params.nsamps_twarp];
818 for (size_t j = 0; j < m_warp_params.nsamps_twarp*m_warp_params.num_warps; j++) {
819 // previous sample index
820 pos1[j] = pos1[j]*m_warpings.fs_orig + m_warpings.nsamps_torig/2 + 1;
821 m_warpings.pos_int[j] = (size_t) pos1[j];
822 m_warpings.pos_frac[j] = pos1[j] - (double)(m_warpings.pos_int[j]);
823 } //for
824
825 delete [] phi;
826 delete [] pos1;
827
828 printf(" End of design_warps().\n");
829
830 }
831
832 void
833 FChTransformF0gram::define_warps_linear_chirps(double * freq_relative, double * t_orig) {
834 /** define warps as relative frequency deviation from original frequency
835 t_orig : time vector
836 freq_relative : relative frequency deviations
837 */
838 printf(" Running define_warps_linear_chirps().\n");
839
840 if (m_warp_params.alpha_dist == 0) {
841
842 // linear alpha values spacing
843 m_warpings.chirp_rates = new double [m_warp_params.num_warps];
844 // WARNING m_warp_params.num_warps must be odd
845 m_warpings.chirp_rates[0] = -m_warp_params.alpha_max;
846 double increment = (double) m_warp_params.alpha_max / ((m_warp_params.num_warps - 1) / 2);
847
848 for (size_t ind = 1; ind < m_warp_params.num_warps; ind++) {
849 m_warpings.chirp_rates[ind] = m_warpings.chirp_rates[ind - 1] + increment;
850 }
851 // force zero value
852 m_warpings.chirp_rates[(int) ((m_warp_params.num_warps - 1) / 2)] = 0;
853
854 } else {
855 // log alpha values spacing
856 m_warpings.chirp_rates = new double [m_warp_params.num_warps];
857
858 // force zero value
859 int middle_point = (int) ((m_warp_params.num_warps - 1) / 2);
860 m_warpings.chirp_rates[middle_point] = 0;
861
862 double logMax = log10(m_warp_params.alpha_max + 1);
863 double increment = logMax / ((m_warp_params.num_warps - 1) / 2.0f);
864 double exponent = 0;
865
866 // fill positive values
867 int ind_log = middle_point;
868 for (size_t ind = 0; ind < (m_warp_params.num_warps + 1) / 2; ind++) {
869 m_warpings.chirp_rates[ind_log] = pow(10, exponent) - 1;
870 exponent += increment;
871 ind_log++;
872 }
873 // fill negative values
874 for (size_t ind = 0; ind < (m_warp_params.num_warps - 1) / 2; ind++) {
875 m_warpings.chirp_rates[ind] = -m_warpings.chirp_rates[m_warp_params.num_warps - 1 - ind];
876 }
877 }
878
879 // compute relative frequency deviation
880 for (size_t i = 0; i < m_warpings.nsamps_torig; i++)
881 for (size_t j = 0; j < m_warp_params.num_warps; j++)
882 freq_relative[j * m_warpings.nsamps_torig + i] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j];
883 //freq_relative[i * m_warpings.nsamps_torig + j] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j];
884 //freq_relative[i][j] = 1.0 + t_orig[i] * m_warpings.chirp_rates[j];
885
886 printf(" End of define_warps_linear_chirps().\n");
887
888 }
889
890 void
891 FChTransformF0gram::design_LPF() {
892
893 printf(" Running design_LPF().\n");
894 // in = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * tamanoVentana);
895 // out = (fftw_complex*) fftw_malloc(sizeof (fftw_complex) * tamanoVentana);
896 // in_window = (float*) fftw_malloc(sizeof (float) * tamanoVentana);
897 // p = fftw_plan_dft_1d(tamanoVentana, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
898 double *lp_LPFWindow_aux = new double[m_blockSize/2+1];
899 mp_LPFWindow = new double[m_blockSize/2+1];
900
901 size_t i_max = (size_t) ((2.0*m_fmax/m_fs) * ( (double)m_blockSize / 2.0 + 1.0 ));
902 //printf(" i_max = %d.\n", (int)i_max);
903 for (size_t i = 0; i < m_blockSize/2+1; i++) {
904 if (i >= i_max) {
905 lp_LPFWindow_aux[i] = 0.0;
906 } else {
907 lp_LPFWindow_aux[i] = 1.0;
908 }
909 }
910 LPF_time = (double*)fftw_malloc(sizeof ( double) * m_warpings.nsamps_torig);
911 //memset((char*)LPF_time, 0, m_warpings.nsamps_torig * sizeof(double));
912 // sustituyo el memset por un for:
913 for (size_t i = 0; i < m_warpings.nsamps_torig; i++) {
914 LPF_time[i] = 0.0;
915 }
916 #ifdef DEBUG
917 printf(" Corrio primer memset...\n");
918 #endif
919 LPF_frequency = (fftw_complex*)fftw_malloc(sizeof ( fftw_complex) * (m_warpings.nsamps_torig/2 + 1)); //tamaño de la fft cuando la entrada es real
920 //memset((char*)LPF_frequency, 0, sizeof(fftw_complex) * (m_warpings.nsamps_torig/2 + 1));
921 // sustituyo el memset por un for:
922 for (size_t i = 0; i < (m_warpings.nsamps_torig/2 + 1); i++) {
923 LPF_frequency[i][0] = 0.0;
924 LPF_frequency[i][1] = 0.0;
925 }
926 // for (int i=0; i<(m_blockSize/2+1); i++) {
927 // LPF_frequency[i] = new fftw_complex;
928 // }
929 plan_forward_LPF = fftw_plan_dft_r2c_1d(m_blockSize, LPF_time, LPF_frequency, FFTW_ESTIMATE);
930 plan_backward_LPF = fftw_plan_dft_c2r_1d(m_warpings.nsamps_torig, LPF_frequency, LPF_time, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
931
932 size_t winWidth = 11;
933 double *lp_hanningWindow = new double[winWidth];
934 double accum=0;
935 for (size_t i = 0; i < winWidth; i++) {
936 lp_hanningWindow[i]=0.5*(1.0-cos(2*M_PI*(double)(i+1)/((double)winWidth+1.0)));
937 accum+=lp_hanningWindow[i];
938
939 }
940 for (size_t i = 0; i < winWidth; i++) { //window normalization
941 lp_hanningWindow[i]=lp_hanningWindow[i]/accum;
942 //printf(" lp_hanningWindow[%d] = %f.\n",(int)i,lp_hanningWindow[i]);
943 }
944 for (size_t i = 0; i < m_blockSize/2+1; i++) {
945 //if (((i-(winWidth-1)/2)<0)||(i+(winWidth-1))/2>m_blockSize/2-1) {//consideramos winWidth impar, si la ventana sale del arreglo se rellena con el valor origianl
946 if ( (i > (i_max + (winWidth-1)/2)) || (i <= (i_max - (winWidth-1)/2)) ) {
947 mp_LPFWindow[i]=lp_LPFWindow_aux[i];
948 //printf(" entro al if en i=%d.\n",(int)i);
949 } else {
950 accum=0;
951 for (size_t j = -((winWidth-1)/2); j <= (winWidth-1)/2; j++) {
952 accum+=lp_LPFWindow_aux[i-j]*lp_hanningWindow[j+(winWidth-1)/2];
953 //printf(" accum = %f.\n",accum);
954 }
955 mp_LPFWindow[i]=accum;
956 }
957 }
958
959 delete[] lp_LPFWindow_aux;
960 delete[] lp_hanningWindow;
961
962 printf(" End of design_LPF().\n");
963 }
964
965 void FChTransformF0gram::apply_LPF() {
966 fftw_execute(plan_forward_LPF);
967 for (size_t i = 0; i < m_blockSize/2+1; i++) {
968 LPF_frequency[i][0]*=mp_LPFWindow[i];
969 LPF_frequency[i][1]*=mp_LPFWindow[i];
970 }
971 fftw_execute(plan_backward_LPF);
972
973 // TODO ver si hay que hacer fftshift para corregir la fase respecto al centro del frame.
974 // nota: además de aplicar el LPF, esta función resamplea la señal original.
975 }
976
977 void FChTransformF0gram::clean_LPF() {
978 delete[] mp_LPFWindow;
979
980 fftw_destroy_plan(plan_forward_LPF);
981 fftw_destroy_plan(plan_backward_LPF);
982 fftw_free(LPF_time);
983 fftw_free(LPF_frequency);
984 }
985
986 void FChTransformF0gram::reset() {
987
988 printf("FUNCTION CALL: %s\n", __FUNCTION__);
989 // Clear buffers, reset stored values, etc
990
991 delete [] m_warpings.pos_int;
992 delete [] m_warpings.pos_frac;
993
994 fftw_destroy_plan(planFFT);
995 fftw_free(in);
996 fftw_free(out);
997
998 clean_LPF();
999
1000 delete [] m_timeWindow;
1001
1002 delete [] mp_HanningWindow;
1003
1004 // Warping
1005 delete [] x_warping;
1006 fftw_destroy_plan(plan_forward_xwarping);
1007 fftw_free(m_absFanChirpTransform);
1008 fftw_free(m_auxFanChirpTransform);
1009
1010 // design_GLogS
1011 delete [] m_glogs_f0;
1012 delete [] m_glogs;
1013 delete [] m_glogs_n;
1014 delete [] m_glogs_index;
1015 delete [] m_glogs_posint;
1016 delete [] m_glogs_posfrac;
1017 delete [] m_glogs_third_harmonic_posint;
1018 delete [] m_glogs_third_harmonic_posfrac;
1019 delete [] m_glogs_third_harmonic;
1020 delete [] m_glogs_fifth_harmonic_posint;
1021 delete [] m_glogs_fifth_harmonic_posfrac;
1022 delete [] m_glogs_fifth_harmonic;
1023 delete [] m_glogs_f0_preference_weights;
1024 delete [] m_glogs_median_correction;
1025 delete [] m_glogs_sigma_correction;
1026 delete [] m_glogs_hf_smoothing_window;
1027
1028 }
1029
1030 FChTransformF0gram::FeatureSet
1031 FChTransformF0gram::process(const float *const *inputBuffers, Vamp::RealTime timestamp) {
1032
1033 printf("FUNCTION CALL: %s\n", __FUNCTION__);
1034
1035 // // Do actual work!
1036 //
1037
1038 /* PSEUDOCÓDIGO:
1039 - Aplicar FFT al frame entero.
1040 - Filtro pasabajos en frecuencia.
1041 - FFT inversa al frame entero.
1042 -----------------------------------------------------------------------------
1043 - Para cada warp: *Si es un espectrograma direccional (un solo warp
1044 => no es para cada warp sino para el elegido)
1045 - Hacer la interpolación con interp1q.
1046 - Aplicar la FFT al frame warpeado.
1047 - (Opcional) GLogS.
1048 - ...
1049 */
1050
1051 //---------------------------------------------------------------------------
1052 FeatureSet fs;
1053
1054 #ifdef DEBUG
1055 printf("\n ----- DEBUG INFORMATION ----- \n");
1056 printf(" m_fs = %f Hz.\n",m_fs);
1057 printf(" fs_orig = %f Hz.\n",m_warpings.fs_orig);
1058 printf(" fs_warp = %f Hz.\n",m_warpings.fs_warp);
1059 printf(" m_nfft = %d.\n",m_nfft);
1060 printf(" m_blockSize = %d.\n",m_blockSize);
1061 printf(" m_warpings.nsamps_torig = %d.\n",m_warpings.nsamps_torig);
1062 printf(" m_warp_params.num_warps = %d.\n",m_warp_params.num_warps);
1063 printf(" m_glogs_harmonic_count = %d.\n",m_glogs_harmonic_count);
1064 #endif
1065
1066 // size_t n = m_nfft/2 + 1;
1067 // double *tbuf = in_window;
1068
1069 for (size_t i = 0; i < m_blockSize; i++) {
1070 LPF_time[i] = (double)(inputBuffers[0][i]) * m_timeWindow[i];
1071 }
1072
1073 // #ifdef DEBUG
1074 // printf(" HASTA ACÁ ANDA!!!\n");
1075 // cout << flush;
1076 // #endif
1077
1078 apply_LPF();
1079 // Señal filtrada queda en LPF_time
1080
1081 Feature feature;
1082 feature.hasTimestamp = false;
1083
1084
1085 /* Solo a modo de prueba, voy a poner la salida del filtrado en «in» y
1086 voy a mostrar la FFT de eso, para ver el efecto del filtrado. */
1087 // for (size_t i = 0; i < m_nfft; i++) {
1088 // in[i][0] = tbuf[i];
1089 // in[i][1] = 0;
1090 // }
1091 // fftw_execute(planFFT);
1092 // double real, imag;
1093 // for (size_t i=0; i<n; ++i) { // preincremento?? ver version de nacho
1094 // real = out[i][0];
1095 // imag = out[i][1];
1096 // feature.values.push_back(real*real + imag*imag);
1097 // }
1098 // fs[0].push_back(feature);
1099
1100 // float real;
1101 // float imag;
1102 // for (size_t i=0; i<m_blockSize/2+1; i++) {
1103 // real = (float)(LPF_frequency[i][0]);
1104 // imag = (float)(LPF_frequency[i][1]);
1105 // feature.values.push_back(real*real+imag*imag);
1106 // //feature.values.push_back((float)(mp_LPFWindow[i]));
1107 // }
1108
1109 // ----------------------------------------------------------------------------------------------
1110 // Hanning window & FFT for all warp directions
1111
1112 double max_glogs = -DBL_MAX;
1113 size_t ind_max_glogs = 0;
1114
1115 for (size_t i_warp = 0; i_warp < m_warp_params.num_warps; i_warp++) {
1116 // Interpolate
1117 interp1q(LPF_time, (m_warpings.pos_int) + i_warp*m_warp_params.nsamps_twarp, m_warpings.pos_frac + i_warp*m_warp_params.nsamps_twarp, x_warping, m_warp_params.nsamps_twarp);
1118
1119 // Apply window
1120 for (size_t i = 0; i < m_warp_params.nsamps_twarp; i++) {
1121 x_warping[i] *= mp_HanningWindow[i];
1122 }
1123
1124 // Transform
1125 fftw_execute(plan_forward_xwarping);
1126
1127 // Copy result
1128 //memcpy(m_absFanChirpTransform + i_warp*(m_warp_params.nsamps_twarp/2+1), m_auxFanChirpTransform, (m_warp_params.nsamps_twarp/2+1)*sizeof(fftw_complex)); asi como esta no funciona
1129 double *aux_abs_fcht = m_absFanChirpTransform + i_warp*(m_warp_params.nsamps_twarp/2+1);
1130 for (size_t i = 0; i < (m_warp_params.nsamps_twarp/2+1); i++) {
1131 aux_abs_fcht[i] = log10(1.0 + 10.0*sqrt(m_auxFanChirpTransform[i][0]*m_auxFanChirpTransform[i][0]+m_auxFanChirpTransform[i][1]*m_auxFanChirpTransform[i][1]));
1132 // smoothing high frequency values
1133 //aux_abs_fcht[i] *= m_glogs_hf_smoothing_window[i];
1134 }
1135
1136 // -----------------------------------------------------------------------------------------
1137 // GLogS
1138 interp1q(aux_abs_fcht, m_glogs_posint, m_glogs_posfrac, m_glogs_interp, m_glogs_harmonic_count);
1139 size_t glogs_ind = 0;
1140 for (size_t i = 0; i < m_glogs_num_f0s; i++) {
1141 double glogs_accum = 0;
1142 for (size_t j = 1; j <= m_glogs_n[i]; j++) {
1143 glogs_accum += m_glogs_interp[glogs_ind++];
1144 }
1145 m_glogs[i + i_warp*m_glogs_num_f0s] = glogs_accum/(double)m_glogs_n[i];
1146 }
1147 //printf(" glogs_ind = %d.\n",(int)glogs_ind);
1148
1149 // Sub/super harmonic correction
1150 interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_third_harmonic_posint, m_glogs_third_harmonic_posfrac, m_glogs_third_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct);
1151 interp1q(m_glogs + i_warp*m_glogs_num_f0s, m_glogs_fifth_harmonic_posint, m_glogs_fifth_harmonic_posfrac, m_glogs_fifth_harmonic, (m_f0_params.num_octs+1)*m_f0_params.num_f0s_per_oct);
1152 for (size_t i = m_glogs_num_f0s-1; i >= m_glogs_init_f0s; i--) {
1153 m_glogs[i + i_warp*m_glogs_num_f0s] -= MAX(MAX(m_glogs[i-m_f0_params.num_f0s_per_oct + i_warp*m_glogs_num_f0s],m_glogs_third_harmonic[i-m_glogs_init_f0s]),m_glogs_fifth_harmonic[i-m_glogs_init_f0s]);
1154 //m_glogs[i] -= MAX(m_glogs[i-m_f0_params.num_f0s_per_oct],m_glogs_third_harmonic[i-m_glogs_init_f0s]);
1155 }
1156 for (size_t i = m_glogs_init_f0s; i < m_glogs_num_f0s-m_f0_params.num_f0s_per_oct; i++) {
1157 m_glogs[i + i_warp*m_glogs_num_f0s] -= 0.3*m_glogs[i+m_f0_params.num_f0s_per_oct + i_warp*m_glogs_num_f0s];
1158 // Median, sigma $ weights correction
1159 m_glogs[i + i_warp*m_glogs_num_f0s] = (m_glogs[i + i_warp*m_glogs_num_f0s]-m_glogs_median_correction[i-m_glogs_init_f0s])*m_glogs_sigma_correction[i-m_glogs_init_f0s]*m_glogs_f0_preference_weights[i-m_glogs_init_f0s];
1160 }
1161
1162 // Look for maximum value to determine best direction
1163 for (size_t i = m_glogs_init_f0s; i < m_glogs_num_f0s-m_f0_params.num_f0s_per_oct; i++) {
1164 if (m_glogs[i + i_warp*m_glogs_num_f0s] > max_glogs) {
1165 max_glogs = m_glogs[i + i_warp*m_glogs_num_f0s];
1166 ind_max_glogs = i_warp;
1167 }
1168 }
1169 }
1170
1171 // ----------------------------------------------------------------------------------------------
1172
1173 for (size_t i=m_glogs_init_f0s; i< m_glogs_num_f0s - m_f0_params.num_f0s_per_oct; i++) {
1174 //for (size_t i=0; i<(m_warp_params.nsamps_twarp/2+1); i++) {
1175 //feature.values.push_back((float)(m_warpings.pos_int[i])+ (float)(m_warpings.pos_frac[i]));
1176 //feature.values.push_back((float)(phi[i]*100000.0));
1177 //feature.values.push_back((float)(t_orig[i]));
1178 //feature.values.push_back((float)(pos1[i]));
1179 //feature.values.push_back((float)x_warping[i]);
1180 //feature.values.push_back(m_absFanChirpTransform[i + ind_max_glogs*(m_warp_params.nsamps_twarp/2+1)]);
1181 //feature.values.push_back((float)m_glogs[i+(long)ind_max_glogs*(long)m_glogs_num_f0s]);
1182 switch (m_f0gram_mode) {
1183 case 1:
1184 max_glogs = -DBL_MAX;
1185 for (size_t i_warp = 0; i_warp < m_warp_params.num_warps; i_warp++) {
1186 if (m_glogs[i + i_warp*m_glogs_num_f0s] > max_glogs) {
1187 max_glogs = m_glogs[i + i_warp*m_glogs_num_f0s];
1188 ind_max_glogs = i_warp;
1189 }
1190 }
1191 feature.values.push_back((float)max_glogs);
1192 break;
1193 case 0:
1194 feature.values.push_back((float)m_glogs[i+(size_t)ind_max_glogs*(size_t)m_glogs_num_f0s]);
1195 break;
1196 }
1197 //feature.values.push_back((float)m_glogs_hf_smoothing_window[i]);
1198 }
1199
1200 // ----------------------------------------------------------------------------------------------
1201
1202 fs[0].push_back(feature);
1203
1204 #ifdef DEBUG
1205 printf(" ----------------------------- \n");
1206 #endif
1207
1208 return fs;
1209 //---------------------------------------------------------------------------
1210
1211 //return FeatureSet();
1212 }
1213
1214 FChTransformF0gram::FeatureSet
1215 FChTransformF0gram::getRemainingFeatures() {
1216
1217 printf("FUNCTION CALL: %s\n", __FUNCTION__);
1218
1219 return FeatureSet();
1220 }
1221
1222 void
1223 FChTransformF0gram::design_time_window() {
1224
1225 printf(" Running design_time_window().\n");
1226
1227 size_t transitionWidth = (size_t)m_blockSize/128 + 1;;
1228 m_timeWindow = new double[m_blockSize];
1229 double *lp_transitionWindow = new double[transitionWidth];
1230
1231 //memset(m_timeWindow, 1.0, m_blockSize);
1232 for (size_t i = 0; i < m_blockSize; i++) {
1233 m_timeWindow[i] = 1.0;
1234 }
1235
1236 for (size_t i = 0; i < transitionWidth; i++) {
1237 lp_transitionWindow[i]=0.5*(1.0-cos(2*M_PI*(double)(i+1)/((double)transitionWidth+1.0)));
1238 }
1239
1240 for (size_t i = 0; i < transitionWidth/2; i++) {
1241 m_timeWindow[i] = lp_transitionWindow[i];
1242 m_timeWindow[m_blockSize-1-i] = lp_transitionWindow[transitionWidth-1-i];
1243 }
1244
1245 #ifdef DEBUG
1246 for (int i = 0; i < m_blockSize; i++) {
1247 if ((i<transitionWidth)) {
1248 printf(" m_timeWindow[%d] = %f.\n",i,m_timeWindow[i]);
1249 }
1250 }
1251 #endif
1252
1253 delete [] lp_transitionWindow;
1254
1255 printf(" End of design_time_window().\n");
1256 }
1257