Edinburgh Speech Tools  2.1-release
EST_track_aux.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : August 1995 */
35 /*-----------------------------------------------------------------------*/
36 /* EST_Track Auxiliary routines */
37 /* */
38 /*=======================================================================*/
39 
40 #include <cmath>
41 #include <cstdlib>
42 #include "EST_cutils.h"
43 #include "EST_simplestats.h"
44 #include "EST_sort.h"
45 #include "EST_Track.h"
46 #include "EST_TrackFile.h"
47 #include "EST_Option.h"
48 #include "EST_track_aux.h"
49 #include "EST_error.h"
50 
51 using namespace std;
52 
53 static inline int irint(float f) { return (int)(f+0.5); }
54 static inline int irint(double f) { return (int)(f+0.5); }
55 static inline int ifloor(float f) { return (int)(f); }
56 
57 float correlation(EST_Track &a, EST_Track &b, ssize_t cha, ssize_t chb);
58 
59 /* Allow EST_Track to be used in an EST_Val */
61 
62 static int sorttest(const void *a, const void *b)
63 { // for use with qsort C library function.
64  float *c = (float *)a;
65  float *d = (float *)b;
66  float res = (*c - *d);
67  if (res == 0.0)
68  return 0;
69  return (res < 0.0) ? -1 : 1;
70 }
71 
72 void track_smooth(EST_Track &c, float x, EST_String stype)
73 {
74  if (stype == "median")
75  time_med_smooth(c, x);
76  else
77  time_mean_smooth(c, x);
78 }
79 
80 void time_med_smooth(EST_Track &c, float x)
81 {
82  if (!c.equal_space())
83  {
84  cerr << "Error: Time smoothing can only operate on fixed contours\n";
85  return;
86  }
87  // want to check for divide by zero
88  if (c.shift() == 0.0)
89  {
90  cerr << "Error in smoothing: time spacing problem\n";
91  return;
92  }
93  ssize_t n = (ssize_t)(x / c.shift());
94  for (ssize_t i = 0; i < c.num_channels(); ++i)
95  simple_med_smooth(c, n, i);
96 }
97 
98 void time_mean_smooth(EST_Track &c, float x)
99 {
100  ssize_t j;
101  EST_Track t;
102  ssize_t n = (int)(x / c.shift());
103 
104  for (j = 0; j < c.num_channels(); ++j)
105  simple_mean_smooth(c, n, j);
106 }
107 
109 {// simple median smoother of order n
110 
111 
112  // windows longer than twice the track length cause problems
113  // here is one solution
114  if(n > c.num_frames())
115  n=c.num_frames();
116 
117  // and tiny windows don't work either
118  // can't do median of 2 of fewer points
119  if(n < 3)
120  return;
121 
122  ssize_t i, j, h, k;
123  float *a = new float[c.num_frames()];
124  float *m = new float[n];
125  h = n/2;
126 
127 
128  // sort start using < n order smoothing
129  for (i = 0; i < h; ++i)
130  {
131  k = (i * 2) + 1;
132  for (j = 0; j < k; ++j)
133  m[j] = c.a(j, channel);
134  qsort(m, k, sizeof(float), sorttest);
135  a[i] = m[i];
136  }
137 
138  // sort main section using n order smoothing
139  for (i = h; i < c.num_frames() - h; ++i)
140  {
141  for (j = 0; j < n; ++j)
142  m[j] = c.a(i - h + j, channel);
143 
144  qsort(m, n, sizeof(float), sorttest);
145  a[i] = m[h];
146  }
147  // sort end section using < n order smoothing
148  for (; i < c.num_frames(); ++i)
149  {
150  k = ((c.num_frames() - i)* 2) -1;
151  for (j = 0; j < k; ++j)
152  m[j] = c.a(i - (k/2) + j, channel);
153  qsort(m, k, sizeof(float), sorttest);
154  a[i] = m[k/2];
155  }
156 
157  for (i = 0; i < c.num_frames(); ++i)
158  c.a(i,channel) = a[i];
159 
160  delete [] a;
161  delete [] m;
162 }
163 
165 { // simple mean smoother of order n
166  ssize_t i, j, h, k=1;
167  float *a = new float[c.num_frames()];
168  float sum;
169  h = n/2;
170 
171  for (i = 0; i < h; ++i)
172  {
173  k = (i * 2) + 1;
174  sum = 0.0;
175  for (j = 0; j < k; ++j)
176  sum += c.a(j, channel);
177  a[i] = sum /(float) k;
178  }
179 
180  k= h*2 + 1;
181 
182  for (i = h; i < c.num_frames() - h; ++i)
183  {
184  sum = 0.0;
185  for (j = 0; j < k; ++j)
186  sum += c.a(i - h + j, channel);
187  a[i] = sum /(float) k;
188  }
189 
190  for (; i < c.num_frames(); ++i)
191  {
192  k = ((c.num_frames() - i)* 2) -1;
193  sum = 0.0;
194  for (j = 0; j < k; ++j)
195  sum += c.a(i - (k/2) + j, channel);
196  a[i] = sum /(float) k;
197  }
198 
199  for (i = 0; i < c.num_frames(); ++i)
200  c.a(i,channel) = a[i];
201 
202  delete [] a;
203 }
204 
206 {
207  ssize_t i, j;
208  for (i = 0; i < tr.num_frames(); ++i)
209  for (j = 0; j < tr.num_channels(); ++j)
210  tr.a(i, j) = fabs(tr.a(i, j));
211 }
212 
214 {
215  EST_FVector mean, sd;
216 
217  meansd(tr, mean, sd);
218  normalise(tr, mean, sd, -1.0, 1.0);
219 }
220 
221 /* Normalise a list of tracks */
223  float upper, float lower)
224 {
225  for (EST_Litem *p = trlist.head(); p; p = p->next())
226  normalise(trlist(p), mean, sd, upper, lower);
227 }
228 
229 /* Normalise by subtracting the mean and dividing by TWICE the
230  standard deviation. */
232  float upper, float lower)
233 {
234  for (ssize_t i = 0; i < tr.num_channels(); ++i)
235  normalise(tr, mean(i), sd(i), i, upper, lower);
236 }
237 
238 void normalise(EST_Track &tr, float mean, float sd, ssize_t channel,
239  float upper, float lower)
240 {
241  // This scales the data so that 2 standard deviations worth of values
242  // lie between upper and lower.
243  ssize_t i;
244  // cout << "upper = " << upper << " lower " << lower << endl;
245  for (i = 0; i < tr.num_frames(); ++i)
246  if (!tr.track_break(i))
247  tr.a(i, channel) = ((((tr.a(i, channel) - mean) / (4 *sd)) + 0.5)
248  * (upper -lower)) + lower;
249 }
250 
251 EST_Track differentiate(EST_Track &c, float samp_int)
252 {
253  // Differentiate track. SEE ALSO delta(EST_Track, int) which does
254  // this in a more sophisticated way!!!
255 
256  EST_Track diff;
257  ssize_t i, j;
258  float dist;
259 
260  if (samp_int != 0.0)
261  c.sample(samp_int);
262 
263  diff.copy_setup(c);
264  diff.resize(c.num_frames() - 1, c.num_channels());
265 
266  for (i = 0; i < diff.num_frames(); ++i)
267  {
268  dist = c.t(i + 1) - c.t(i);
269  for (j = 0; j < diff.num_channels(); ++j)
270  diff.a(i, j) = (c.track_break(i) || c.track_break(i + 1)) ? 0.0
271  : (c.a(i + 1) - c.a(i)) / dist;
272  diff.t(i) = c.t(i) + (dist / 2.0);
273  }
274 
275  return diff;
276 }
277 
279 {
280  ssize_t i, j;
281 
282  ssize_t size = Lof(a.num_frames(), b.num_frames());
283  EST_Track diff = a;
284 
285  // ERROR REORG - this needs to return a proper error
286  if (a.num_channels() != b.num_channels())
287  {
288  cerr << "Error: Can't compare " << a.num_channels() <<
289  " channel EST_Track with " << b.num_channels() << " channel EST_Track\n";
290  return diff;
291  }
292 
293  for (i = 0; i < size; ++i)
294  for (j = 0; j < a.num_channels(); ++j)
295  diff.a(i, j) = a.a(i, j) - b.a(i, j);
296 
297  return diff;
298 }
299 
300 EST_Track difference(EST_Track &a, EST_Track &b, ssize_t channel_a, ssize_t channel_b)
301 {
302  ssize_t i;
303 
304  ssize_t size = Lof(a.num_frames(), b.num_frames());
305  EST_Track diff = a;
306 
307  for (i = 0; i < size; ++i)
308  diff.a(i, channel_a) = a.a(i, channel_a) - b.a(i, channel_b);
309 
310  return diff;
311 }
312 
314 {
315  ssize_t ch_a, ch_b;
316  EST_Track cor;
317 
318  if (!a.has_channel(fname))
319  {
320  cerr << "Error: Couldn't find field named " << fname <<
321  " in first Track\n";
322  return cor;
323  }
324 
325  if (!b.has_channel(fname))
326  {
327  cerr << "Error: Couldn't find field named " << fname <<
328  " in second Track\n";
329  return cor;
330  }
331 
332  ch_a = a.channel_position(fname);
333  ch_b = b.channel_position(fname);
334 
335  return difference(a, b, ch_a, ch_b);
336 }
337 
338 
339 float mean( const EST_Track &tr, ssize_t channel )
340 {
341  if ( (int)channel<0 || channel >= tr.num_channels() )
342  EST_error( "Tried to access channel %d of %d channel track",
343  channel, tr.num_channels() );
344 
345  float mean=0.0;
346  ssize_t i, n;
347  ssize_t tr_num_frames = tr.num_frames();
348 
349  for( i=0, n=0; i<tr_num_frames; ++i )
350  if( !tr.track_break(i) ){
351  mean += tr.a_no_check( i, channel );
352  ++n;
353  }
354 
355  if (n == 0) return NAN;
356 
357  return mean/(float)n;
358 }
359 
360 void mean( const EST_Track &tr, EST_FVector &m )
361 {
362  int tr_num_channels = tr.num_channels();
363 
364  m.resize( tr_num_channels, 0 );
365 
366  for( ssize_t i=0; i<tr_num_channels; ++i )
367  m.a_no_check(i) = mean( tr, i );
368 }
369 
370 
371 /** Calculate the mead and standard deviation for a single channel of a track
372 */
373 
374 void meansd(EST_Track &tr, float &m, float &sd, ssize_t channel)
375 {
376  ssize_t i, n;
377 
378  m = mean( tr, channel );
379 
380  float var=0.0;
381  ssize_t tr_num_frames = tr.num_frames();
382  for( i=0, n=0; i<tr_num_frames; ++i)
383  if( !tr.track_break(i) ){
384  var += pow(tr.a_no_check(i, channel) - m, float(2.0));
385  ++n;
386  }
387 
388  if( n>1 ){ // use n, not tr_num_frames because of breaks
389  var /= (float) (n-1);
390  sd = sqrt(var);
391  }
392  else
393  sd = 0.0;
394 }
395 
396 /** Calculate the root mean square error between the same channel in
397 two tracks
398 @see abs_error, rms_error
399 */
400 float rms_error(EST_Track &a, EST_Track &b, ssize_t channel)
401 {
402  ssize_t i;
403  ssize_t size = Lof(a.num_frames(), b.num_frames());
404  float sum = 0;
405 
406  for (i = 0; i < size; ++i)
407  if (a.val(i) && b.val(i))
408  sum += pow((a.a(i, channel) - b.a(i, channel)), float(2.0));
409 
410  sum = sqrt(sum / size);
411  return sum;
412 }
413 
414 float abs_error(EST_Track &a, EST_Track &b, ssize_t channel)
415 {
416  ssize_t i;
417  ssize_t size = Lof(a.num_frames(), b.num_frames());
418  float sum = 0;
419  for (i = 0; i < size; ++i)
420  {
421  // cout << i << " " << a.a(i, channel) << " " << b.a(i, channel) << endl;
422  if (a.val(i) && b.val(i))
423  sum += fabs(a.a(i, channel) - b.a(i, channel));
424  }
425  return sum / size;
426 }
427 
428 float correlation(EST_Track &a, EST_Track &b, ssize_t channela, ssize_t channelb)
429 {
430  ssize_t i;
431  ssize_t size = Lof(a.num_frames(), b.num_frames());
432  float predict,real;
433  EST_SuffStats x,y,xx,yy,xy,se,e;
434  float cor,error;
435 
436  for (i = 0; i < size; ++i)
437  if (a.val(i) && b.val(i))
438  {
439 // cout << a.t(i) << " " << a.a(i, channela) << " " << b.a(i, channelb) << endl;
440  predict = b.a(i, channelb);
441  real = a.a(i, channela);
442  x += predict;
443  y += real;
444  error = predict-real;
445  se += error*error;
446  e += fabs(error);
447  xx += predict*predict;
448  yy += real*real;
449  xy += predict*real;
450  }
451 
452  cor = (xy.mean() - (x.mean()*y.mean()))/
453  (sqrt(xx.mean()-(x.mean()*x.mean())) *
454  sqrt(yy.mean()-(y.mean()*y.mean())));
455 
456 // cout << xy.mean() << " " << x.mean() << " " << y.mean() << " "
457 // << xx.mean() << " " << yy.mean() << endl;
458 
459  cout << "RMSE " << sqrt(se.mean()) << " Correlation is " << cor
460  << " Mean (abs) Error " << e.mean() << " (" << e.stddev() << ")"
461  << endl;
462  return cor;
463 }
464 
466 {
467  ssize_t i;
468 
469  m.resize(a.num_channels());
470  sd.resize(a.num_channels());
471 
472  for (i = 0; i < a.num_channels(); ++i)
473  meansd(a, m[i], sd[i], i);
474 }
475 
476 void meansd(EST_TrackList &tl, float &mean, float &sd, ssize_t channel)
477 {
478  EST_Litem *p;
479  float var=0.0;
480  ssize_t i, n;
481 
482  n = 0;
483  mean = 0.0;
484 
485  for (p = tl.head(); p; p = p->next())
486  for (i = 0; i < tl(p).num_frames(); ++i)
487  {
488  if (!tl(p).track_break(i))
489  {
490  mean += tl(p).a(i, channel);
491  ++n;
492  }
493  }
494  if (n == 0) {
495  mean = NAN;
496  sd = NAN;
497  return;
498  }
499 
500  mean /= n;
501 
502  for (p = tl.head(); p; p = p->next())
503  for (i = 0; i < tl(p).num_frames(); ++i)
504  if (!tl(p).track_break(i))
505  var += pow(tl(p).a(i, channel) - mean, float(2.0));
506 
507  var /= n;
508  sd = sqrt(var);
509 }
510 
512 {
513  ssize_t i;
514 
515  m.resize(tl.first().num_channels());
516  sd.resize(tl.first().num_channels());
517 
518  for (i = 0; i < tl.first().num_channels(); ++i)
519  meansd(tl, m[i], sd[i], i);
520 }
521 
523 {
524  ssize_t i;
525  EST_FVector e;
526 
527  // ERROR REORG - this needs to return a proper error
528  if (a.num_channels() != b.num_channels())
529  {
530  cerr << "Error: Can't compare " << a.num_channels() <<
531  " channel EST_Track with " << b.num_channels() << " channel EST_Track\n";
532  return e;
533  }
534  e.resize(a.num_channels());
535  for (i = 0; i < a.num_channels(); ++i)
536  e[i] = rms_error(a, b, i);
537 
538  return e;
539 }
540 
542 {
543  ssize_t i;
544  EST_FVector e;
545 
546  // ERROR REORG - this needs to return a proper error
547  if (a.num_channels() != b.num_channels())
548  {
549  cerr << "Error: Can't compare " << a.num_channels() <<
550  " channel EST_Track with " << b.num_channels() << " channel EST_Track\n";
551  return e;
552  }
553  e.resize(a.num_channels());
554  for (i = 0; i < a.num_channels(); ++i)
555  e[i] = abs_error(a, b, i);
556 
557  return e;
558 }
559 
561 {
562  ssize_t i;
563  EST_FVector cor;
564 
565  // ERROR REORG - this needs to return a proper error
566  if (a.num_channels() != b.num_channels())
567  {
568  cerr << "Error: Can't compare " << a.num_channels() <<
569  " channel EST_Track with " << b.num_channels() << " channel EST_Track\n";
570  return cor;
571  }
572  cor.resize(a.num_channels());
573  for (i = 0; i < a.num_channels(); ++i)
574  cor[i] = correlation(a, b, i, i);
575 
576  return cor;
577 }
578 
580 {
581  int ch_a, ch_b;
582  EST_FVector cor;
583 
584  if (!a.has_channel(fname))
585  {
586  cerr << "Error: Couldn't find field named " << fname <<
587  " in first Track\n";
588  return cor;
589  }
590 
591  if (!b.has_channel(fname))
592  {
593  cerr << "Error: Couldn't find field named " << fname <<
594  " in second Track\n";
595  return cor;
596  }
597 
598  ch_a = a.channel_position(fname);
599  ch_b = b.channel_position(fname);
600 
601  cor.resize(1);
602  cor[0] = correlation(a, b, ch_a, ch_b);
603 
604  return cor;
605 }
606 
607 EST_Track error(EST_Track &ref, EST_Track &test, int relax)
608 {
609  ssize_t i, j, k, l;
610  EST_Track diff;
611  diff = ref;
612  float t;
613 
614  // relaxation allows an error to be ignored near boundaries. The
615  // degree of relation specifies how many frames can be ignored.
616 
617  float *r = new float[relax*3];
618 
619  for (l = 0; l < ref.num_channels(); ++l)
620  for (i = 0; i < ref.num_frames(); ++i)
621  {
622  t = 0;
623  for (k = 0, j = Gof((i - relax), 0); j < i + relax + 1; ++j, ++k)
624  {
625  if (ref.a(i, l) > 0.5)
626  r[k] = ((j < test.num_frames()) && (test.a(j, l)> 0.6)) ?1
627  : 0.5;
628  else
629  r[k] = ((j < test.num_frames()) && (test.a(j, l)< 0.4)) ? -1
630  : -0.5;
631 
632  // fix for relaxation
633  t = r[k];
634  }
635 // cout << "ref: " << ref.a(i, l) << " test:" << test.a(i, l) << " error:" << t << endl;
636  diff.a(i, l) = t;
637  }
638 
639  delete [] r;
640  return diff;
641 }
642 
643 void align_to_track(EST_Track &tr, float &start, float &end)
644 {
645  ssize_t is, ie;
646 
647  // cout << " in " << start << " " << end << "\n";
648 
649  is = tr.index(start);
650  ie = tr.index(end);
651 
652  // cout << " indexes " << is << " " << ie << "\n";
653 
654  start = tr.t(is);
655  end = tr.t(ie);
656  // cout << " out " << start << " " << end << "\n";
657 }
658 
659 void align_to_track(EST_Track &tr, int &start, int &end, int sample_rate)
660 {
661  float start_t = start/(float)sample_rate;
662  float end_t = end/(float)sample_rate;
663 
664 
665  // cout << "align " << start_t << " " << end_t << " " << sample_rate << "\n";
666  align_to_track(tr, start_t, end_t);
667  // cout << " gives " << start_t << " " << end_t << "\n";
668 
669  start = (int)(start_t*sample_rate + 0.5);
670  end = (int)( end_t*sample_rate + 0.5);
671 }
672 
674  int &start, int &end,
675  int sample_rate,
676  float offset)
677 {
678  float start_t = start/(float)sample_rate;
679  float end_t = end/(float)sample_rate;
680 
681  // cout << "move " << start_t << " " << end_t << " " << sample_rate << "\n";
682 
683  int is = tr.index(start_t-offset);
684  int ie = tr.index(end_t-offset);
685 
686  ssize_t start_s, start_c, start_e;
687  ssize_t end_s, end_c, end_e=0;
688 
689  if (tr.has_channel(channel_length))
690  {
691  get_frame(tr, sample_rate, is, start_s, start_c, start_e);
692  get_frame(tr, sample_rate, ie, end_s, end_c, end_e);
693  }
694  else
695  {
696  start_s = (int)(tr.t(is) * sample_rate);
697  end_s = (int)(tr.t(ie) * sample_rate);
698  }
699 
700  start = start_s + (int)(offset*sample_rate + 0.5);
701  end = end_e + (int)(offset*sample_rate + 0.5);
702 }
703 
704 int nearest_boundary(EST_Track &tr, float time, int sample_rate, float offset)
705 {
706  time -= offset;
707 
708  float distance = 10000;
709 
710  for (ssize_t i = 0; i < tr.num_frames(); ++i)
711  {
712  float start, center, end;
713 
714  get_frame(tr, sample_rate, i, start, center, end);
715 
716  // printf("nb %f: %d distance %f start %f\n", time, i, distance, start);
717 
718  if (fabs(start-time) > distance)
719  return i-1;
720  distance = fabs(start-time);
721  }
722 
723  return tr.num_frames();
724 }
725 
726 void move_start(EST_Track &tr, float shift)
727 {
728  for(ssize_t i=0; i<tr.num_frames(); i++)
729  tr.t(i) += shift;
730 }
731 
732 void set_start(EST_Track &tr, float start)
733 {
734  float shift = start - tr.t(0);
735 
736  move_start(tr, shift);
737 }
738 
739 
740 void extract2(EST_Track &orig, float start, float end, EST_Track &ret)
741 {
742  int from, to;
743  ssize_t i, j;
744  from = orig.index(start);
745  to = orig.index_below(end);
746 
747  ret.copy_setup(orig);
748 
749  ret.resize(to - from, orig.num_channels());
750 
751  for (i = 0; i < ret.num_frames(); ++i)
752  for (j = 0; j < ret.num_channels(); ++j)
753  {
754  ret.a(i, j) = orig.a(i + from, j);
755  ret.t(i) = orig.t(i + from);
756  if (orig.track_break(i + from))
757  ret.set_break(i);
758  else
759  ret.set_value(i);
760  }
761 
762 
763  // cout << "from " << from << " to " << to << endl;
764  // cout << "times from " << orig.t(from) << " to " << orig.t(to) << endl;
765 
766  // orig.sub_track(ret, from, to);
767  // cout << ret.num_frames() << " " << ret.start() << " " << ret.end() << endl;
768  // cout << "ret " << ret;
769 }
770 
771 
772 void extract(EST_Track &orig, float start, float end, EST_Track &ret)
773 {
774  ssize_t new_num_frames;
775 
776  ret.copy_setup(orig);
777 
778  ssize_t i, j;
779  int is = 0, ie = 0;
780 
781  is = orig.index(start);
782  ie = orig.index(end);
783 
784  // check in case above results in negative length
785  new_num_frames = (ie - is) > 0 ?ie - is : 0;
786  ret.resize(new_num_frames, orig.num_channels());
787 
788  for (i = 0; i < new_num_frames; ++i)
789  {
790  for (j = 0; j < orig.num_channels(); ++j)
791  ret.a(i, j) = orig.a(i + is, j);
792  ret.t(i) = orig.t(i + is);
793  if (orig.track_break(i + is))
794  ret.set_break(i);
795  else
796  ret.set_value(i);
797  }
798 }
799 
800 int get_order(const EST_Track &t, EST_CoefficientType type, int d)
801 {
802  int order;
803  EST_ChannelType start_c = (EST_ChannelType)EST_CoefChannelId(type, d, 0);
805 
806  if (t.has_channel(start_c))
807  if (t.has_channel(end_c))
808  order = t.channel_position(end_c) - t.channel_position(start_c);
809  else
810  order = t.num_channels()-t.channel_position(start_c)-1;
811  else
812  order=0;
813  return order;
814 }
815 
816 int get_order(const EST_Track &tr)
817 {
818  int order=0;
820 
821  for(t=cot_first; t <cot_free; t=(EST_CoefficientType)(t+1))
822  if ((order=get_order(tr,t))>0)
823  return order;
824 
825  cout << "No coefficients in track\n";
826  return 0;
827 }
828 
829 int sum_lengths(const EST_Track &t,
830  int sample_rate,
831  ssize_t start_frame, ssize_t end_frame)
832 {
833  (void)sample_rate;
834  int l=0;
835 
837  for(ssize_t i=start_frame; i<end_frame; i++)
838  l += (ssize_t)t.a(i, channel_length);
839  else
840  {
841  cout << "no length channel";
842  }
843 
844  return l;
845 }
846 
847 void get_start_positions(const EST_Track &t, int sample_rate,
848  EST_TBuffer<int> &pos)
849 {
850  pos.ensure(t.num_frames());
851 
852  if (!t.has_channel(channel_length))
853  {
854  cout << "no length channel\n";
855  return;
856  }
857 
858  for(ssize_t i=0; i<t.num_frames(); i++)
859  {
860  ssize_t wstart, wcent, wend;
861  get_frame(t, sample_rate, i, wstart, wcent, wend);
862  pos[i] = wstart;
863  // cout << "frame " << i << " t " << t.t(i) << " sr " << sample_rate << " offset " << t.a(i,channel_offset) << " cent " << wcent << " pos " << wstart << "\n";
864  }
865 }
866 
867 
869 {
870  int from, to;
871  EST_Track sub_track;
872 
873  if (al.present("-start"))
874  from = tr.index(al.fval("-start"));
875  else if (al.present("-from"))
876  from = al.ival("-from");
877  else
878  from = 0;
879 
880  if (al.present("-end"))
881  to = tr.index(al.fval("-end"));
882  else if (al.present("-to"))
883  to = al.ival("-to");
884  else
885  to = tr.num_frames() - 1;
886 
887  tr.sub_track(sub_track, from, to-from+1, 0, EST_ALL);
888  EST_Track tr2 = sub_track;
889  tr = tr2;
890 }
891 
892 void extract_channel(EST_Track &orig, EST_Track &nt, EST_IList &ch_list)
893 {
894  ssize_t new_ch, i, j, k;
895  EST_Litem *p;
896  new_ch = ch_list.length();
897 
898  nt.copy_setup(orig);
899  nt.resize(orig.num_frames(), new_ch);
900 
901  for (i = 0, p = ch_list.head(); p; p = p->next(), ++i)
902  {
903  k = ch_list(p);
904 
905  if (k >= orig.num_channels())
906  EST_error("Tried to extract channel number %d from track with "
907  "only %d channels\n", k, orig.num_channels());
908 
909  for (j = 0; j < orig.num_frames(); ++j)
910  nt.a(j, i) = orig.a(j, k);
911  nt.set_channel_name(orig.channel_name(k), i);
912  }
913  for (j = 0; j < orig.num_frames(); ++j)
914  nt.t(j) = orig.t(j);
915 }
916 
917 void ParallelTracks(EST_Track &a, EST_TrackList &list,const EST_String &style)
918 {
919  // Make multi channel track out of list of tracks. There are two
920  // "styles". "0" means take the size of the first track in the list,
921  // "1" means take the size of the longest as the number of frames in
922  // the created track.
923  EST_Litem *p, *longest;
924  ssize_t num_channels, num_frames;
925  ssize_t i, j, k, n;
926 
927  for (num_channels=0,p=list.head(); p; p=p->next())
928  num_channels += list(p).num_channels();
929 
930  if (style == "first")
931  {
932  num_frames = list.first().num_frames();
933  longest = list.head();
934  }
935  else
936  {
937  if (style != "longest")
938  cerr << "EST_Track: unknown combine style \"" << style <<
939  "\" assuming longest" << endl;
940  for (num_frames = 0, longest = p = list.head(); p; p = p->next())
941  if (num_frames < list(p).num_frames())
942  {
943  num_frames = list(p).num_frames();
944  longest = p;
945  }
946  }
947 
948  a.resize(num_frames, num_channels);
949  a.fill(0.0);
950 
951  for (k = 0, p = list.head(); p; p = p->next())
952  {
953  n = Lof(num_frames, list(p).num_frames());
954  for (j = 0; j < list(p).num_channels(); ++j, ++k)
955  {
956  for (i = 0; i < n; ++i)
957  a(i, k) = list(p).a(i, j);
958  a.set_channel_name(list(p).channel_name(j), k);
959  }
960  }
961  // fill time with times from longest file.
962  for (i = 0; i < list(longest).num_frames(); ++i)
963  a.t(i) = list(longest).t(i);
964 }
965 
966 void channel_to_time(EST_Track &tr, ssize_t channel, float scale)
967 {
968 
969  for(ssize_t i=0; i < tr.num_frames(); i++)
970  {
971  tr.t(i) = tr.a(i,channel) * scale;
972  }
974 }
975 
976 void channel_to_time(EST_Track &tr, EST_ChannelType c, float scale)
977 {
978  ssize_t channel = NO_SUCH_CHANNEL;
979 
980  if (tr.map() != 0 && (channel = (tr.map()->get(c)) != NO_SUCH_CHANNEL))
981  {
982  channel_to_time(tr, channel, scale);
983  return;
984  }
985  else
986  {
987  cerr << "no channel '" << EST_default_channel_names.name(c) << "' = " << (int)c << "\n";
988  abort();
989  }
990 }
991 
992 void channel_to_time(EST_Track &tr, const EST_String c_name, float scale)
993 {
994  for (ssize_t c=0; c<tr.num_channels(); c++)
995  if (tr.channel_name(c) == c_name)
996  {
997  channel_to_time(tr, c, scale);
998  return;
999  }
1000 
1001  cerr << "no channel named '" << c_name << "'\n";
1002  abort();
1003 }
1004 
1005 void channel_to_time_lengths(EST_Track &tr, ssize_t channel, float scale)
1006 {
1007  float tt=0;
1008  for(ssize_t i=0; i < tr.num_frames(); i++)
1009  {
1010  // cout << "c_t_t " << i << " " << tt << "\n";
1011  tr.t(i) = tt;
1012  tt += tr.a(i,channel) * scale;
1013  }
1014  tr.set_equal_space(FALSE);
1015 }
1016 
1018 {
1019  ssize_t channel = NO_SUCH_CHANNEL;
1020 
1021  if (tr.map()!=0 && (channel = tr.map()->get(c)) != NO_SUCH_CHANNEL)
1022  {
1023  channel_to_time_lengths(tr, channel, scale);
1024  return;
1025  }
1026  else
1027  {
1028  cerr << "no channel '" << EST_default_channel_names.name(c) << "' = " << (int)c << "\n";
1029  abort();
1030  }
1031 }
1032 
1033 void channel_to_time_lengths(EST_Track &tr, const EST_String c_name, float scale)
1034 {
1035  for (ssize_t c=0; c<tr.num_channels(); c++)
1036  if (tr.channel_name(c) == c_name)
1037  {
1038  channel_to_time_lengths(tr, c, scale);
1039  return;
1040  }
1041 
1042  cerr << "no channel named '" << c_name << "'\n";
1043  abort();
1044 }
1045 
1047 {
1048  return
1049  EST_String("")+
1050  "-start <float> Extract track starting at this time, \n"
1051  " specified in seconds\n\n"
1052  "-end <float> Extract track ending at this time, \n"
1053  " specified in seconds\n\n"
1054  "-from <int> Extract track starting at this frame position\n\n"
1055  "-to <int> Extract track ending at this frame position\n\n";
1056 }
1057 
1059 {
1060  // The standard waveform input options
1061  return
1062  EST_String("")+
1063  "-itype <string> Input file type (optional). If no type is\n"
1064  " specified type is automatically derived from\n"
1065  " file's header. Supported types\n"
1066  " are: "+options_track_filetypes()+"\n\n"
1067 // remove ???
1068  "-ctype <string> Contour type: F0, track\n\n"
1069  "-s <float> Frame spacing of input in seconds, for unheadered input file\n\n"
1070  "-startt <float> Time of first frame, for formats which don't provide this\n\n"
1071  "-c <string> Select a subset of channels (starts from 0). \n"
1072  " Tracks can have multiple channels. This option \n"
1073  " specifies a list of numbers, refering to the channel \n"
1074  " numbers which are to be used for for processing. \n\n"+
1075  options_subtrack();
1076 }
1077 
1078 
1080 {
1081  // The standard track output options
1082  return
1083  EST_String("")+
1084  "-otype <string> {ascii}\n"+
1085  " Output file type, if unspecified ascii is\n"+
1086  " assumed, types are: "+options_track_filetypes()+", label\n\n"+
1087  "-S <float> Frame spacing of output in seconds. If this is \n"
1088  " different from the internal spacing, the contour is \n"
1089  " resampled at this spacing \n\n"
1090  "-o <ofile> Output filename, defaults to stdout\n\n";
1091 }
1092 
1094 {
1095  cout << t.name() << endl;
1096  cout << "Number of frames: " << t.num_frames() << endl;
1097  cout << "Number of channels: " << t.num_channels() << endl;
1098  cout << "File type: " << EST_TrackFile::map.name(t.file_type()) << endl;
1099  if (t.equal_space())
1100  cout << "Frame shift: " << t.shift() << endl;
1101  else
1102  cout << "Frame shift: varied" << endl;
1103  for (ssize_t i = 0; i < t.num_channels(); ++i)
1104  cout << "Channel: " << i << ": " << t.channel_name(i) << endl;
1105 }
1106 
1108 {
1109  // Returns list of currently support track filetypes
1110  // Should be extracted from the list in EST_Track
1111 
1113 }
1114 
1116 {
1117  // Returns list of currently support track filetypes
1118  // Should be extracted from the list in EST_Track
1119 
1121 }
1122 
void time_mean_smooth(EST_Track &c, float x)
float end(const EST_Item &item)
Definition: EST_item_aux.cc:96
short get(EST_ChannelType type) const
Get the position of a channel.
Definition: EST_TrackMap.h:136
void qsort(EST_TList< T > &a)
#define EST_CoefChannelId(CT, D, SE)
void move_to_frame_ends(EST_Track &tr, int &start, int &end, int sample_rate, float offset)
Move the start and end variables to the start and end of the nearest frame.
EST_CoefficientType
EST_ChannelType
double stddev(void) const
standard deviation of currently cummulated values
void channel_to_time(EST_Track &tr, ssize_t channel, float scale)
void get_start_positions(const EST_Track &t, int sample_rate, EST_TBuffer< int > &pos)
Find the start point in the signal of the sections of speech related to each frame.
void simple_mean_smooth(EST_Track &c, ssize_t n, ssize_t channel)
A vector class for floating point numbers. EST_FVector x should be used instead of float *x wherever ...
Definition: EST_FMatrix.h:119
void set_value(ssize_t i)
set frame i to be a value
Definition: EST_Track.cc:133
void set_channel_name(const EST_String &name, int channel)
set the name of the channel.
Definition: EST_Track.cc:168
void set_break(ssize_t i)
set frame i to be a break
Definition: EST_Track.cc:124
int ival(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:82
EST_String name() const
name of track - redundant use access to features
Definition: EST_Track.h:196
int num_channels() const
return number of channels in track
Definition: EST_Track.h:657
float rms_error(EST_Track &a, EST_Track &b, ssize_t channel)
double mean(void) const
mean of currently cummulated values
EST_TrackFileType file_type() const
Definition: EST_Track.h:733
void ensure(unsigned int req_size)
Extend if needed, copying existing data.
Definition: EST_TBuffer.h:128
INLINE const T & a_no_check(ssize_t n) const
read-only const access operator: without bounds checking
Definition: EST_TVector.h:254
float abs_error(EST_Track &a, EST_Track &b, ssize_t channel)
ssize_t index_below(float x) const
return the frame index before time t
Definition: EST_Track.cc:521
void set_start(EST_Track &tr, float start)
Move the track so that it starts at the indicated time.
float fval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:104
int ssize_t
#define VAL_REGISTER_CLASS(NAME, CLASS)
Definition: EST_Val_defs.h:62
const int EST_ALL
void resize(ssize_t num_frames, int num_channels, bool preserve=1)
Definition: EST_Track.cc:214
float & a_no_check(ssize_t i, int c=0)
Definition: EST_Track.h:420
static EST_String options_short(void)
#define Lof(a, b)
Definition: EST_cutils.h:97
void extract(EST_Track &orig, float start, float end, EST_Track &ret)
ssize_t index(float t) const
return the frame index nearest time t
Definition: EST_Track.cc:473
EST_UItem * next()
Definition: EST_UList.h:55
EST_Track error(EST_Track &ref, EST_Track &test, int relax)
guaranteed to be the first known type
void time_med_smooth(EST_Track &c, float x)
void track_smooth(EST_Track &c, float x, EST_String stype)
void sub_track(EST_Track &st, int start_frame=0, int nframes=EST_ALL, int start_chan=0, int nchans=EST_ALL)
Definition: EST_Track.cc:1100
float correlation(EST_Track &a, EST_Track &b, ssize_t cha, ssize_t chb)
int track_break(ssize_t i) const
return true if frame i is a break
Definition: EST_Track.h:634
int channel_position(const char *name, int offset=0) const
Definition: EST_Track.cc:395
bool equal_space() const
return true if track has equal (i.e. fixed) frame spacing */
Definition: EST_Track.h:670
float & t(ssize_t i=0)
return time position of frame i
Definition: EST_Track.h:478
float & a(ssize_t i, int c=0)
Definition: EST_Track.cc:1025
const char * name(ENUM tok, int n=0) const
void copy_setup(const EST_Track &a)
copy everything but data
Definition: EST_Track.cc:205
void move_start(EST_Track &tr, float shift)
Move the track by shift seconds.
EST_String options_track_filetypes_long(void)
int nearest_boundary(EST_Track &tr, float time, int sample_rate, float offset)
Index of the frame whose start boundary.
void track_info(EST_Track &t)
void channel_to_time_lengths(EST_Track &tr, ssize_t channel, float scale)
void simple_med_smooth(EST_Track &c, ssize_t n, ssize_t channel)
#define FALSE
Definition: EST_bool.h:119
EST_String options_subtrack(void)
float time(const EST_Item &item)
Definition: EST_item_aux.cc:82
void align_to_track(EST_Track &tr, float &start, float &end)
Move the start and end variables to the nearest frame.
#define EST_error
Definition: EST_error.h:104
const T & first() const
return const reference to first item in list
Definition: EST_TList.h:152
f
Definition: EST_item_aux.cc:48
static EST_TNamedEnumI< EST_TrackFileType, Info > map
void sample(float shift)
Definition: EST_Track.cc:674
ssize_t num_frames() const
return number of frames in track
Definition: EST_Track.h:651
Length of section in samples.
getString int
Definition: EST_item_aux.cc:50
EST_Track difference(EST_Track &a, EST_Track &b)
int length() const
Definition: EST_UList.cc:57
const EST_String channel_name(int channel, const EST_ChannelNameMap &map, int strings_override=1) const
Definition: EST_Track.cc:138
EST_ChannelNameMap EST_default_channel_names
Definition of standard names we use for channels.
void fill(float v)
Definition: EST_Track.h:501
void absolute(EST_Track &tr)
float mean(const EST_Track &tr, ssize_t channel)
#define Gof(a, b)
Definition: EST_cutils.h:95
float start(const EST_Item &item)
Definition: EST_item_aux.cc:52
void extract2(EST_Track &orig, float start, float end, EST_Track &ret)
EST_UItem * t
Definition: EST_UList.h:62
int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
void normalise(EST_Track &tr)
EST_UItem * head() const
Definition: EST_UList.h:97
int val(ssize_t i) const
return true if frame i is a value
Definition: EST_Track.cc:542
float shift() const
Definition: EST_Track.cc:602
int get_order(const EST_Track &t, EST_CoefficientType type, int d)
How many coefficients in track (looks for Coef0 and coefN channels)
void ParallelTracks(EST_Track &a, EST_TrackList &list, const EST_String &style)
int sum_lengths(const EST_Track &t, int sample_rate, ssize_t start_frame, ssize_t end_frame)
Total the length channel values.
EST_String options_track_filetypes(void)
EST_Track differentiate(EST_Track &c, float samp_int)
EST_String
Extending buffer class.
Definition: EST_TBuffer.h:86
void extract_channel(EST_Track &orig, EST_Track &nt, EST_IList &ch_list)
bool has_channel(const char *name) const
Definition: EST_Track.h:385
float sum(const EST_FMatrix &a)
sum of elements
Definition: vec_mat_aux.cc:147
void set_equal_space(bool t)
Definition: EST_Track.h:675
EST_String options_track_input(void)
EST_String options_track_output(void)
void meansd(EST_Track &tr, float &m, float &sd, ssize_t channel)
void resize(int n, int set=1)
resize vector
static EST_String options_supported(void)
#define NO_SUCH_CHANNEL
Returned if we ask for a channel not in the map.
Definition: EST_TrackMap.h:86
EST_TrackMap::P map() const
Definition: EST_Track.h:698
Guaranteed to be one more than last legal coefficient type.