annotate examples/10-Instruments/d-box/spear_parser.cpp @ 556:ce391098f321 prerelease tip

THIS PROJECT HAS MOVED TO https://github.com/BelaPlatform/bela
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 25 Jun 2016 20:21:00 +0100
parents 8fcfbfb32aa0
children
rev   line source
robert@464 1 /*
robert@464 2 * spear_parser.cpp v1.2
robert@464 3 *
robert@464 4 * Created on: May 6, 2014
robert@464 5 * Author: Victor Zappi
robert@464 6 */
robert@464 7
robert@464 8 #include "spear_parser.h"
robert@464 9
robert@464 10 using namespace std;
robert@464 11
robert@464 12 //#define DO_CHECKS
robert@464 13
robert@464 14 //------------------------------------------------------------------------------------------------
robert@464 15 // partials
robert@464 16 //------------------------------------------------------------------------------------------------
robert@464 17
robert@464 18 Partials::Partials()
robert@464 19 {
robert@464 20 partialFrequencies = NULL;
robert@464 21 // partialAmplitudes = NULL;
robert@464 22 // partialNumFrames = NULL;
robert@464 23 // partialStartSample = NULL;
robert@464 24 // partialEndSample = NULL;
robert@464 25 // partialCurrentFrame = NULL;
robert@464 26 // partialFreqDelta = NULL;
robert@464 27 // partialAmpDelta = NULL;
robert@464 28
robert@464 29
robert@464 30 activePartialNum = NULL;
robert@464 31 // activePartials = NULL;
robert@464 32
robert@464 33 currentSample = -1;
robert@464 34 }
robert@464 35
robert@464 36 Partials::~Partials()
robert@464 37 {
robert@464 38 if(partialFrequencies != NULL) // check on one is enough
robert@464 39 {
robert@464 40 if(partialFrequencies[0] != NULL) // check on one is enough
robert@464 41 {
robert@464 42 for(unsigned int i=0; i<parNum; i++)
robert@464 43 {
robert@464 44 delete[] partialFrequencies[i];
robert@464 45 delete[] partialAmplitudes[i];
robert@464 46 delete[] partialFreqDelta[i];
robert@464 47 delete[] partialAmpDelta[i];
robert@464 48
robert@464 49 }
robert@464 50 }
robert@464 51
robert@464 52 delete[] partialFrequencies;
robert@464 53 delete[] partialAmplitudes;
robert@464 54 delete[] partialNumFrames;
robert@464 55 delete[] partialFreqDelta;
robert@464 56 delete[] partialAmpDelta;
robert@464 57 delete[] partialFreqMean;
robert@464 58 }
robert@464 59
robert@464 60 if(activePartialNum != NULL)
robert@464 61 {
robert@464 62 for(unsigned int i=0; i<hopNum+1; i++)
robert@464 63 delete[] activePartials[i];
robert@464 64
robert@464 65 delete[] activePartialNum;
robert@464 66 delete[] activePartials ;
robert@464 67 }
robert@464 68 }
robert@464 69
robert@464 70 void Partials::init(int parN, int hopS, bool isDBX)
robert@464 71 {
robert@464 72 if(!isDBX)
robert@464 73 {
robert@464 74 parNum = parN;
robert@464 75 hopSize = hopS;
robert@464 76
robert@464 77 partialFrequencies = new float *[parNum];
robert@464 78 partialAmplitudes = new float *[parNum];
robert@464 79 partialNumFrames = new unsigned int[parNum];
robert@464 80 partialStartFrame = new unsigned int[parNum];
robert@464 81 partialStartSample = new unsigned int[parNum];
robert@464 82 partialEndSample = new unsigned int[parNum];
robert@464 83 partialFreqDelta = new float *[parNum];
robert@464 84 partialAmpDelta = new float *[parNum];
robert@464 85 partialFreqMean = new float[parNum];
robert@464 86
robert@464 87
robert@464 88
robert@464 89 // init in one shot
robert@464 90 fill(partialFreqMean, partialFreqMean+parNum, 0); // mean is zero
robert@464 91
robert@464 92 partialFrequencies[0] = NULL; // for free check
robert@464 93 }
robert@464 94 else
robert@464 95 {
robert@464 96 parNum = parN;
robert@464 97 hopSize = hopS;
robert@464 98
robert@464 99 partialFrequencies = new float *[parNum];
robert@464 100 partialAmplitudes = new float *[parNum];
robert@464 101 partialNumFrames = new unsigned int[parNum];
robert@464 102 partialStartFrame = new unsigned int[parNum];
robert@464 103 partialFreqDelta = new float *[parNum];
robert@464 104 partialAmpDelta = new float *[parNum];
robert@464 105 partialFreqMean = new float[parNum];
robert@464 106
robert@464 107 partialFrequencies[0] = NULL; // for free check
robert@464 108 }
robert@464 109 }
robert@464 110
robert@464 111
robert@464 112
robert@464 113 void Partials::update(int parIndex, int frameNum)
robert@464 114 {
robert@464 115 partialFrequencies[parIndex] = new float[frameNum];
robert@464 116 partialAmplitudes[parIndex] = new float[frameNum];
robert@464 117 partialFreqDelta[parIndex] = new float[frameNum];
robert@464 118 partialAmpDelta[parIndex] = new float[frameNum];
robert@464 119
robert@464 120 fill(partialFreqDelta[parIndex], partialFreqDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999
robert@464 121 fill(partialAmpDelta[parIndex], partialAmpDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999
robert@464 122 }
robert@464 123
robert@464 124
robert@464 125
robert@464 126
robert@464 127
robert@464 128
robert@464 129
robert@464 130
robert@464 131
robert@464 132
robert@464 133
robert@464 134
robert@464 135
robert@464 136
robert@464 137
robert@464 138
robert@464 139
robert@464 140
robert@464 141
robert@464 142
robert@464 143 //------------------------------------------------------------------------------------------------
robert@464 144 // spear parser
robert@464 145 //------------------------------------------------------------------------------------------------
robert@464 146 Spear_parser::Spear_parser()
robert@464 147 {
robert@464 148 // some default values
robert@464 149 hopSize = -1;
robert@464 150 fileSampleRate = -1;
robert@464 151 }
robert@464 152
robert@464 153 Spear_parser::~Spear_parser()
robert@464 154 {
robert@464 155 }
robert@464 156
robert@464 157 void Spear_parser::calculateHopSize(char *filename)
robert@464 158 {
robert@464 159 int index = 0;
robert@464 160 bool prevWas_ = false;
robert@464 161 bool found_h = false;
robert@464 162 int n = 0;
robert@464 163
robert@464 164 hopSize = 0;
robert@464 165
robert@464 166 do
robert@464 167 {
robert@464 168 // check if '_'
robert@464 169 if(filename[index] == '_')
robert@464 170 prevWas_ = true;
robert@464 171 else if( (filename[index] == 'h') && prevWas_) // if it is not, but it is 'h' and previous was '_', found "_h"!
robert@464 172 {
robert@464 173 found_h = true;
robert@464 174 while(filename[index] != '\0')
robert@464 175 {
robert@464 176 index++;
robert@464 177 if( (filename[index] == '.') || (filename[index] == '_'))
robert@464 178 break;
robert@464 179 else // i am not checking if char are digits...!
robert@464 180 {
robert@464 181 n = filename[index];
robert@464 182 hopSize = hopSize*10+(n-48);
robert@464 183 }
robert@464 184 }
robert@464 185 }
robert@464 186 else // else, nothing
robert@464 187 prevWas_ = false;
robert@464 188 index++;
robert@464 189 }
robert@464 190 while( (filename[index] != '\0') && !found_h );
robert@464 191
robert@464 192 if( !found_h || (hopSize<1) )
robert@464 193 hopSize = 551; // default val
robert@464 194
robert@464 195 }
robert@464 196
robert@464 197
robert@464 198 bool Spear_parser::parser(char *filename, int hopsize, int samplerate)
robert@464 199 {
robert@464 200 string name = string(filename);
robert@464 201 int len = name.length();
robert@464 202 // invoke correct parser according to the type of file...just checking the extension, crude but functional
robert@464 203 if( (name[len-4]=='.') && (name[len-3]=='d') && (name[len-2]=='b') && (name[len-1]=='x') )
robert@464 204 return DBXparser(filename, samplerate); // .dbox
robert@464 205 else
robert@464 206 return TXTparser(filename, hopSize, samplerate); // .txt, or whatever
robert@464 207 }
robert@464 208
robert@464 209
robert@464 210 bool Spear_parser::DBXparser(char *filename, int samplerate)
robert@464 211 {
robert@464 212 fileSampleRate = samplerate;
robert@464 213
robert@464 214 // working vars
robert@464 215 int parNum = 0; // total num of partials
robert@464 216 int hopNum = 0; // total num of hops
robert@464 217
robert@464 218 //----------------------------------------------------------------------------------------
robert@464 219 // open a file
robert@464 220 ifstream fin;
robert@464 221 fin.open(filename, ios::in | ios::binary);
robert@464 222 if (!fin.good())
robert@464 223 {
robert@464 224 cout << "Parser Error: file not found" << endl; // exit if file not found
robert@464 225 return false;
robert@464 226 }
robert@464 227
robert@464 228 gettimeofday(&start, NULL);
robert@464 229 //----------------------------------------------------------------------------------------
robert@464 230 // general data
robert@464 231
robert@464 232 // look for partial count
robert@464 233 fin.read((char *) &parNum, sizeof(int));
robert@464 234 partials.parNum = parNum;
robert@464 235
robert@464 236 // look for hop count
robert@464 237 fin.read((char *) &hopNum, sizeof(int));
robert@464 238 partials.setHopNum(hopNum);
robert@464 239
robert@464 240 // look for hop size
robert@464 241 fin.read((char *) &hopSize, sizeof(int));
robert@464 242 partials.hopSize = hopSize; // it's handy for both classes to know it
robert@464 243
robert@464 244 // init partials data structure
robert@464 245 partials.init(parNum, hopSize, true);
robert@464 246
robert@464 247 // look for max active par num
robert@464 248 fin.read((char *) &(partials.maxActiveParNum), sizeof(int));
robert@464 249
robert@464 250
robert@464 251
robert@464 252 // partial data
robert@464 253
robert@464 254 // start frame of each partial
robert@464 255 fin.read((char *) partials.partialStartFrame, sizeof(int)*parNum);
robert@464 256
robert@464 257 // num of frames of each partial
robert@464 258 fin.read((char *) partials.partialNumFrames, sizeof(int)*parNum);
robert@464 259
robert@464 260 // frequency mean of each partial
robert@464 261 fin.read((char *) partials.partialFreqMean, sizeof(int)*parNum);
robert@464 262
robert@464 263 for(int par=0; par<parNum; par++)
robert@464 264 {
robert@464 265 int frameNum = partials.partialNumFrames[par];
robert@464 266 partials.update(par, frameNum);
robert@464 267 fin.read((char *)partials.partialAmplitudes[par], sizeof(float)*frameNum); // amplitude of each partial in each frame
robert@464 268 fin.read((char *)partials.partialFrequencies[par], sizeof(float)*frameNum); // frequency of each partial in each frame
robert@464 269 fin.read((char *)partials.partialAmpDelta[par], sizeof(float)*frameNum); // amplitude delta of each partial in each frame
robert@464 270 fin.read((char *)partials.partialFreqDelta[par], sizeof(float)*frameNum); // frequency delta of each partial in each frame
robert@464 271 }
robert@464 272
robert@464 273
robert@464 274
robert@464 275
robert@464 276 // frame data
robert@464 277
robert@464 278 // number of active partial per each frame
robert@464 279 fin.read((char *) partials.activePartialNum, sizeof(short)*(hopNum+1));
robert@464 280 // init array
robert@464 281 for(int frame=0; frame<hopNum+1; frame++)
robert@464 282 {
robert@464 283 partials.activePartials[frame] = new unsigned int[partials.activePartialNum[frame]];
robert@464 284 fin.read((char *)partials.activePartials[frame], sizeof(int)*partials.activePartialNum[frame]); // active partials per each frame
robert@464 285 }
robert@464 286
robert@464 287
robert@464 288
robert@464 289
robert@464 290
robert@464 291 gettimeofday(&stop, NULL);
robert@464 292 parserT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
robert@464 293
robert@464 294
robert@464 295 printf("\n-----------------------\n");
robert@464 296 printf("\nFile: %s\n", filename);
robert@464 297 printf("\n-----------------------\n");
robert@464 298 printf("Profiler\n");
robert@464 299 printf("-----------------------\n");
robert@464 300 printf("File parser:\t\t\t%lu usec\n", parserT);
robert@464 301 printf("\n\nTotal:\t\t%lu usec\n", parserT);
robert@464 302 printf("-----------------------\n");
robert@464 303
robert@464 304 fin.close();
robert@464 305
robert@464 306 return true;
robert@464 307 }
robert@464 308
robert@464 309
robert@464 310
robert@464 311
robert@464 312 bool Spear_parser::TXTparser(char *filename, int hopsize, int samplerate)
robert@464 313 {
robert@464 314 hopSize = hopsize;
robert@464 315 fileSampleRate = samplerate;
robert@464 316 if(hopsize<0)
robert@464 317 {
robert@464 318 gettimeofday(&start, NULL);
robert@464 319 calculateHopSize(filename);
robert@464 320 gettimeofday(&stop, NULL);
robert@464 321 hopSizeT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
robert@464 322 }
robert@464 323 else
robert@464 324 hopSizeT = 0;
robert@464 325
robert@464 326 calculateDeltaTime();
robert@464 327
robert@464 328 // working vars
robert@464 329 char * token; // where to save single figures from file
robert@464 330 string s = ""; // where to save lines from file
robert@464 331 int parNum = 0; // total num of partials
robert@464 332 int parIndex = -1; // index of current partial
robert@464 333 int frameNum = 0; // total num of frames
robert@464 334 int frameIndex = -1; // index of current frame
robert@464 335 int startSample = -1; // sample value for first frame of partials
robert@464 336 int endSample = -1; // sample value for last frame of partials
robert@464 337 int maxSample = 0; // to calculate total number of hops in file
robert@464 338 int missSampCnt = 0; // number of mising samples
robert@464 339 double freq = 0; // to calculate frequency delta
robert@464 340 double prevFreq = 0; // to calculate frequency delta
robert@464 341 double amp = 0; // to calculate amplitude delta
robert@464 342 double prevAmp = 0; // to calculate amplitude delta
robert@464 343
robert@464 344
robert@464 345 //----------------------------------------------------------------------------------------
robert@464 346 // open a file
robert@464 347 ifstream fin;
robert@464 348 fin.open(filename);
robert@464 349 if (!fin.good())
robert@464 350 {
robert@464 351 cout << "Parser Error: file not found" << endl; // exit if file not found
robert@464 352 return false;
robert@464 353 }
robert@464 354
robert@464 355 gettimeofday(&start, NULL);
robert@464 356 //----------------------------------------------------------------------------------------
robert@464 357 // init partials data structure
robert@464 358 getline(fin, s);
robert@464 359 getline(fin, s);
robert@464 360 getline(fin, s); // third line is the first we are interested into
robert@464 361
robert@464 362 // look for partial count
robert@464 363 token = strtok((char *)s.c_str(), " ");
robert@464 364 // check if first token is there
robert@464 365 if(token)
robert@464 366 {
robert@464 367 token = strtok(0, " ");
robert@464 368 // check if second token is there
robert@464 369 if(token)
robert@464 370 parNum = atoi(token);
robert@464 371 #ifdef DO_CHECKS
robert@464 372 else
robert@464 373 {
robert@464 374 cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found
robert@464 375 return false;
robert@464 376 }
robert@464 377 #endif
robert@464 378 }
robert@464 379 #ifdef DO_CHECKS
robert@464 380 else
robert@464 381 {
robert@464 382 cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found
robert@464 383 return false;
robert@464 384 }
robert@464 385 #endif
robert@464 386 // from now on we take for granted that format is correct
robert@464 387
robert@464 388 // init partials data structure
robert@464 389 partials.init(parNum, hopSize);
robert@464 390
robert@464 391 //----------------------------------------------------------------------------------------
robert@464 392 // fill in partials data structure
robert@464 393 getline(fin, s); // get rid of intro line "partials-data"
robert@464 394 getline(fin, s); // first important line
robert@464 395
robert@464 396 while (!fin.eof())
robert@464 397 {
robert@464 398 //-------------------------------------
robert@464 399 // partial specific info
robert@464 400 token = strtok((char *)s.c_str(), " ");
robert@464 401 parIndex = atoi(token); // partial index
robert@464 402
robert@464 403 token = strtok(0, " "); // num of frames, not used, cos we will do linear interpolation for missing frames
robert@464 404 // frameNum = atoi(token);
robert@464 405 // partials.partialNumFrames[parIndex] = frameNum;
robert@464 406
robert@464 407 token = strtok(0, " "); // time of first frame, still char *
robert@464 408 startSample = fromTimeToSamples(atof(token)); // convert time to samples
robert@464 409 partials.partialStartSample[parIndex] = startSample;
robert@464 410
robert@464 411 token = strtok(0, " "); // time of last frame, still char *
robert@464 412 endSample = fromTimeToSamples(atof(token)); // convert time to samples
robert@464 413 partials.partialEndSample[parIndex] = endSample;
robert@464 414
robert@464 415 frameNum = ((endSample-startSample)/hopSize) + 1; // num of frames, including missing consecutive ones [+1 one cos we count frames, not hops]
robert@464 416 partials.partialNumFrames[parIndex] = frameNum;
robert@464 417
robert@464 418
robert@464 419 // check if this is the highest sample value so far
robert@464 420 if(endSample > maxSample)
robert@464 421 maxSample = endSample;
robert@464 422
robert@464 423 // update data structure
robert@464 424 partials.update(parIndex, frameNum);
robert@464 425
robert@464 426
robert@464 427 //-------------------------------------
robert@464 428 // frames
robert@464 429 getline(fin, s);
robert@464 430 token = strtok((char *)s.c_str(), " "); // frame time
robert@464 431 frameIndex = -1;
robert@464 432
robert@464 433 // unroll first iteration, so that in the following loop we save the check on the last frame to calculate increments
robert@464 434 if(token) // all frames data are on one line, in groups of 3 entries
robert@464 435 {
robert@464 436 frameIndex++;
robert@464 437
robert@464 438 endSample = fromTimeToSamples(atof(token));
robert@464 439
robert@464 440 token = strtok(0, " "); // frame frequency
robert@464 441 prevFreq = atof(token);
robert@464 442 partials.partialFrequencies[parIndex][frameIndex] = (float)prevFreq;
robert@464 443 partials.partialFreqMean[parIndex] += prevFreq; // for frequency mean
robert@464 444
robert@464 445 token = strtok(0, " "); // frame amplitude
robert@464 446 prevAmp = atof(token);
robert@464 447 partials.partialAmplitudes[parIndex][frameIndex] = (float)prevAmp;
robert@464 448
robert@464 449 token = strtok(0, " "); // next frame frequency, to be checked
robert@464 450 }
robert@464 451
robert@464 452 // here the loop starts
robert@464 453 while(token) // all frames data are on one line, in groups of 3 entries
robert@464 454 {
robert@464 455 frameIndex++;
robert@464 456 missSampCnt = 0;
robert@464 457
robert@464 458 startSample = fromTimeToSamples(atof(token));
robert@464 459
robert@464 460 token = strtok(0, " "); // frame frequency
robert@464 461 freq = atof(token);
robert@464 462
robert@464 463 token = strtok(0, " "); // frame amplitude
robert@464 464 amp = atof(token);
robert@464 465 // now we know all about the current frame, but we want to know if some frames are missing between this and the last one
robert@464 466
robert@464 467 // while current frame sample is farther than one hopsize...
robert@464 468 while(startSample > endSample+hopSize)
robert@464 469 {
robert@464 470 missSampCnt++; // ...one sample is missing
robert@464 471 endSample += hopSize; // move to next hop
robert@464 472 }
robert@464 473
robert@464 474 // if frames are missing do interpolation and update indices
robert@464 475 if(missSampCnt>0)
robert@464 476 startSample = interpolateSamples(parIndex, &frameIndex, missSampCnt, endSample+hopSize, freq, amp, &prevFreq, &prevAmp);
robert@464 477
robert@464 478 partials.partialFrequencies[parIndex][frameIndex] = (float)freq;
robert@464 479 partials.partialFreqMean[parIndex] += freq; // for frequency mean
robert@464 480 partials.setFreqDelta(parIndex, frameIndex-1, (freq-prevFreq)/hopSize); // freq delta between prev and current frame
robert@464 481 prevFreq = freq;
robert@464 482
robert@464 483 partials.partialAmplitudes[parIndex][frameIndex] = (float)amp;
robert@464 484 partials.setAmpDelta(parIndex, frameIndex-1, (amp-prevAmp)/hopSize); // amp delta between prev and current frame
robert@464 485 prevAmp = amp;
robert@464 486
robert@464 487 endSample = startSample;
robert@464 488 token = strtok(0, " "); // next frame frequency, to be checked
robert@464 489 }
robert@464 490 #ifdef DO_CHECKS
robert@464 491 if(frameIndex != (frameNum-1))
robert@464 492 {
robert@464 493 cout << "Parser Error: frame count mismatch on partial " << parIndex << ", bad file format" << endl; // exit if mismatch
robert@464 494 cout << "frameIndex: " << frameIndex << endl;
robert@464 495 cout << "frameNum: " << frameNum << endl;
robert@464 496 return false;
robert@464 497 }
robert@464 498 #endif
robert@464 499
robert@464 500 partials.partialFreqMean[parIndex] /= partials.partialNumFrames[parIndex]; // frequency mean
robert@464 501
robert@464 502 getline(fin, s); // next partial line, to check
robert@464 503 }
robert@464 504 #ifdef DO_CHECKS
robert@464 505 if(parIndex != (parNum-1))
robert@464 506 {
robert@464 507 cout << "Parser Error: partial count mismatch, bad file format" << endl; // exit if mismatch
robert@464 508 return false;
robert@464 509 }
robert@464 510 #endif
robert@464 511
robert@464 512 partials.setHopNum(maxSample/hopSize);
robert@464 513
robert@464 514 gettimeofday(&stop, NULL);
robert@464 515 parserT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
robert@464 516
robert@464 517 gettimeofday(&start, NULL);
robert@464 518 staticCalculations();
robert@464 519 gettimeofday(&stop, NULL);
robert@464 520 staticT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
robert@464 521
robert@464 522 fin.close();
robert@464 523
robert@464 524
robert@464 525 printf("\n-----------------------\n");
robert@464 526 printf("\nFile: %s\n", filename);
robert@464 527 printf("\n-----------------------\n");
robert@464 528 printf("Profiler\n");
robert@464 529 printf("-----------------------\n");
robert@464 530 printf("Hop size parser:\t\t%lu usec\n", hopSizeT);
robert@464 531 printf("File parser:\t\t\t%lu usec\n", parserT);
robert@464 532 printf("Static calculations:\t\t%lu usec\n", staticT);
robert@464 533 printf("\n\nTotal:\t\t%lu usec\n", hopSizeT+parserT+staticT);
robert@464 534 printf("-----------------------\n");
robert@464 535
robert@464 536 return true;
robert@464 537 }
robert@464 538
robert@464 539
robert@464 540 int Spear_parser::interpolateSamples(int parIndex, int *frameIndex, int missCnt, int nextSample, double nextFreq, double nextAmp, double *prevFreq, double *prevAmp)
robert@464 541 {
robert@464 542 int frame = *frameIndex; // current frame index
robert@464 543 int sample = nextSample - (hopSize*(missCnt)); // move from next real frame sample to first missing frame sample
robert@464 544 double freq = *prevFreq; // freq of the prev real frame
robert@464 545 double freqStep = (nextFreq-*prevFreq)/(missCnt+1); // fixed freq step between hops, for missing frames [linear interpolation]
robert@464 546 double deltaFreq = freqStep/hopSize; // fixed hop freq step in samples
robert@464 547 double amp = *prevAmp; // same for amp...
robert@464 548 double ampStep = (nextAmp-*prevAmp)/(missCnt+1);
robert@464 549 double deltaAmp = ampStep/hopSize;
robert@464 550
robert@464 551 // for each missing frame
robert@464 552 for(int i=0; i<missCnt; i++)
robert@464 553 {
robert@464 554 // calculate values for current missing frame
robert@464 555 freq += freqStep;
robert@464 556 amp += ampStep;
robert@464 557 // save values
robert@464 558 partials.partialFrequencies[parIndex][frame] = freq;
robert@464 559 partials.partialAmplitudes[parIndex][frame] = amp;
robert@464 560 partials.partialFreqMean[parIndex] += freq; // for frequency mean
robert@464 561 // set deltas of previous frame [real or missing]
robert@464 562 partials.setFreqDelta(parIndex, frame-1, deltaFreq);
robert@464 563 partials.setAmpDelta(parIndex, frame-1, deltaAmp);
robert@464 564 // move to next frame [missing or real]
robert@464 565 sample += hopSize;
robert@464 566 frame++;
robert@464 567 }
robert@464 568
robert@464 569 // update global values
robert@464 570 *frameIndex = frame;
robert@464 571 *prevFreq = freq;
robert@464 572 *prevAmp = amp;
robert@464 573
robert@464 574 return sample; // return the frame sample of the next real frame
robert@464 575 }
robert@464 576
robert@464 577
robert@464 578
robert@464 579 // for each frame, statically calculate:
robert@464 580 // - which partial is active [and the total num of active partials]
robert@464 581 // - at which local frame each partial is
robert@464 582 void Spear_parser::staticCalculations()
robert@464 583 {
robert@464 584 partials.maxActiveParNum = 0; // init to find maximum
robert@464 585
robert@464 586 unsigned short *indices = new unsigned short[partials.parNum]; // temp array to store up to the maximum num of active partial indices
robert@464 587 unsigned int activeCnt = 0; // counts the num of active partials in each frame
robert@464 588
robert@464 589 unsigned int frameSample = 0; // current frame in samples
robert@464 590
robert@464 591 char *partialStarted = new char [partials.parNum]; // index of the last local frame found per each partial
robert@464 592 fill(partialStarted, partialStarted+partials.parNum, 0);
robert@464 593
robert@464 594 for(unsigned int i=0; i<partials.hopNum+1; i++) // for each frame [not hops, this explains the +1]
robert@464 595 {
robert@464 596 //partials.localPartialFrames[i] = new int[partials.parNum]; // init all local frames to -1
robert@464 597 //fill(partials.localPartialFrames[i], partials.localPartialFrames[i]+partials.parNum, -1);
robert@464 598
robert@464 599 frameSample = i*hopSize; // current frame, expressed in samples
robert@464 600 activeCnt = 0; // reset a each frame
robert@464 601
robert@464 602 for(unsigned int j=0; j<partials.parNum; j++) // for each partial
robert@464 603 {
robert@464 604 // check if inside active time region [expressed in samples]
robert@464 605 if( (frameSample>=partials.partialStartSample[j]) && (frameSample<partials.partialEndSample[j]) ) // frame sample not equal to end sample, this filters out last frames and partials with one frame only
robert@464 606 {
robert@464 607 // activity
robert@464 608 indices[activeCnt] = j; // save active index
robert@464 609 activeCnt++; // increase counter
robert@464 610
robert@464 611 // partial local frames
robert@464 612 if(partialStarted[j]==0) // this partial has just started, so current local frame is first frame
robert@464 613 {
robert@464 614 partialStarted[j] = 1;
robert@464 615 partials.partialStartFrame[j] = i; // here is the number of the first frame
robert@464 616 }
robert@464 617 }
robert@464 618 }
robert@464 619
robert@464 620 // activity
robert@464 621 partials.activePartialNum[i] = activeCnt; // save number of active partials for this frame
robert@464 622 partials.activePartials[i] = new unsigned int[activeCnt]; // set correct size to save all indices
robert@464 623
robert@464 624 // look for maximum number of active partials at the same time
robert@464 625 if(activeCnt > partials.maxActiveParNum)
robert@464 626 partials.maxActiveParNum = activeCnt;
robert@464 627
robert@464 628 // copy indices
robert@464 629 for(unsigned int k=0; k<activeCnt; k++)
robert@464 630 partials.activePartials[i][k] = indices[k];
robert@464 631 }
robert@464 632
robert@464 633 delete[] indices;
robert@464 634 delete[] partialStarted;
robert@464 635
robert@464 636 delete[] partials.partialStartSample;
robert@464 637 delete[] partials.partialEndSample;
robert@464 638 }
robert@464 639
robert@464 640
robert@464 641