annotate FChTransformF0gram.cpp @ 5:cdf7cb06049c

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