comparison examples/d-box/spear_parser.cpp @ 300:dbeed520b014 prerelease

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