annotate projects/d-box/spear_parser.cpp @ 43:4cd9a8ca5745 staging

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