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