andrewm@0
|
1 /*
|
andrewm@0
|
2 * spear_parser.cpp 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 #include "spear_parser.h"
|
andrewm@0
|
9
|
andrewm@0
|
10 using namespace std;
|
andrewm@0
|
11
|
andrewm@0
|
12 //#define DO_CHECKS
|
andrewm@0
|
13
|
andrewm@0
|
14 //------------------------------------------------------------------------------------------------
|
andrewm@0
|
15 // partials
|
andrewm@0
|
16 //------------------------------------------------------------------------------------------------
|
andrewm@0
|
17
|
andrewm@0
|
18 Partials::Partials()
|
andrewm@0
|
19 {
|
andrewm@0
|
20 partialFrequencies = NULL;
|
andrewm@0
|
21 // partialAmplitudes = NULL;
|
andrewm@0
|
22 // partialNumFrames = NULL;
|
andrewm@0
|
23 // partialStartSample = NULL;
|
andrewm@0
|
24 // partialEndSample = NULL;
|
andrewm@0
|
25 // partialCurrentFrame = NULL;
|
andrewm@0
|
26 // partialFreqDelta = NULL;
|
andrewm@0
|
27 // partialAmpDelta = NULL;
|
andrewm@0
|
28
|
andrewm@0
|
29
|
andrewm@0
|
30 activePartialNum = NULL;
|
andrewm@0
|
31 // activePartials = NULL;
|
andrewm@0
|
32
|
andrewm@0
|
33 currentSample = -1;
|
andrewm@0
|
34 }
|
andrewm@0
|
35
|
andrewm@0
|
36 Partials::~Partials()
|
andrewm@0
|
37 {
|
andrewm@0
|
38 if(partialFrequencies != NULL) // check on one is enough
|
andrewm@0
|
39 {
|
andrewm@0
|
40 if(partialFrequencies[0] != NULL) // check on one is enough
|
andrewm@0
|
41 {
|
andrewm@0
|
42 for(unsigned int i=0; i<parNum; i++)
|
andrewm@0
|
43 {
|
andrewm@0
|
44 delete[] partialFrequencies[i];
|
andrewm@0
|
45 delete[] partialAmplitudes[i];
|
andrewm@0
|
46 delete[] partialFreqDelta[i];
|
andrewm@0
|
47 delete[] partialAmpDelta[i];
|
andrewm@0
|
48
|
andrewm@0
|
49 }
|
andrewm@0
|
50 }
|
andrewm@0
|
51
|
andrewm@0
|
52 delete[] partialFrequencies;
|
andrewm@0
|
53 delete[] partialAmplitudes;
|
andrewm@0
|
54 delete[] partialNumFrames;
|
andrewm@0
|
55 delete[] partialFreqDelta;
|
andrewm@0
|
56 delete[] partialAmpDelta;
|
andrewm@0
|
57 delete[] partialFreqMean;
|
andrewm@0
|
58 }
|
andrewm@0
|
59
|
andrewm@0
|
60 if(activePartialNum != NULL)
|
andrewm@0
|
61 {
|
andrewm@0
|
62 for(unsigned int i=0; i<hopNum+1; i++)
|
andrewm@0
|
63 delete[] activePartials[i];
|
andrewm@0
|
64
|
andrewm@0
|
65 delete[] activePartialNum;
|
andrewm@0
|
66 delete[] activePartials ;
|
andrewm@0
|
67 }
|
andrewm@0
|
68 }
|
andrewm@0
|
69
|
andrewm@0
|
70 void Partials::init(int parN, int hopS, bool isDBX)
|
andrewm@0
|
71 {
|
andrewm@0
|
72 if(!isDBX)
|
andrewm@0
|
73 {
|
andrewm@0
|
74 parNum = parN;
|
andrewm@0
|
75 hopSize = hopS;
|
andrewm@0
|
76
|
andrewm@0
|
77 partialFrequencies = new float *[parNum];
|
andrewm@0
|
78 partialAmplitudes = new float *[parNum];
|
andrewm@0
|
79 partialNumFrames = new unsigned int[parNum];
|
andrewm@0
|
80 partialStartFrame = new unsigned int[parNum];
|
andrewm@0
|
81 partialStartSample = new unsigned int[parNum];
|
andrewm@0
|
82 partialEndSample = new unsigned int[parNum];
|
andrewm@0
|
83 partialFreqDelta = new float *[parNum];
|
andrewm@0
|
84 partialAmpDelta = new float *[parNum];
|
andrewm@0
|
85 partialFreqMean = new float[parNum];
|
andrewm@0
|
86
|
andrewm@0
|
87
|
andrewm@0
|
88
|
andrewm@0
|
89 // init in one shot
|
andrewm@0
|
90 fill(partialFreqMean, partialFreqMean+parNum, 0); // mean is zero
|
andrewm@0
|
91
|
andrewm@0
|
92 partialFrequencies[0] = NULL; // for free check
|
andrewm@0
|
93 }
|
andrewm@0
|
94 else
|
andrewm@0
|
95 {
|
andrewm@0
|
96 parNum = parN;
|
andrewm@0
|
97 hopSize = hopS;
|
andrewm@0
|
98
|
andrewm@0
|
99 partialFrequencies = new float *[parNum];
|
andrewm@0
|
100 partialAmplitudes = new float *[parNum];
|
andrewm@0
|
101 partialNumFrames = new unsigned int[parNum];
|
andrewm@0
|
102 partialStartFrame = new unsigned int[parNum];
|
andrewm@0
|
103 partialFreqDelta = new float *[parNum];
|
andrewm@0
|
104 partialAmpDelta = new float *[parNum];
|
andrewm@0
|
105 partialFreqMean = new float[parNum];
|
andrewm@0
|
106
|
andrewm@0
|
107 partialFrequencies[0] = NULL; // for free check
|
andrewm@0
|
108 }
|
andrewm@0
|
109 }
|
andrewm@0
|
110
|
andrewm@0
|
111
|
andrewm@0
|
112
|
andrewm@0
|
113 void Partials::update(int parIndex, int frameNum)
|
andrewm@0
|
114 {
|
andrewm@0
|
115 partialFrequencies[parIndex] = new float[frameNum];
|
andrewm@0
|
116 partialAmplitudes[parIndex] = new float[frameNum];
|
andrewm@0
|
117 partialFreqDelta[parIndex] = new float[frameNum];
|
andrewm@0
|
118 partialAmpDelta[parIndex] = new float[frameNum];
|
andrewm@0
|
119
|
andrewm@0
|
120 fill(partialFreqDelta[parIndex], partialFreqDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999
|
andrewm@0
|
121 fill(partialAmpDelta[parIndex], partialAmpDelta[parIndex]+frameNum, 99999.0); // in the end, only the last one will have 99999
|
andrewm@0
|
122 }
|
andrewm@0
|
123
|
andrewm@0
|
124
|
andrewm@0
|
125
|
andrewm@0
|
126
|
andrewm@0
|
127
|
andrewm@0
|
128
|
andrewm@0
|
129
|
andrewm@0
|
130
|
andrewm@0
|
131
|
andrewm@0
|
132
|
andrewm@0
|
133
|
andrewm@0
|
134
|
andrewm@0
|
135
|
andrewm@0
|
136
|
andrewm@0
|
137
|
andrewm@0
|
138
|
andrewm@0
|
139
|
andrewm@0
|
140
|
andrewm@0
|
141
|
andrewm@0
|
142
|
andrewm@0
|
143 //------------------------------------------------------------------------------------------------
|
andrewm@0
|
144 // spear parser
|
andrewm@0
|
145 //------------------------------------------------------------------------------------------------
|
andrewm@0
|
146 Spear_parser::Spear_parser()
|
andrewm@0
|
147 {
|
andrewm@0
|
148 // some default values
|
andrewm@0
|
149 hopSize = -1;
|
andrewm@0
|
150 fileSampleRate = -1;
|
andrewm@0
|
151 }
|
andrewm@0
|
152
|
andrewm@0
|
153 Spear_parser::~Spear_parser()
|
andrewm@0
|
154 {
|
andrewm@0
|
155 }
|
andrewm@0
|
156
|
andrewm@0
|
157 void Spear_parser::calculateHopSize(char *filename)
|
andrewm@0
|
158 {
|
andrewm@0
|
159 int index = 0;
|
andrewm@0
|
160 bool prevWas_ = false;
|
andrewm@0
|
161 bool found_h = false;
|
andrewm@0
|
162 int n = 0;
|
andrewm@0
|
163
|
andrewm@0
|
164 hopSize = 0;
|
andrewm@0
|
165
|
andrewm@0
|
166 do
|
andrewm@0
|
167 {
|
andrewm@0
|
168 // check if '_'
|
andrewm@0
|
169 if(filename[index] == '_')
|
andrewm@0
|
170 prevWas_ = true;
|
andrewm@0
|
171 else if( (filename[index] == 'h') && prevWas_) // if it is not, but it is 'h' and previous was '_', found "_h"!
|
andrewm@0
|
172 {
|
andrewm@0
|
173 found_h = true;
|
andrewm@0
|
174 while(filename[index] != '\0')
|
andrewm@0
|
175 {
|
andrewm@0
|
176 index++;
|
andrewm@0
|
177 if( (filename[index] == '.') || (filename[index] == '_'))
|
andrewm@0
|
178 break;
|
andrewm@0
|
179 else // i am not checking if char are digits...!
|
andrewm@0
|
180 {
|
andrewm@0
|
181 n = filename[index];
|
andrewm@0
|
182 hopSize = hopSize*10+(n-48);
|
andrewm@0
|
183 }
|
andrewm@0
|
184 }
|
andrewm@0
|
185 }
|
andrewm@0
|
186 else // else, nothing
|
andrewm@0
|
187 prevWas_ = false;
|
andrewm@0
|
188 index++;
|
andrewm@0
|
189 }
|
andrewm@0
|
190 while( (filename[index] != '\0') && !found_h );
|
andrewm@0
|
191
|
andrewm@0
|
192 if( !found_h || (hopSize<1) )
|
andrewm@0
|
193 hopSize = 551; // default val
|
andrewm@0
|
194
|
andrewm@0
|
195 }
|
andrewm@0
|
196
|
andrewm@0
|
197
|
andrewm@0
|
198 bool Spear_parser::parser(char *filename, int hopsize, int samplerate)
|
andrewm@0
|
199 {
|
andrewm@0
|
200 string name = string(filename);
|
andrewm@0
|
201 int len = name.length();
|
andrewm@0
|
202 // invoke correct parser according to the type of file...just checking the extension, crude but functional
|
andrewm@0
|
203 if( (name[len-4]=='.') && (name[len-3]=='d') && (name[len-2]=='b') && (name[len-1]=='x') )
|
andrewm@0
|
204 return DBXparser(filename, samplerate); // .dbox
|
andrewm@0
|
205 else
|
andrewm@0
|
206 return TXTparser(filename, hopSize, samplerate); // .txt, or whatever
|
andrewm@0
|
207 }
|
andrewm@0
|
208
|
andrewm@0
|
209
|
andrewm@0
|
210 bool Spear_parser::DBXparser(char *filename, int samplerate)
|
andrewm@0
|
211 {
|
andrewm@0
|
212 fileSampleRate = samplerate;
|
andrewm@0
|
213
|
andrewm@0
|
214 // working vars
|
andrewm@0
|
215 int parNum = 0; // total num of partials
|
andrewm@0
|
216 int hopNum = 0; // total num of hops
|
andrewm@0
|
217
|
andrewm@0
|
218 //----------------------------------------------------------------------------------------
|
andrewm@0
|
219 // open a file
|
andrewm@0
|
220 ifstream fin;
|
andrewm@0
|
221 fin.open(filename, ios::in | ios::binary);
|
andrewm@0
|
222 if (!fin.good())
|
andrewm@0
|
223 {
|
andrewm@0
|
224 cout << "Parser Error: file not found" << endl; // exit if file not found
|
andrewm@0
|
225 return false;
|
andrewm@0
|
226 }
|
andrewm@0
|
227
|
andrewm@0
|
228 gettimeofday(&start, NULL);
|
andrewm@0
|
229 //----------------------------------------------------------------------------------------
|
andrewm@0
|
230 // general data
|
andrewm@0
|
231
|
andrewm@0
|
232 // look for partial count
|
andrewm@0
|
233 fin.read((char *) &parNum, sizeof(int));
|
andrewm@0
|
234 partials.parNum = parNum;
|
andrewm@0
|
235
|
andrewm@0
|
236 // look for hop count
|
andrewm@0
|
237 fin.read((char *) &hopNum, sizeof(int));
|
andrewm@0
|
238 partials.setHopNum(hopNum);
|
andrewm@0
|
239
|
andrewm@0
|
240 // look for hop size
|
andrewm@0
|
241 fin.read((char *) &hopSize, sizeof(int));
|
andrewm@0
|
242 partials.hopSize = hopSize; // it's handy for both classes to know it
|
andrewm@0
|
243
|
andrewm@0
|
244 // init partials data structure
|
andrewm@0
|
245 partials.init(parNum, hopSize, true);
|
andrewm@0
|
246
|
andrewm@0
|
247 // look for max active par num
|
andrewm@0
|
248 fin.read((char *) &(partials.maxActiveParNum), sizeof(int));
|
andrewm@0
|
249
|
andrewm@0
|
250
|
andrewm@0
|
251
|
andrewm@0
|
252 // partial data
|
andrewm@0
|
253
|
andrewm@0
|
254 // start frame of each partial
|
andrewm@0
|
255 fin.read((char *) partials.partialStartFrame, sizeof(int)*parNum);
|
andrewm@0
|
256
|
andrewm@0
|
257 // num of frames of each partial
|
andrewm@0
|
258 fin.read((char *) partials.partialNumFrames, sizeof(int)*parNum);
|
andrewm@0
|
259
|
andrewm@0
|
260 // frequency mean of each partial
|
andrewm@0
|
261 fin.read((char *) partials.partialFreqMean, sizeof(int)*parNum);
|
andrewm@0
|
262
|
andrewm@0
|
263 for(int par=0; par<parNum; par++)
|
andrewm@0
|
264 {
|
andrewm@0
|
265 int frameNum = partials.partialNumFrames[par];
|
andrewm@0
|
266 partials.update(par, frameNum);
|
andrewm@0
|
267 fin.read((char *)partials.partialAmplitudes[par], sizeof(float)*frameNum); // amplitude of each partial in each frame
|
andrewm@0
|
268 fin.read((char *)partials.partialFrequencies[par], sizeof(float)*frameNum); // frequency of each partial in each frame
|
andrewm@0
|
269 fin.read((char *)partials.partialAmpDelta[par], sizeof(float)*frameNum); // amplitude delta of each partial in each frame
|
andrewm@0
|
270 fin.read((char *)partials.partialFreqDelta[par], sizeof(float)*frameNum); // frequency delta of each partial in each frame
|
andrewm@0
|
271 }
|
andrewm@0
|
272
|
andrewm@0
|
273
|
andrewm@0
|
274
|
andrewm@0
|
275
|
andrewm@0
|
276 // frame data
|
andrewm@0
|
277
|
andrewm@0
|
278 // number of active partial per each frame
|
andrewm@0
|
279 fin.read((char *) partials.activePartialNum, sizeof(short)*(hopNum+1));
|
andrewm@0
|
280 // init array
|
andrewm@0
|
281 for(int frame=0; frame<hopNum+1; frame++)
|
andrewm@0
|
282 {
|
andrewm@0
|
283 partials.activePartials[frame] = new unsigned int[partials.activePartialNum[frame]];
|
andrewm@0
|
284 fin.read((char *)partials.activePartials[frame], sizeof(int)*partials.activePartialNum[frame]); // active partials per each frame
|
andrewm@0
|
285 }
|
andrewm@0
|
286
|
andrewm@0
|
287
|
andrewm@0
|
288
|
andrewm@0
|
289
|
andrewm@0
|
290
|
andrewm@0
|
291 gettimeofday(&stop, NULL);
|
andrewm@0
|
292 parserT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
|
andrewm@0
|
293
|
andrewm@0
|
294
|
andrewm@0
|
295 printf("\n-----------------------\n");
|
andrewm@0
|
296 printf("\nFile: %s\n", filename);
|
andrewm@0
|
297 printf("\n-----------------------\n");
|
andrewm@0
|
298 printf("Profiler\n");
|
andrewm@0
|
299 printf("-----------------------\n");
|
andrewm@0
|
300 printf("File parser:\t\t\t%lu usec\n", parserT);
|
andrewm@0
|
301 printf("\n\nTotal:\t\t%lu usec\n", parserT);
|
andrewm@0
|
302 printf("-----------------------\n");
|
andrewm@0
|
303
|
andrewm@0
|
304 fin.close();
|
andrewm@0
|
305
|
andrewm@0
|
306 return true;
|
andrewm@0
|
307 }
|
andrewm@0
|
308
|
andrewm@0
|
309
|
andrewm@0
|
310
|
andrewm@0
|
311
|
andrewm@0
|
312 bool Spear_parser::TXTparser(char *filename, int hopsize, int samplerate)
|
andrewm@0
|
313 {
|
andrewm@0
|
314 hopSize = hopsize;
|
andrewm@0
|
315 fileSampleRate = samplerate;
|
andrewm@0
|
316 if(hopsize<0)
|
andrewm@0
|
317 {
|
andrewm@0
|
318 gettimeofday(&start, NULL);
|
andrewm@0
|
319 calculateHopSize(filename);
|
andrewm@0
|
320 gettimeofday(&stop, NULL);
|
andrewm@0
|
321 hopSizeT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
|
andrewm@0
|
322 }
|
andrewm@0
|
323 else
|
andrewm@0
|
324 hopSizeT = 0;
|
andrewm@0
|
325
|
andrewm@0
|
326 calculateDeltaTime();
|
andrewm@0
|
327
|
andrewm@0
|
328 // working vars
|
andrewm@0
|
329 char * token; // where to save single figures from file
|
andrewm@0
|
330 string s = ""; // where to save lines from file
|
andrewm@0
|
331 int parNum = 0; // total num of partials
|
andrewm@0
|
332 int parIndex = -1; // index of current partial
|
andrewm@0
|
333 int frameNum = 0; // total num of frames
|
andrewm@0
|
334 int frameIndex = -1; // index of current frame
|
andrewm@0
|
335 int startSample = -1; // sample value for first frame of partials
|
andrewm@0
|
336 int endSample = -1; // sample value for last frame of partials
|
andrewm@0
|
337 int maxSample = 0; // to calculate total number of hops in file
|
andrewm@0
|
338 int missSampCnt = 0; // number of mising samples
|
andrewm@0
|
339 double freq = 0; // to calculate frequency delta
|
andrewm@0
|
340 double prevFreq = 0; // to calculate frequency delta
|
andrewm@0
|
341 double amp = 0; // to calculate amplitude delta
|
andrewm@0
|
342 double prevAmp = 0; // to calculate amplitude delta
|
andrewm@0
|
343
|
andrewm@0
|
344
|
andrewm@0
|
345 //----------------------------------------------------------------------------------------
|
andrewm@0
|
346 // open a file
|
andrewm@0
|
347 ifstream fin;
|
andrewm@0
|
348 fin.open(filename);
|
andrewm@0
|
349 if (!fin.good())
|
andrewm@0
|
350 {
|
andrewm@0
|
351 cout << "Parser Error: file not found" << endl; // exit if file not found
|
andrewm@0
|
352 return false;
|
andrewm@0
|
353 }
|
andrewm@0
|
354
|
andrewm@0
|
355 gettimeofday(&start, NULL);
|
andrewm@0
|
356 //----------------------------------------------------------------------------------------
|
andrewm@0
|
357 // init partials data structure
|
andrewm@0
|
358 getline(fin, s);
|
andrewm@0
|
359 getline(fin, s);
|
andrewm@0
|
360 getline(fin, s); // third line is the first we are interested into
|
andrewm@0
|
361
|
andrewm@0
|
362 // look for partial count
|
andrewm@0
|
363 token = strtok((char *)s.c_str(), " ");
|
andrewm@0
|
364 // check if first token is there
|
andrewm@0
|
365 if(token)
|
andrewm@0
|
366 {
|
andrewm@0
|
367 token = strtok(0, " ");
|
andrewm@0
|
368 // check if second token is there
|
andrewm@0
|
369 if(token)
|
andrewm@0
|
370 parNum = atoi(token);
|
andrewm@0
|
371 #ifdef DO_CHECKS
|
andrewm@0
|
372 else
|
andrewm@0
|
373 {
|
andrewm@0
|
374 cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found
|
andrewm@0
|
375 return false;
|
andrewm@0
|
376 }
|
andrewm@0
|
377 #endif
|
andrewm@0
|
378 }
|
andrewm@0
|
379 #ifdef DO_CHECKS
|
andrewm@0
|
380 else
|
andrewm@0
|
381 {
|
andrewm@0
|
382 cout << "Parser Error: partial count not found, bad file format" << endl; // exit if value not found
|
andrewm@0
|
383 return false;
|
andrewm@0
|
384 }
|
andrewm@0
|
385 #endif
|
andrewm@0
|
386 // from now on we take for granted that format is correct
|
andrewm@0
|
387
|
andrewm@0
|
388 // init partials data structure
|
andrewm@0
|
389 partials.init(parNum, hopSize);
|
andrewm@0
|
390
|
andrewm@0
|
391 //----------------------------------------------------------------------------------------
|
andrewm@0
|
392 // fill in partials data structure
|
andrewm@0
|
393 getline(fin, s); // get rid of intro line "partials-data"
|
andrewm@0
|
394 getline(fin, s); // first important line
|
andrewm@0
|
395
|
andrewm@0
|
396 while (!fin.eof())
|
andrewm@0
|
397 {
|
andrewm@0
|
398 //-------------------------------------
|
andrewm@0
|
399 // partial specific info
|
andrewm@0
|
400 token = strtok((char *)s.c_str(), " ");
|
andrewm@0
|
401 parIndex = atoi(token); // partial index
|
andrewm@0
|
402
|
andrewm@0
|
403 token = strtok(0, " "); // num of frames, not used, cos we will do linear interpolation for missing frames
|
andrewm@0
|
404 // frameNum = atoi(token);
|
andrewm@0
|
405 // partials.partialNumFrames[parIndex] = frameNum;
|
andrewm@0
|
406
|
andrewm@0
|
407 token = strtok(0, " "); // time of first frame, still char *
|
andrewm@0
|
408 startSample = fromTimeToSamples(atof(token)); // convert time to samples
|
andrewm@0
|
409 partials.partialStartSample[parIndex] = startSample;
|
andrewm@0
|
410
|
andrewm@0
|
411 token = strtok(0, " "); // time of last frame, still char *
|
andrewm@0
|
412 endSample = fromTimeToSamples(atof(token)); // convert time to samples
|
andrewm@0
|
413 partials.partialEndSample[parIndex] = endSample;
|
andrewm@0
|
414
|
andrewm@0
|
415 frameNum = ((endSample-startSample)/hopSize) + 1; // num of frames, including missing consecutive ones [+1 one cos we count frames, not hops]
|
andrewm@0
|
416 partials.partialNumFrames[parIndex] = frameNum;
|
andrewm@0
|
417
|
andrewm@0
|
418
|
andrewm@0
|
419 // check if this is the highest sample value so far
|
andrewm@0
|
420 if(endSample > maxSample)
|
andrewm@0
|
421 maxSample = endSample;
|
andrewm@0
|
422
|
andrewm@0
|
423 // update data structure
|
andrewm@0
|
424 partials.update(parIndex, frameNum);
|
andrewm@0
|
425
|
andrewm@0
|
426
|
andrewm@0
|
427 //-------------------------------------
|
andrewm@0
|
428 // frames
|
andrewm@0
|
429 getline(fin, s);
|
andrewm@0
|
430 token = strtok((char *)s.c_str(), " "); // frame time
|
andrewm@0
|
431 frameIndex = -1;
|
andrewm@0
|
432
|
andrewm@0
|
433 // unroll first iteration, so that in the following loop we save the check on the last frame to calculate increments
|
andrewm@0
|
434 if(token) // all frames data are on one line, in groups of 3 entries
|
andrewm@0
|
435 {
|
andrewm@0
|
436 frameIndex++;
|
andrewm@0
|
437
|
andrewm@0
|
438 endSample = fromTimeToSamples(atof(token));
|
andrewm@0
|
439
|
andrewm@0
|
440 token = strtok(0, " "); // frame frequency
|
andrewm@0
|
441 prevFreq = atof(token);
|
andrewm@0
|
442 partials.partialFrequencies[parIndex][frameIndex] = (float)prevFreq;
|
andrewm@0
|
443 partials.partialFreqMean[parIndex] += prevFreq; // for frequency mean
|
andrewm@0
|
444
|
andrewm@0
|
445 token = strtok(0, " "); // frame amplitude
|
andrewm@0
|
446 prevAmp = atof(token);
|
andrewm@0
|
447 partials.partialAmplitudes[parIndex][frameIndex] = (float)prevAmp;
|
andrewm@0
|
448
|
andrewm@0
|
449 token = strtok(0, " "); // next frame frequency, to be checked
|
andrewm@0
|
450 }
|
andrewm@0
|
451
|
andrewm@0
|
452 // here the loop starts
|
andrewm@0
|
453 while(token) // all frames data are on one line, in groups of 3 entries
|
andrewm@0
|
454 {
|
andrewm@0
|
455 frameIndex++;
|
andrewm@0
|
456 missSampCnt = 0;
|
andrewm@0
|
457
|
andrewm@0
|
458 startSample = fromTimeToSamples(atof(token));
|
andrewm@0
|
459
|
andrewm@0
|
460 token = strtok(0, " "); // frame frequency
|
andrewm@0
|
461 freq = atof(token);
|
andrewm@0
|
462
|
andrewm@0
|
463 token = strtok(0, " "); // frame amplitude
|
andrewm@0
|
464 amp = atof(token);
|
andrewm@0
|
465 // 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
|
466
|
andrewm@0
|
467 // while current frame sample is farther than one hopsize...
|
andrewm@0
|
468 while(startSample > endSample+hopSize)
|
andrewm@0
|
469 {
|
andrewm@0
|
470 missSampCnt++; // ...one sample is missing
|
andrewm@0
|
471 endSample += hopSize; // move to next hop
|
andrewm@0
|
472 }
|
andrewm@0
|
473
|
andrewm@0
|
474 // if frames are missing do interpolation and update indices
|
andrewm@0
|
475 if(missSampCnt>0)
|
andrewm@0
|
476 startSample = interpolateSamples(parIndex, &frameIndex, missSampCnt, endSample+hopSize, freq, amp, &prevFreq, &prevAmp);
|
andrewm@0
|
477
|
andrewm@0
|
478 partials.partialFrequencies[parIndex][frameIndex] = (float)freq;
|
andrewm@0
|
479 partials.partialFreqMean[parIndex] += freq; // for frequency mean
|
andrewm@0
|
480 partials.setFreqDelta(parIndex, frameIndex-1, (freq-prevFreq)/hopSize); // freq delta between prev and current frame
|
andrewm@0
|
481 prevFreq = freq;
|
andrewm@0
|
482
|
andrewm@0
|
483 partials.partialAmplitudes[parIndex][frameIndex] = (float)amp;
|
andrewm@0
|
484 partials.setAmpDelta(parIndex, frameIndex-1, (amp-prevAmp)/hopSize); // amp delta between prev and current frame
|
andrewm@0
|
485 prevAmp = amp;
|
andrewm@0
|
486
|
andrewm@0
|
487 endSample = startSample;
|
andrewm@0
|
488 token = strtok(0, " "); // next frame frequency, to be checked
|
andrewm@0
|
489 }
|
andrewm@0
|
490 #ifdef DO_CHECKS
|
andrewm@0
|
491 if(frameIndex != (frameNum-1))
|
andrewm@0
|
492 {
|
andrewm@0
|
493 cout << "Parser Error: frame count mismatch on partial " << parIndex << ", bad file format" << endl; // exit if mismatch
|
andrewm@0
|
494 cout << "frameIndex: " << frameIndex << endl;
|
andrewm@0
|
495 cout << "frameNum: " << frameNum << endl;
|
andrewm@0
|
496 return false;
|
andrewm@0
|
497 }
|
andrewm@0
|
498 #endif
|
andrewm@0
|
499
|
andrewm@0
|
500 partials.partialFreqMean[parIndex] /= partials.partialNumFrames[parIndex]; // frequency mean
|
andrewm@0
|
501
|
andrewm@0
|
502 getline(fin, s); // next partial line, to check
|
andrewm@0
|
503 }
|
andrewm@0
|
504 #ifdef DO_CHECKS
|
andrewm@0
|
505 if(parIndex != (parNum-1))
|
andrewm@0
|
506 {
|
andrewm@0
|
507 cout << "Parser Error: partial count mismatch, bad file format" << endl; // exit if mismatch
|
andrewm@0
|
508 return false;
|
andrewm@0
|
509 }
|
andrewm@0
|
510 #endif
|
andrewm@0
|
511
|
andrewm@0
|
512 partials.setHopNum(maxSample/hopSize);
|
andrewm@0
|
513
|
andrewm@0
|
514 gettimeofday(&stop, NULL);
|
andrewm@0
|
515 parserT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
|
andrewm@0
|
516
|
andrewm@0
|
517 gettimeofday(&start, NULL);
|
andrewm@0
|
518 staticCalculations();
|
andrewm@0
|
519 gettimeofday(&stop, NULL);
|
andrewm@0
|
520 staticT = ( (stop.tv_sec*1000000+stop.tv_usec) - (start.tv_sec*1000000+start.tv_usec) );
|
andrewm@0
|
521
|
andrewm@0
|
522 fin.close();
|
andrewm@0
|
523
|
andrewm@0
|
524
|
andrewm@0
|
525 printf("\n-----------------------\n");
|
andrewm@0
|
526 printf("\nFile: %s\n", filename);
|
andrewm@0
|
527 printf("\n-----------------------\n");
|
andrewm@0
|
528 printf("Profiler\n");
|
andrewm@0
|
529 printf("-----------------------\n");
|
andrewm@0
|
530 printf("Hop size parser:\t\t%lu usec\n", hopSizeT);
|
andrewm@0
|
531 printf("File parser:\t\t\t%lu usec\n", parserT);
|
andrewm@0
|
532 printf("Static calculations:\t\t%lu usec\n", staticT);
|
andrewm@0
|
533 printf("\n\nTotal:\t\t%lu usec\n", hopSizeT+parserT+staticT);
|
andrewm@0
|
534 printf("-----------------------\n");
|
andrewm@0
|
535
|
andrewm@0
|
536 return true;
|
andrewm@0
|
537 }
|
andrewm@0
|
538
|
andrewm@0
|
539
|
andrewm@0
|
540 int Spear_parser::interpolateSamples(int parIndex, int *frameIndex, int missCnt, int nextSample, double nextFreq, double nextAmp, double *prevFreq, double *prevAmp)
|
andrewm@0
|
541 {
|
andrewm@0
|
542 int frame = *frameIndex; // current frame index
|
andrewm@0
|
543 int sample = nextSample - (hopSize*(missCnt)); // move from next real frame sample to first missing frame sample
|
andrewm@0
|
544 double freq = *prevFreq; // freq of the prev real frame
|
andrewm@0
|
545 double freqStep = (nextFreq-*prevFreq)/(missCnt+1); // fixed freq step between hops, for missing frames [linear interpolation]
|
andrewm@0
|
546 double deltaFreq = freqStep/hopSize; // fixed hop freq step in samples
|
andrewm@0
|
547 double amp = *prevAmp; // same for amp...
|
andrewm@0
|
548 double ampStep = (nextAmp-*prevAmp)/(missCnt+1);
|
andrewm@0
|
549 double deltaAmp = ampStep/hopSize;
|
andrewm@0
|
550
|
andrewm@0
|
551 // for each missing frame
|
andrewm@0
|
552 for(int i=0; i<missCnt; i++)
|
andrewm@0
|
553 {
|
andrewm@0
|
554 // calculate values for current missing frame
|
andrewm@0
|
555 freq += freqStep;
|
andrewm@0
|
556 amp += ampStep;
|
andrewm@0
|
557 // save values
|
andrewm@0
|
558 partials.partialFrequencies[parIndex][frame] = freq;
|
andrewm@0
|
559 partials.partialAmplitudes[parIndex][frame] = amp;
|
andrewm@0
|
560 partials.partialFreqMean[parIndex] += freq; // for frequency mean
|
andrewm@0
|
561 // set deltas of previous frame [real or missing]
|
andrewm@0
|
562 partials.setFreqDelta(parIndex, frame-1, deltaFreq);
|
andrewm@0
|
563 partials.setAmpDelta(parIndex, frame-1, deltaAmp);
|
andrewm@0
|
564 // move to next frame [missing or real]
|
andrewm@0
|
565 sample += hopSize;
|
andrewm@0
|
566 frame++;
|
andrewm@0
|
567 }
|
andrewm@0
|
568
|
andrewm@0
|
569 // update global values
|
andrewm@0
|
570 *frameIndex = frame;
|
andrewm@0
|
571 *prevFreq = freq;
|
andrewm@0
|
572 *prevAmp = amp;
|
andrewm@0
|
573
|
andrewm@0
|
574 return sample; // return the frame sample of the next real frame
|
andrewm@0
|
575 }
|
andrewm@0
|
576
|
andrewm@0
|
577
|
andrewm@0
|
578
|
andrewm@0
|
579 // for each frame, statically calculate:
|
andrewm@0
|
580 // - which partial is active [and the total num of active partials]
|
andrewm@0
|
581 // - at which local frame each partial is
|
andrewm@0
|
582 void Spear_parser::staticCalculations()
|
andrewm@0
|
583 {
|
andrewm@0
|
584 partials.maxActiveParNum = 0; // init to find maximum
|
andrewm@0
|
585
|
andrewm@0
|
586 unsigned short *indices = new unsigned short[partials.parNum]; // temp array to store up to the maximum num of active partial indices
|
andrewm@0
|
587 unsigned int activeCnt = 0; // counts the num of active partials in each frame
|
andrewm@0
|
588
|
andrewm@0
|
589 unsigned int frameSample = 0; // current frame in samples
|
andrewm@0
|
590
|
andrewm@0
|
591 char *partialStarted = new char [partials.parNum]; // index of the last local frame found per each partial
|
andrewm@0
|
592 fill(partialStarted, partialStarted+partials.parNum, 0);
|
andrewm@0
|
593
|
andrewm@0
|
594 for(unsigned int i=0; i<partials.hopNum+1; i++) // for each frame [not hops, this explains the +1]
|
andrewm@0
|
595 {
|
andrewm@0
|
596 //partials.localPartialFrames[i] = new int[partials.parNum]; // init all local frames to -1
|
andrewm@0
|
597 //fill(partials.localPartialFrames[i], partials.localPartialFrames[i]+partials.parNum, -1);
|
andrewm@0
|
598
|
andrewm@0
|
599 frameSample = i*hopSize; // current frame, expressed in samples
|
andrewm@0
|
600 activeCnt = 0; // reset a each frame
|
andrewm@0
|
601
|
andrewm@0
|
602 for(unsigned int j=0; j<partials.parNum; j++) // for each partial
|
andrewm@0
|
603 {
|
andrewm@0
|
604 // check if inside active time region [expressed in samples]
|
andrewm@0
|
605 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
|
606 {
|
andrewm@0
|
607 // activity
|
andrewm@0
|
608 indices[activeCnt] = j; // save active index
|
andrewm@0
|
609 activeCnt++; // increase counter
|
andrewm@0
|
610
|
andrewm@0
|
611 // partial local frames
|
andrewm@0
|
612 if(partialStarted[j]==0) // this partial has just started, so current local frame is first frame
|
andrewm@0
|
613 {
|
andrewm@0
|
614 partialStarted[j] = 1;
|
andrewm@0
|
615 partials.partialStartFrame[j] = i; // here is the number of the first frame
|
andrewm@0
|
616 }
|
andrewm@0
|
617 }
|
andrewm@0
|
618 }
|
andrewm@0
|
619
|
andrewm@0
|
620 // activity
|
andrewm@0
|
621 partials.activePartialNum[i] = activeCnt; // save number of active partials for this frame
|
andrewm@0
|
622 partials.activePartials[i] = new unsigned int[activeCnt]; // set correct size to save all indices
|
andrewm@0
|
623
|
andrewm@0
|
624 // look for maximum number of active partials at the same time
|
andrewm@0
|
625 if(activeCnt > partials.maxActiveParNum)
|
andrewm@0
|
626 partials.maxActiveParNum = activeCnt;
|
andrewm@0
|
627
|
andrewm@0
|
628 // copy indices
|
andrewm@0
|
629 for(unsigned int k=0; k<activeCnt; k++)
|
andrewm@0
|
630 partials.activePartials[i][k] = indices[k];
|
andrewm@0
|
631 }
|
andrewm@0
|
632
|
andrewm@0
|
633 delete[] indices;
|
andrewm@0
|
634 delete[] partialStarted;
|
andrewm@0
|
635
|
andrewm@0
|
636 delete[] partials.partialStartSample;
|
andrewm@0
|
637 delete[] partials.partialEndSample;
|
andrewm@0
|
638 }
|
andrewm@0
|
639
|
andrewm@0
|
640
|
andrewm@0
|
641
|