| andrewm@0 | 1 /* | 
| andrewm@0 | 2  * spear_parser.h 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 #ifndef SPEAR_PARSER_H_ | 
| andrewm@0 | 9 #define SPEAR_PARSER_H_ | 
| andrewm@0 | 10 | 
| andrewm@0 | 11 #include <iostream> | 
| andrewm@0 | 12 #include <fstream> | 
| andrewm@0 | 13 #include <cstring> | 
| andrewm@0 | 14 #include <string> | 
| andrewm@0 | 15 #include <stdlib.h>		// atoi, atof | 
| andrewm@0 | 16 #include <math.h> | 
| andrewm@0 | 17 #include <algorithm>	// std::fill | 
| andrewm@0 | 18 | 
| andrewm@0 | 19 #include <sys/time.h> | 
| andrewm@0 | 20 | 
| andrewm@0 | 21 using namespace std; | 
| andrewm@0 | 22 | 
| andrewm@0 | 23 | 
| andrewm@0 | 24 //------------------------------------------------------------------------------------------------ | 
| andrewm@0 | 25 // partials | 
| andrewm@0 | 26 //------------------------------------------------------------------------------------------------ | 
| andrewm@0 | 27 | 
| andrewm@0 | 28 class Spear_parser; // for class friendship | 
| andrewm@0 | 29 | 
| andrewm@0 | 30 class Partials | 
| andrewm@0 | 31 { | 
| andrewm@0 | 32 	friend class Spear_parser; | 
| andrewm@0 | 33 	friend class Dbox_parser; | 
| andrewm@0 | 34 | 
| andrewm@0 | 35 public: | 
| andrewm@0 | 36 	int **partialSamples;				// sample at which each frame is | 
| andrewm@0 | 37 	float **partialFrequencies;			// frequencies at each frame | 
| andrewm@0 | 38 	float **partialAmplitudes;			// amplitudes at each frame | 
| andrewm@0 | 39 	unsigned int *partialNumFrames;		// Length of each partial in frames | 
| andrewm@0 | 40 	unsigned int *partialStartFrame;	// frame at which each partial begins | 
| andrewm@0 | 41 	float **partialFreqDelta;			// constant frequency slope for each partial in each frame interval | 
| andrewm@0 | 42 	float **partialAmpDelta;			// constant amplitude slope for each partial in each frame interval | 
| andrewm@0 | 43 	float *partialFreqMean;				// frequency mean for each partial, over all its frames | 
| andrewm@0 | 44 | 
| andrewm@0 | 45 	unsigned short *activePartialNum;	// num of each active partial at each frame | 
| andrewm@0 | 46 	unsigned int **activePartials;		// indices of all active partials at each frame | 
| andrewm@0 | 47 | 
| andrewm@0 | 48 | 
| andrewm@0 | 49 	int getPartialNum(); | 
| andrewm@0 | 50 	int getHopNum(); | 
| andrewm@0 | 51 	int getMaxActivePartialNum(); | 
| andrewm@0 | 52 | 
| andrewm@0 | 53 private: | 
| andrewm@0 | 54 	Partials(); | 
| andrewm@0 | 55 	~Partials(); | 
| andrewm@0 | 56 | 
| andrewm@0 | 57 	unsigned int *partialStartSample;	// sample at which each partial begins | 
| andrewm@0 | 58 	unsigned int *partialEndSample;		// sample at which each partial ends [sample gap between 2 consecutive frames can be an integer multiple of hopSize] | 
| andrewm@0 | 59 	unsigned int parNum; | 
| andrewm@0 | 60 	unsigned int currentSample; | 
| andrewm@0 | 61 	unsigned int hopSize; | 
| andrewm@0 | 62 	unsigned int hopNum; | 
| andrewm@0 | 63 	unsigned int maxActiveParNum; | 
| andrewm@0 | 64 | 
| andrewm@0 | 65 	void init(int parNum, int hopSize, bool isDBX=false); | 
| andrewm@0 | 66 	void update(int parIndex, int frameNum); | 
| andrewm@0 | 67 	void setFreqDelta(int parIndex, int frameNum, double delta); | 
| andrewm@0 | 68 	void setAmpDelta(int parIndex, int frameNum, double delta); | 
| andrewm@0 | 69 	void setHopNum(int hopNum); | 
| andrewm@0 | 70 }; | 
| andrewm@0 | 71 | 
| andrewm@0 | 72 inline int Partials::getPartialNum() | 
| andrewm@0 | 73 { | 
| andrewm@0 | 74 	return parNum; | 
| andrewm@0 | 75 } | 
| andrewm@0 | 76 | 
| andrewm@0 | 77 inline void Partials::setHopNum(int hopN) | 
| andrewm@0 | 78 { | 
| andrewm@0 | 79 	hopNum = hopN; | 
| andrewm@0 | 80 | 
| andrewm@0 | 81 	// prepare data structures | 
| andrewm@0 | 82 	activePartialNum 	= new unsigned short[hopNum+1];	// +1 cos total num of frames = num of hops+1 | 
| andrewm@0 | 83 	activePartials	 	= new unsigned int *[hopNum+1]; | 
| andrewm@0 | 84 } | 
| andrewm@0 | 85 | 
| andrewm@0 | 86 // 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 | 87 inline int Partials::getHopNum() | 
| andrewm@0 | 88 { | 
| andrewm@0 | 89 	return hopNum; | 
| andrewm@0 | 90 } | 
| andrewm@0 | 91 | 
| andrewm@0 | 92 inline void Partials::setFreqDelta(int parIndex, int frameNum, double delta) | 
| andrewm@0 | 93 { | 
| andrewm@0 | 94 	partialFreqDelta[parIndex][frameNum] = delta; | 
| andrewm@0 | 95 } | 
| andrewm@0 | 96 | 
| andrewm@0 | 97 inline void Partials::setAmpDelta(int parIndex, int frameNum, double delta) | 
| andrewm@0 | 98 { | 
| andrewm@0 | 99 	partialAmpDelta[parIndex][frameNum] = delta; | 
| andrewm@0 | 100 } | 
| andrewm@0 | 101 | 
| andrewm@0 | 102 inline int Partials::getMaxActivePartialNum() | 
| andrewm@0 | 103 { | 
| andrewm@0 | 104 	return maxActiveParNum; | 
| andrewm@0 | 105 } | 
| andrewm@0 | 106 | 
| andrewm@0 | 107 | 
| andrewm@0 | 108 | 
| andrewm@0 | 109 | 
| andrewm@0 | 110 | 
| andrewm@0 | 111 | 
| andrewm@0 | 112 | 
| andrewm@0 | 113 //------------------------------------------------------------------------------------------------ | 
| andrewm@0 | 114 // spear parser | 
| andrewm@0 | 115 //------------------------------------------------------------------------------------------------ | 
| andrewm@0 | 116 | 
| andrewm@0 | 117 class Spear_parser | 
| andrewm@0 | 118 { | 
| andrewm@0 | 119 public: | 
| andrewm@0 | 120 	Spear_parser(); | 
| andrewm@0 | 121 	~Spear_parser(); | 
| andrewm@0 | 122 | 
| andrewm@0 | 123 	Partials partials; | 
| andrewm@0 | 124 | 
| andrewm@0 | 125 	bool parseFile(string filename, int hopsize=-1, int samplerate = 44100); | 
| andrewm@0 | 126 	bool parseFile(char *filename, int hopsize=-1, int samplerate = 44100); | 
| andrewm@0 | 127 	int getHopSize(); | 
| andrewm@0 | 128 	int getFileSampleRate(); | 
| andrewm@0 | 129 	double getDeltaTime(); | 
| andrewm@0 | 130 | 
| andrewm@0 | 131 private: | 
| andrewm@0 | 132 | 
| andrewm@0 | 133 	int hopSize; | 
| andrewm@0 | 134 	int fileSampleRate; | 
| andrewm@0 | 135 	double deltaTime;	// min time gap between consecutive frames | 
| andrewm@0 | 136 | 
| andrewm@0 | 137 	timeval start, stop; | 
| andrewm@0 | 138 	unsigned long hopSizeT, parserT, staticT; | 
| andrewm@0 | 139 | 
| andrewm@0 | 140 	void calculateDeltaTime(); | 
| andrewm@0 | 141 	void calculateHopSize(char *filename); | 
| andrewm@0 | 142 	bool parser(char *filename, int hopsize=-1, int samplerate=44100); | 
| andrewm@0 | 143 	bool DBXparser(char *filename, int samplerate=44100); | 
| andrewm@0 | 144 	bool TXTparser(char *filename, int hopsize=-1, int samplerate=44100); | 
| andrewm@0 | 145 	int fromTimeToSamples(float time); | 
| andrewm@0 | 146 	int interpolateSamples(int parIndex, int *frameIndex, int missCnt, int nextSample, | 
| andrewm@0 | 147 							double nextFreq, double nextAmp, double *prevFreq, double *prevAmp); | 
| andrewm@0 | 148 	void staticCalculations(); | 
| andrewm@0 | 149 | 
| andrewm@0 | 150 }; | 
| andrewm@0 | 151 | 
| andrewm@0 | 152 inline bool Spear_parser::parseFile(string filename, int hopsize, int samplerate) | 
| andrewm@0 | 153 { | 
| andrewm@0 | 154 	return parser((char *)filename.c_str(), hopsize, samplerate); | 
| andrewm@0 | 155 } | 
| andrewm@0 | 156 | 
| andrewm@0 | 157 inline bool Spear_parser::parseFile(char *filename, int hopsize, int samplerate) | 
| andrewm@0 | 158 { | 
| andrewm@0 | 159 	return parser(filename, hopsize, samplerate); | 
| andrewm@0 | 160 } | 
| andrewm@0 | 161 | 
| andrewm@0 | 162 inline void Spear_parser::calculateDeltaTime() | 
| andrewm@0 | 163 { | 
| andrewm@0 | 164 	deltaTime = (double)hopSize/ (double)fileSampleRate; | 
| andrewm@0 | 165 } | 
| andrewm@0 | 166 | 
| andrewm@0 | 167 // 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 | 168 inline int Spear_parser::fromTimeToSamples(float time) | 
| andrewm@0 | 169 { | 
| andrewm@0 | 170 	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 | 171 } | 
| andrewm@0 | 172 | 
| andrewm@0 | 173 inline int Spear_parser::getHopSize() | 
| andrewm@0 | 174 { | 
| andrewm@0 | 175 	return hopSize; | 
| andrewm@0 | 176 } | 
| andrewm@0 | 177 | 
| andrewm@0 | 178 inline int Spear_parser::getFileSampleRate() | 
| andrewm@0 | 179 { | 
| andrewm@0 | 180 	return fileSampleRate; | 
| andrewm@0 | 181 } | 
| andrewm@0 | 182 | 
| andrewm@0 | 183 inline double Spear_parser::getDeltaTime() | 
| andrewm@0 | 184 { | 
| andrewm@0 | 185 	return deltaTime; | 
| andrewm@0 | 186 } | 
| andrewm@0 | 187 | 
| andrewm@0 | 188 #endif /* SPEAR_PARSER_H_ */ |