andrewm@0: /* andrewm@0: * spear_parser.cpp v1.2 andrewm@0: * andrewm@0: * Created on: May 6, 2014 andrewm@0: * Author: Victor Zappi andrewm@0: */ andrewm@0: andrewm@0: #include "spear_parser.h" andrewm@0: andrewm@0: using namespace std; andrewm@0: andrewm@0: //#define DO_CHECKS andrewm@0: andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: // partials andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: andrewm@0: Partials::Partials() andrewm@0: { andrewm@0: partialFrequencies = NULL; andrewm@0: // partialAmplitudes = NULL; andrewm@0: // partialNumFrames = NULL; andrewm@0: // partialStartSample = NULL; andrewm@0: // partialEndSample = NULL; andrewm@0: // partialCurrentFrame = NULL; andrewm@0: // partialFreqDelta = NULL; andrewm@0: // partialAmpDelta = NULL; andrewm@0: andrewm@0: andrewm@0: activePartialNum = NULL; andrewm@0: // activePartials = NULL; andrewm@0: andrewm@0: currentSample = -1; andrewm@0: } andrewm@0: andrewm@0: Partials::~Partials() andrewm@0: { andrewm@0: if(partialFrequencies != NULL) // check on one is enough andrewm@0: { andrewm@0: if(partialFrequencies[0] != NULL) // check on one is enough andrewm@0: { andrewm@0: for(unsigned int i=0; i maxSample) andrewm@0: maxSample = endSample; andrewm@0: andrewm@0: // update data structure andrewm@0: partials.update(parIndex, frameNum); andrewm@0: andrewm@0: andrewm@0: //------------------------------------- andrewm@0: // frames andrewm@0: getline(fin, s); andrewm@0: token = strtok((char *)s.c_str(), " "); // frame time andrewm@0: frameIndex = -1; andrewm@0: andrewm@0: // unroll first iteration, so that in the following loop we save the check on the last frame to calculate increments andrewm@0: if(token) // all frames data are on one line, in groups of 3 entries andrewm@0: { andrewm@0: frameIndex++; andrewm@0: andrewm@0: endSample = fromTimeToSamples(atof(token)); andrewm@0: andrewm@0: token = strtok(0, " "); // frame frequency andrewm@0: prevFreq = atof(token); andrewm@0: partials.partialFrequencies[parIndex][frameIndex] = (float)prevFreq; andrewm@0: partials.partialFreqMean[parIndex] += prevFreq; // for frequency mean andrewm@0: andrewm@0: token = strtok(0, " "); // frame amplitude andrewm@0: prevAmp = atof(token); andrewm@0: partials.partialAmplitudes[parIndex][frameIndex] = (float)prevAmp; andrewm@0: andrewm@0: token = strtok(0, " "); // next frame frequency, to be checked andrewm@0: } andrewm@0: andrewm@0: // here the loop starts andrewm@0: while(token) // all frames data are on one line, in groups of 3 entries andrewm@0: { andrewm@0: frameIndex++; andrewm@0: missSampCnt = 0; andrewm@0: andrewm@0: startSample = fromTimeToSamples(atof(token)); andrewm@0: andrewm@0: token = strtok(0, " "); // frame frequency andrewm@0: freq = atof(token); andrewm@0: andrewm@0: token = strtok(0, " "); // frame amplitude andrewm@0: amp = atof(token); andrewm@0: // 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: andrewm@0: // while current frame sample is farther than one hopsize... andrewm@0: while(startSample > endSample+hopSize) andrewm@0: { andrewm@0: missSampCnt++; // ...one sample is missing andrewm@0: endSample += hopSize; // move to next hop andrewm@0: } andrewm@0: andrewm@0: // if frames are missing do interpolation and update indices andrewm@0: if(missSampCnt>0) andrewm@0: startSample = interpolateSamples(parIndex, &frameIndex, missSampCnt, endSample+hopSize, freq, amp, &prevFreq, &prevAmp); andrewm@0: andrewm@0: partials.partialFrequencies[parIndex][frameIndex] = (float)freq; andrewm@0: partials.partialFreqMean[parIndex] += freq; // for frequency mean andrewm@0: partials.setFreqDelta(parIndex, frameIndex-1, (freq-prevFreq)/hopSize); // freq delta between prev and current frame andrewm@0: prevFreq = freq; andrewm@0: andrewm@0: partials.partialAmplitudes[parIndex][frameIndex] = (float)amp; andrewm@0: partials.setAmpDelta(parIndex, frameIndex-1, (amp-prevAmp)/hopSize); // amp delta between prev and current frame andrewm@0: prevAmp = amp; andrewm@0: andrewm@0: endSample = startSample; andrewm@0: token = strtok(0, " "); // next frame frequency, to be checked andrewm@0: } andrewm@0: #ifdef DO_CHECKS andrewm@0: if(frameIndex != (frameNum-1)) andrewm@0: { andrewm@0: cout << "Parser Error: frame count mismatch on partial " << parIndex << ", bad file format" << endl; // exit if mismatch andrewm@0: cout << "frameIndex: " << frameIndex << endl; andrewm@0: cout << "frameNum: " << frameNum << endl; andrewm@0: return false; andrewm@0: } andrewm@0: #endif andrewm@0: andrewm@0: partials.partialFreqMean[parIndex] /= partials.partialNumFrames[parIndex]; // frequency mean andrewm@0: andrewm@0: getline(fin, s); // next partial line, to check andrewm@0: } andrewm@0: #ifdef DO_CHECKS andrewm@0: if(parIndex != (parNum-1)) andrewm@0: { andrewm@0: cout << "Parser Error: partial count mismatch, bad file format" << endl; // exit if mismatch andrewm@0: return false; andrewm@0: } andrewm@0: #endif andrewm@0: andrewm@0: partials.setHopNum(maxSample/hopSize); andrewm@0: andrewm@0: gettimeofday(&stop, NULL); andrewm@0: parserT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) ); andrewm@0: andrewm@0: gettimeofday(&start, NULL); andrewm@0: staticCalculations(); andrewm@0: gettimeofday(&stop, NULL); andrewm@0: staticT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) ); andrewm@0: andrewm@0: fin.close(); andrewm@0: andrewm@0: andrewm@0: printf("\n-----------------------\n"); andrewm@0: printf("\nFile: %s\n", filename); andrewm@0: printf("\n-----------------------\n"); andrewm@0: printf("Profiler\n"); andrewm@0: printf("-----------------------\n"); andrewm@0: printf("Hop size parser:\t\t%lu usec\n", hopSizeT); andrewm@0: printf("File parser:\t\t\t%lu usec\n", parserT); andrewm@0: printf("Static calculations:\t\t%lu usec\n", staticT); andrewm@0: printf("\n\nTotal:\t\t%lu usec\n", hopSizeT+parserT+staticT); andrewm@0: printf("-----------------------\n"); andrewm@0: andrewm@0: return true; andrewm@0: } andrewm@0: andrewm@0: andrewm@0: int Spear_parser::interpolateSamples(int parIndex, int *frameIndex, int missCnt, int nextSample, double nextFreq, double nextAmp, double *prevFreq, double *prevAmp) andrewm@0: { andrewm@0: int frame = *frameIndex; // current frame index andrewm@0: int sample = nextSample - (hopSize*(missCnt)); // move from next real frame sample to first missing frame sample andrewm@0: double freq = *prevFreq; // freq of the prev real frame andrewm@0: double freqStep = (nextFreq-*prevFreq)/(missCnt+1); // fixed freq step between hops, for missing frames [linear interpolation] andrewm@0: double deltaFreq = freqStep/hopSize; // fixed hop freq step in samples andrewm@0: double amp = *prevAmp; // same for amp... andrewm@0: double ampStep = (nextAmp-*prevAmp)/(missCnt+1); andrewm@0: double deltaAmp = ampStep/hopSize; andrewm@0: andrewm@0: // for each missing frame andrewm@0: for(int i=0; i=partials.partialStartSample[j]) && (frameSample partials.maxActiveParNum) andrewm@0: partials.maxActiveParNum = activeCnt; andrewm@0: andrewm@0: // copy indices andrewm@0: for(unsigned int k=0; k