andrewm@0: /* andrewm@0: * spear_parser.h v1.2 andrewm@0: * andrewm@0: * Created on: May 6, 2014 andrewm@0: * Author: Victor Zappi andrewm@0: */ andrewm@0: andrewm@0: #ifndef SPEAR_PARSER_H_ andrewm@0: #define SPEAR_PARSER_H_ andrewm@0: andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: #include // atoi, atof andrewm@0: #include andrewm@0: #include // std::fill andrewm@0: andrewm@0: #include andrewm@0: andrewm@0: using namespace std; andrewm@0: andrewm@0: andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: // partials andrewm@0: //------------------------------------------------------------------------------------------------ andrewm@0: andrewm@0: class Spear_parser; // for class friendship andrewm@0: andrewm@0: class Partials andrewm@0: { andrewm@0: friend class Spear_parser; andrewm@0: friend class Dbox_parser; andrewm@0: andrewm@0: public: andrewm@0: int **partialSamples; // sample at which each frame is andrewm@0: float **partialFrequencies; // frequencies at each frame andrewm@0: float **partialAmplitudes; // amplitudes at each frame andrewm@0: unsigned int *partialNumFrames; // Length of each partial in frames andrewm@0: unsigned int *partialStartFrame; // frame at which each partial begins andrewm@0: float **partialFreqDelta; // constant frequency slope for each partial in each frame interval andrewm@0: float **partialAmpDelta; // constant amplitude slope for each partial in each frame interval andrewm@0: float *partialFreqMean; // frequency mean for each partial, over all its frames andrewm@0: andrewm@0: unsigned short *activePartialNum; // num of each active partial at each frame andrewm@0: unsigned int **activePartials; // indices of all active partials at each frame andrewm@0: andrewm@0: andrewm@0: int getPartialNum(); andrewm@0: int getHopNum(); andrewm@0: int getMaxActivePartialNum(); andrewm@0: andrewm@0: private: andrewm@0: Partials(); andrewm@0: ~Partials(); andrewm@0: andrewm@0: unsigned int *partialStartSample; // sample at which each partial begins andrewm@0: unsigned int *partialEndSample; // sample at which each partial ends [sample gap between 2 consecutive frames can be an integer multiple of hopSize] andrewm@0: unsigned int parNum; andrewm@0: unsigned int currentSample; andrewm@0: unsigned int hopSize; andrewm@0: unsigned int hopNum; andrewm@0: unsigned int maxActiveParNum; andrewm@0: andrewm@0: void init(int parNum, int hopSize, bool isDBX=false); andrewm@0: void update(int parIndex, int frameNum); andrewm@0: void setFreqDelta(int parIndex, int frameNum, double delta); andrewm@0: void setAmpDelta(int parIndex, int frameNum, double delta); andrewm@0: void setHopNum(int hopNum); andrewm@0: }; andrewm@0: andrewm@0: inline int Partials::getPartialNum() andrewm@0: { andrewm@0: return parNum; andrewm@0: } andrewm@0: andrewm@0: inline void Partials::setHopNum(int hopN) andrewm@0: { andrewm@0: hopNum = hopN; andrewm@0: andrewm@0: // prepare data structures andrewm@0: activePartialNum = new unsigned short[hopNum+1]; // +1 cos total num of frames = num of hops+1 andrewm@0: activePartials = new unsigned int *[hopNum+1]; andrewm@0: } andrewm@0: andrewm@0: // useful to increase current sample using a modulo on the total number of samples [easy to be deduced from the total num or hops] andrewm@0: inline int Partials::getHopNum() andrewm@0: { andrewm@0: return hopNum; andrewm@0: } andrewm@0: andrewm@0: inline void Partials::setFreqDelta(int parIndex, int frameNum, double delta) andrewm@0: { andrewm@0: partialFreqDelta[parIndex][frameNum] = delta; andrewm@0: } andrewm@0: andrewm@0: inline void Partials::setAmpDelta(int parIndex, int frameNum, double delta) andrewm@0: { andrewm@0: partialAmpDelta[parIndex][frameNum] = delta; andrewm@0: } andrewm@0: andrewm@0: inline int Partials::getMaxActivePartialNum() andrewm@0: { andrewm@0: return maxActiveParNum; 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: andrewm@0: class Spear_parser andrewm@0: { andrewm@0: public: andrewm@0: Spear_parser(); andrewm@0: ~Spear_parser(); andrewm@0: andrewm@0: Partials partials; andrewm@0: andrewm@0: bool parseFile(string filename, int hopsize=-1, int samplerate = 44100); andrewm@0: bool parseFile(char *filename, int hopsize=-1, int samplerate = 44100); andrewm@0: int getHopSize(); andrewm@0: int getFileSampleRate(); andrewm@0: double getDeltaTime(); andrewm@0: andrewm@0: private: andrewm@0: andrewm@0: int hopSize; andrewm@0: int fileSampleRate; andrewm@0: double deltaTime; // min time gap between consecutive frames andrewm@0: andrewm@0: timeval start, stop; andrewm@0: unsigned long hopSizeT, parserT, staticT; andrewm@0: andrewm@0: void calculateDeltaTime(); andrewm@0: void calculateHopSize(char *filename); andrewm@0: bool parser(char *filename, int hopsize=-1, int samplerate=44100); andrewm@0: bool DBXparser(char *filename, int samplerate=44100); andrewm@0: bool TXTparser(char *filename, int hopsize=-1, int samplerate=44100); andrewm@0: int fromTimeToSamples(float time); andrewm@0: int interpolateSamples(int parIndex, int *frameIndex, int missCnt, int nextSample, andrewm@0: double nextFreq, double nextAmp, double *prevFreq, double *prevAmp); andrewm@0: void staticCalculations(); andrewm@0: andrewm@0: }; andrewm@0: andrewm@0: inline bool Spear_parser::parseFile(string filename, int hopsize, int samplerate) andrewm@0: { andrewm@0: return parser((char *)filename.c_str(), hopsize, samplerate); andrewm@0: } andrewm@0: andrewm@0: inline bool Spear_parser::parseFile(char *filename, int hopsize, int samplerate) andrewm@0: { andrewm@0: return parser(filename, hopsize, samplerate); andrewm@0: } andrewm@0: andrewm@0: inline void Spear_parser::calculateDeltaTime() andrewm@0: { andrewm@0: deltaTime = (double)hopSize/ (double)fileSampleRate; andrewm@0: } andrewm@0: andrewm@0: // each time value in the file is rounded, and 2 consecutive frames can differ of a time gap = i*deltaTime, where i is a positive integer andrewm@0: inline int Spear_parser::fromTimeToSamples(float time) andrewm@0: { andrewm@0: return round(time/deltaTime)*hopSize; // round is necessary since in the file log time values are rounded, so they do not apparently look like integer multiples of deltaTime andrewm@0: } andrewm@0: andrewm@0: inline int Spear_parser::getHopSize() andrewm@0: { andrewm@0: return hopSize; andrewm@0: } andrewm@0: andrewm@0: inline int Spear_parser::getFileSampleRate() andrewm@0: { andrewm@0: return fileSampleRate; andrewm@0: } andrewm@0: andrewm@0: inline double Spear_parser::getDeltaTime() andrewm@0: { andrewm@0: return deltaTime; andrewm@0: } andrewm@0: andrewm@0: #endif /* SPEAR_PARSER_H_ */