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