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<parNum; i++) andrewm@0: { andrewm@0: delete[] partialFrequencies[i]; andrewm@0: delete[] partialAmplitudes[i]; andrewm@0: delete[] partialFreqDelta[i]; andrewm@0: delete[] partialAmpDelta[i]; andrewm@0: andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: delete[] partialFrequencies; andrewm@0: delete[] partialAmplitudes; andrewm@0: delete[] partialNumFrames; andrewm@0: delete[] partialFreqDelta; andrewm@0: delete[] partialAmpDelta; andrewm@0: delete[] partialFreqMean; andrewm@0: } andrewm@0: andrewm@0: if(activePartialNum != NULL) andrewm@0: { andrewm@0: for(unsigned int i=0; i<hopNum+1; i++) andrewm@0: delete[] activePartials[i]; andrewm@0: andrewm@0: delete[] activePartialNum; andrewm@0: delete[] activePartials ; andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: void Partials::init(int parN, int hopS, bool isDBX) andrewm@0: { andrewm@0: if(!isDBX) andrewm@0: { andrewm@0: parNum = parN; andrewm@0: hopSize = hopS; andrewm@0: andrewm@0: partialFrequencies = new float *[parNum]; andrewm@0: partialAmplitudes = new float *[parNum]; andrewm@0: partialNumFrames = new unsigned int[parNum]; andrewm@0: partialStartFrame = new unsigned int[parNum]; andrewm@0: partialStartSample = new unsigned int[parNum]; andrewm@0: partialEndSample = new unsigned int[parNum]; andrewm@0: partialFreqDelta = new float *[parNum]; andrewm@0: partialAmpDelta = new float *[parNum]; andrewm@0: partialFreqMean = new float[parNum]; andrewm@0: andrewm@0: andrewm@0: andrewm@0: // init in one shot andrewm@0: fill(partialFreqMean, partialFreqMean+parNum, 0); // mean is zero andrewm@0: andrewm@0: partialFrequencies[0] = NULL; // for free check andrewm@0: } andrewm@0: else andrewm@0: { andrewm@0: parNum = parN; andrewm@0: hopSize = hopS; andrewm@0: andrewm@0: partialFrequencies = new float *[parNum]; andrewm@0: partialAmplitudes = new float *[parNum]; andrewm@0: partialNumFrames = new unsigned int[parNum]; andrewm@0: partialStartFrame = new unsigned int[parNum]; andrewm@0: partialFreqDelta = new float *[parNum]; andrewm@0: partialAmpDelta = new float *[parNum]; andrewm@0: partialFreqMean = new float[parNum]; andrewm@0: andrewm@0: partialFrequencies[0] = NULL; // for free check andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: void Partials::update(int parIndex, int frameNum) andrewm@0: { andrewm@0: partialFrequencies[parIndex] = new float[frameNum]; andrewm@0: partialAmplitudes[parIndex] = new float[frameNum]; andrewm@0: partialFreqDelta[parIndex] = new float[frameNum]; andrewm@0: partialAmpDelta[parIndex] = new float[frameNum]; andrewm@0: andrewm@0: fill(partialFreqDelta[parIndex], partialFreqDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999 andrewm@0: fill(partialAmpDelta[parIndex], partialAmpDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999 andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: // spear parser andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: Spear_parser::Spear_parser() andrewm@0: { andrewm@0: // some default values andrewm@0: hopSize = -1; andrewm@0: fileSampleRate = -1; andrewm@0: } andrewm@0: andrewm@0: Spear_parser::~Spear_parser() andrewm@0: { andrewm@0: } andrewm@0: andrewm@0: void Spear_parser::calculateHopSize(char *filename) andrewm@0: { andrewm@0: int index = 0; andrewm@0: bool prevWas_ = false; andrewm@0: bool found_h = false; andrewm@0: int n = 0; andrewm@0: andrewm@0: hopSize = 0; andrewm@0: andrewm@0: do andrewm@0: { andrewm@0: // check if '_' andrewm@0: if(filename[index] == '_') andrewm@0: prevWas_ = true; andrewm@0: else if( (filename[index] == 'h') && prevWas_) // if it is not, but it is 'h' and previous was '_', found "_h"! andrewm@0: { andrewm@0: found_h = true; andrewm@0: while(filename[index] != '\0') andrewm@0: { andrewm@0: index++; andrewm@0: if( (filename[index] == '.') || (filename[index] == '_')) andrewm@0: break; andrewm@0: else // i am not checking if char are digits...! andrewm@0: { andrewm@0: n = filename[index]; andrewm@0: hopSize = hopSize*10+(n-48); andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: else // else, nothing andrewm@0: prevWas_ = false; andrewm@0: index++; andrewm@0: } andrewm@0: while( (filename[index] != '\0') && !found_h ); andrewm@0: andrewm@0: if( !found_h || (hopSize<1) ) andrewm@0: hopSize = 551; // default val andrewm@0: andrewm@0: } andrewm@0: andrewm@0: andrewm@0: bool Spear_parser::parser(char *filename, int hopsize, int samplerate) andrewm@0: { andrewm@0: string name = string(filename); andrewm@0: int len = name.length(); andrewm@0: // invoke correct parser according to the type of file...just checking the extension, crude but functional andrewm@0: if( (name[len-4]=='.') && (name[len-3]=='d') && (name[len-2]=='b') && (name[len-1]=='x') ) andrewm@0: return DBXparser(filename, samplerate); // .dbox andrewm@0: else andrewm@0: return TXTparser(filename, hopSize, samplerate); // .txt, or whatever andrewm@0: } andrewm@0: andrewm@0: andrewm@0: bool Spear_parser::DBXparser(char *filename, int samplerate) andrewm@0: { andrewm@0: fileSampleRate = samplerate; andrewm@0: andrewm@0: // working vars andrewm@0: int parNum = 0; // total num of partials andrewm@0: int hopNum = 0; // total num of hops andrewm@0: andrewm@0: //---------------------------------------------------------------------------------------- andrewm@0: // open a file andrewm@0: ifstream fin; andrewm@0: fin.open(filename, ios::in | ios::binary); andrewm@0: if (!fin.good()) andrewm@0: { andrewm@0: cout << "Parser Error: file not found" << endl; // exit if file not found andrewm@0: return false; andrewm@0: } andrewm@0: andrewm@0: gettimeofday(&start, NULL); andrewm@0: //---------------------------------------------------------------------------------------- andrewm@0: // general data andrewm@0: andrewm@0: // look for partial count andrewm@0: fin.read((char *) &parNum, sizeof(int)); andrewm@0: partials.parNum = parNum; andrewm@0: andrewm@0: // look for hop count andrewm@0: fin.read((char *) &hopNum, sizeof(int)); andrewm@0: partials.setHopNum(hopNum); andrewm@0: andrewm@0: // look for hop size andrewm@0: fin.read((char *) &hopSize, sizeof(int)); andrewm@0: partials.hopSize = hopSize; // it's handy for both classes to know it andrewm@0: andrewm@0: // init partials data structure andrewm@0: partials.init(parNum, hopSize, true); andrewm@0: andrewm@0: // look for max active par num andrewm@0: fin.read((char *) &(partials.maxActiveParNum), sizeof(int)); andrewm@0: andrewm@0: andrewm@0: andrewm@0: // partial data andrewm@0: andrewm@0: // start frame of each partial andrewm@0: fin.read((char *) partials.partialStartFrame, sizeof(int)*parNum); andrewm@0: andrewm@0: // num of frames of each partial andrewm@0: fin.read((char *) partials.partialNumFrames, sizeof(int)*parNum); andrewm@0: andrewm@0: // frequency mean of each partial andrewm@0: fin.read((char *) partials.partialFreqMean, sizeof(int)*parNum); andrewm@0: andrewm@0: for(int par=0; par<parNum; par++) andrewm@0: { andrewm@0: int frameNum = partials.partialNumFrames[par]; andrewm@0: partials.update(par, frameNum); andrewm@0: fin.read((char *)partials.partialAmplitudes[par], sizeof(float)*frameNum); // amplitude of each partial in each frame andrewm@0: fin.read((char *)partials.partialFrequencies[par], sizeof(float)*frameNum); // frequency of each partial in each frame andrewm@0: fin.read((char *)partials.partialAmpDelta[par], sizeof(float)*frameNum); // amplitude delta of each partial in each frame andrewm@0: fin.read((char *)partials.partialFreqDelta[par], sizeof(float)*frameNum); // frequency delta of each partial in each frame andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: // frame data andrewm@0: andrewm@0: // number of active partial per each frame andrewm@0: fin.read((char *) partials.activePartialNum, sizeof(short)*(hopNum+1)); andrewm@0: // init array andrewm@0: for(int frame=0; frame<hopNum+1; frame++) andrewm@0: { andrewm@0: partials.activePartials[frame] = new unsigned int[partials.activePartialNum[frame]]; andrewm@0: fin.read((char *)partials.activePartials[frame], sizeof(int)*partials.activePartialNum[frame]); // active partials per each frame andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: 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: 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("File parser:\t\t\t%lu usec\n", parserT); andrewm@0: printf("\n\nTotal:\t\t%lu usec\n", parserT); andrewm@0: printf("-----------------------\n"); andrewm@0: andrewm@0: fin.close(); andrewm@0: andrewm@0: return true; andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: andrewm@0: bool Spear_parser::TXTparser(char *filename, int hopsize, int samplerate) andrewm@0: { andrewm@0: hopSize = hopsize; andrewm@0: fileSampleRate = samplerate; andrewm@0: if(hopsize<0) andrewm@0: { andrewm@0: gettimeofday(&start, NULL); andrewm@0: calculateHopSize(filename); andrewm@0: gettimeofday(&stop, NULL); andrewm@0: hopSizeT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) ); andrewm@0: } andrewm@0: else andrewm@0: hopSizeT = 0; andrewm@0: andrewm@0: calculateDeltaTime(); andrewm@0: andrewm@0: // working vars andrewm@0: char * token; // where to save single figures from file andrewm@0: string s = ""; // where to save lines from file andrewm@0: int parNum = 0; // total num of partials andrewm@0: int parIndex = -1; // index of current partial andrewm@0: int frameNum = 0; // total num of frames andrewm@0: int frameIndex = -1; // index of current frame andrewm@0: int startSample = -1; // sample value for first frame of partials andrewm@0: int endSample = -1; // sample value for last frame of partials andrewm@0: int maxSample = 0; // to calculate total number of hops in file andrewm@0: int missSampCnt = 0; // number of mising samples andrewm@0: double freq = 0; // to calculate frequency delta andrewm@0: double prevFreq = 0; // to calculate frequency delta andrewm@0: double amp = 0; // to calculate amplitude delta andrewm@0: double prevAmp = 0; // to calculate amplitude delta andrewm@0: andrewm@0: andrewm@0: //---------------------------------------------------------------------------------------- andrewm@0: // open a file andrewm@0: ifstream fin; andrewm@0: fin.open(filename); andrewm@0: if (!fin.good()) andrewm@0: { andrewm@0: cout << "Parser Error: file not found" << endl; // exit if file not found andrewm@0: return false; andrewm@0: } andrewm@0: andrewm@0: gettimeofday(&start, NULL); andrewm@0: //---------------------------------------------------------------------------------------- andrewm@0: // init partials data structure andrewm@0: getline(fin, s); andrewm@0: getline(fin, s); andrewm@0: getline(fin, s); // third line is the first we are interested into andrewm@0: andrewm@0: // look for partial count andrewm@0: token = strtok((char *)s.c_str(), " "); andrewm@0: // check if first token is there andrewm@0: if(token) andrewm@0: { andrewm@0: token = strtok(0, " "); andrewm@0: // check if second token is there andrewm@0: if(token) andrewm@0: parNum = atoi(token); andrewm@0: #ifdef DO_CHECKS andrewm@0: else andrewm@0: { andrewm@0: cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found andrewm@0: return false; andrewm@0: } andrewm@0: #endif andrewm@0: } andrewm@0: #ifdef DO_CHECKS andrewm@0: else andrewm@0: { andrewm@0: cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found andrewm@0: return false; andrewm@0: } andrewm@0: #endif andrewm@0: // from now on we take for granted that format is correct andrewm@0: andrewm@0: // init partials data structure andrewm@0: partials.init(parNum, hopSize); andrewm@0: andrewm@0: //---------------------------------------------------------------------------------------- andrewm@0: // fill in partials data structure andrewm@0: getline(fin, s); // get rid of intro line "partials-data" andrewm@0: getline(fin, s); // first important line andrewm@0: andrewm@0: while (!fin.eof()) andrewm@0: { andrewm@0: //------------------------------------- andrewm@0: // partial specific info andrewm@0: token = strtok((char *)s.c_str(), " "); andrewm@0: parIndex = atoi(token); // partial index andrewm@0: andrewm@0: token = strtok(0, " "); // num of frames, not used, cos we will do linear interpolation for missing frames andrewm@0: // frameNum = atoi(token); andrewm@0: // partials.partialNumFrames[parIndex] = frameNum; andrewm@0: andrewm@0: token = strtok(0, " "); // time of first frame, still char * andrewm@0: startSample = fromTimeToSamples(atof(token)); // convert time to samples andrewm@0: partials.partialStartSample[parIndex] = startSample; andrewm@0: andrewm@0: token = strtok(0, " "); // time of last frame, still char * andrewm@0: endSample = fromTimeToSamples(atof(token)); // convert time to samples andrewm@0: partials.partialEndSample[parIndex] = endSample; andrewm@0: andrewm@0: frameNum = ((endSample-startSample)/hopSize) + 1; // num of frames, including missing consecutive ones [+1 one cos we count frames, not hops] andrewm@0: partials.partialNumFrames[parIndex] = frameNum; andrewm@0: andrewm@0: andrewm@0: // check if this is the highest sample value so far andrewm@0: if(endSample > 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<missCnt; i++) andrewm@0: { andrewm@0: // calculate values for current missing frame andrewm@0: freq += freqStep; andrewm@0: amp += ampStep; andrewm@0: // save values andrewm@0: partials.partialFrequencies[parIndex][frame] = freq; andrewm@0: partials.partialAmplitudes[parIndex][frame] = amp; andrewm@0: partials.partialFreqMean[parIndex] += freq; // for frequency mean andrewm@0: // set deltas of previous frame [real or missing] andrewm@0: partials.setFreqDelta(parIndex, frame-1, deltaFreq); andrewm@0: partials.setAmpDelta(parIndex, frame-1, deltaAmp); andrewm@0: // move to next frame [missing or real] andrewm@0: sample += hopSize; andrewm@0: frame++; andrewm@0: } andrewm@0: andrewm@0: // update global values andrewm@0: *frameIndex = frame; andrewm@0: *prevFreq = freq; andrewm@0: *prevAmp = amp; andrewm@0: andrewm@0: return sample; // return the frame sample of the next real frame andrewm@0: } andrewm@0: andrewm@0: andrewm@0: andrewm@0: // for each frame, statically calculate: andrewm@0: // - which partial is active [and the total num of active partials] andrewm@0: // - at which local frame each partial is andrewm@0: void Spear_parser::staticCalculations() andrewm@0: { andrewm@0: partials.maxActiveParNum = 0; // init to find maximum andrewm@0: andrewm@0: unsigned short *indices = new unsigned short[partials.parNum]; // temp array to store up to the maximum num of active partial indices andrewm@0: unsigned int activeCnt = 0; // counts the num of active partials in each frame andrewm@0: andrewm@0: unsigned int frameSample = 0; // current frame in samples andrewm@0: andrewm@0: char *partialStarted = new char [partials.parNum]; // index of the last local frame found per each partial andrewm@0: fill(partialStarted, partialStarted+partials.parNum, 0); andrewm@0: andrewm@0: for(unsigned int i=0; i<partials.hopNum+1; i++) // for each frame [not hops, this explains the +1] andrewm@0: { andrewm@0: //partials.localPartialFrames[i] = new int[partials.parNum]; // init all local frames to -1 andrewm@0: //fill(partials.localPartialFrames[i], partials.localPartialFrames[i]+partials.parNum, -1); andrewm@0: andrewm@0: frameSample = i*hopSize; // current frame, expressed in samples andrewm@0: activeCnt = 0; // reset a each frame andrewm@0: andrewm@0: for(unsigned int j=0; j<partials.parNum; j++) // for each partial andrewm@0: { andrewm@0: // check if inside active time region [expressed in samples] andrewm@0: 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: { andrewm@0: // activity andrewm@0: indices[activeCnt] = j; // save active index andrewm@0: activeCnt++; // increase counter andrewm@0: andrewm@0: // partial local frames andrewm@0: if(partialStarted[j]==0) // this partial has just started, so current local frame is first frame andrewm@0: { andrewm@0: partialStarted[j] = 1; andrewm@0: partials.partialStartFrame[j] = i; // here is the number of the first frame andrewm@0: } andrewm@0: } andrewm@0: } andrewm@0: andrewm@0: // activity andrewm@0: partials.activePartialNum[i] = activeCnt; // save number of active partials for this frame andrewm@0: partials.activePartials[i] = new unsigned int[activeCnt]; // set correct size to save all indices andrewm@0: andrewm@0: // look for maximum number of active partials at the same time andrewm@0: if(activeCnt > partials.maxActiveParNum) andrewm@0: partials.maxActiveParNum = activeCnt; andrewm@0: andrewm@0: // copy indices andrewm@0: for(unsigned int k=0; k<activeCnt; k++) andrewm@0: partials.activePartials[i][k] = indices[k]; andrewm@0: } andrewm@0: andrewm@0: delete[] indices; andrewm@0: delete[] partialStarted; andrewm@0: andrewm@0: delete[] partials.partialStartSample; andrewm@0: delete[] partials.partialEndSample; andrewm@0: } andrewm@0: andrewm@0: andrewm@0: