Edinburgh Speech Tools  2.4-release
EST_TrackFile.cc
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 /* File I/O functions for EST_Track class */
37 /* */
38 /*=======================================================================*/
39 #include <fstream>
40 #include <iostream>
41 #include <cstdlib>
42 #include <cmath>
43 #include <time.h>
44 #include "EST_unix.h"
45 #include "EST_types.h"
46 #include "EST_Track.h"
47 #include "EST_track_aux.h"
48 #include "EST_TrackMap.h"
49 #include "EST_cutils.h"
50 #include "EST_Token.h"
51 #include "EST_TList.h"
52 #include "EST_string_aux.h"
53 #include "EST_walloc.h"
54 #include "EST_TrackFile.h"
55 #include "EST_FileType.h"
56 #include "EST_WaveFile.h"
57 #include "EST_wave_utils.h"
58 
59 // size of locally allocated buffer. If more channels than this we have to
60 // call new
61 
62 #define NEARLY_ZERO 0.00001
63 
64 #define REASONABLE_FRAME_SIZE (20)
65 #define UNREASONABLE_FRAME_SIZE (80)
66 
67 #if 0
68 static const char *NIST_SIG = "NIST_1A\n 1024\n";
69 static const char *NIST_END_SIG = "end_head\n";
70 #define NIST_HDR_SIZE 1024
71 // default for tracks is the standard EMA sample rate
72 static int def_load_sample_rate = 500;
73 
74 #endif
75 
76 // some functions written for reading NIST headered waveform files,
77 // but useful here.
78 int nist_get_param_int(char *hdr, char *field, int def_val);
79 char *nist_get_param_str(char *hdr, char *field, char *def_val);
80 const char *sample_type_to_nist(enum EST_sample_type_t sample_type);
81 enum EST_sample_type_t nist_to_sample_type(char *type);
82 
83 EST_read_status read_est_header(EST_TokenStream &ts, EST_Features &hinfo,
84  bool &ascii, EST_EstFileType &t);
85 
86 EST_read_status EST_TrackFile::load_esps(const EST_String filename, EST_Track &tr, float ishift, float startt)
87 {
88  (void)ishift;
89  (void)startt;
90 
91  float **tt;
92  float fsize;
93  char **fields;
94  int num_points, num_fields, num_values;
95  int i,j;
96  EST_read_status r_val;
97  short fixed;
98  int first_channel=0;
99 
100  r_val = get_track_esps(filename, &fields, &tt, &fsize, &num_points,
101  &num_values, &fixed);
102  if (r_val == misc_read_error)
103  {
104  cerr << "Error reading ESPS file " << filename << endl;
105  return misc_read_error;
106  }
107  else if (r_val == wrong_format)
108  return wrong_format;
109 
110  num_fields = num_values;
111  if (!fixed)
112  {
113  --num_fields;
114  ++first_channel;
115  }
116 
117  tr.resize(num_points,num_fields);
118  tr.fill_time(fsize);
119 
120  for (i = 0; i < num_points; ++i)
121  {
122  for (j = 0; j < num_fields; ++j)
123  tr.a(i, j) = tt[i][j+first_channel];
124  tr.set_value(i);
125  if (!fixed)
126  tr.t(i) = tt[i][0];
127  }
128 
129  for (i = 0; i < num_fields; ++i)
130  tr.set_channel_name(fields[i+first_channel], i);
131 
132 
133  // REORG not sure what these should be -- awb
134  tr.set_single_break(false);
135  tr.set_equal_space(true);
136 
137  // get_track_esps allocs all the memory, we therefore need to release it
138  for (i = 0; i < num_values; ++i)
139  wfree(fields[i]);
140  wfree(fields);
141  for (i = 0; i < num_values; ++i)
142  wfree(tt[i]);
143  wfree(tt);
144 
145  tr.set_file_type(tff_esps);
146  tr.set_name(filename);
147 
148  if (tr.channel_name(0) == "F0")
149  espsf0_to_track(tr);
150 
151  return format_ok;
152 }
153 
154 EST_read_status EST_TrackFile::load_ascii(const EST_String filename, EST_Track &tr, float ishift, float startt)
155 {
156  (void)startt;
157 
158  EST_TokenStream ts, tt;
159  EST_StrList sl;
160 
161  int i, j, n_rows, n_cols=0;
162  EST_String t;
163  EST_Litem *p;
164 
165  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
166  {
167  cerr << "Can't open track file " << filename << endl;
168  return misc_read_error;
169  }
170  // set up the character constant values for this stream
171  ts.set_SingleCharSymbols(";");
172 
173  if (ishift < NEARLY_ZERO)
174  {
175  cerr<<
176  "Error: Frame spacing must be specified (or apparent frame shift nearly zero)\n";
177  return misc_read_error;
178  }
179 
180  // first read in as list
181 
182  for (n_rows = 0; !ts.eof(); ++n_rows)
183  sl.append(ts.get_upto_eoln().string());
184 
185  if (n_rows > 0)
186  {
187  tt.open_string(sl.first());
188  for (n_cols = 0; !tt.eof(); ++n_cols)
189  tt.get().string();
190  }
191 
192  // resize track and copy values in
193  tr.resize(n_rows, n_cols);
194 
195  for (p = sl.head(), i = 0; p != 0; ++i, p = p->next())
196  {
197  bool ok;
198  tt.open_string(sl(p));
199  for (j = 0; !tt.eof(); ++j)
200  tr.a(i, j) = tt.get().Float(ok);
201  if (j != n_cols)
202  {
203  cerr << "Wrong number of points in row " << i << endl;
204  cerr << "Expected " << n_cols << " got " << j << endl;
205  return misc_read_error;
206  }
207  }
208 
209  tr.fill_time(ishift);
210  tr.set_single_break(FALSE);
211  tr.set_equal_space(TRUE);
212  tr.set_file_type(tff_ascii);
213  tr.set_name(filename);
214 
215  return format_ok;
216 }
217 
218 EST_read_status EST_TrackFile::load_xgraph(const EST_String filename, EST_Track &tr, float ishift, float startt)
219 {
220  (void)ishift;
221  (void)startt;
222 
223  EST_TokenStream ts, tt;
224  EST_StrList sl;
225  // const float NEARLY_ZERO = 0.001;
226  int i, j, n_rows, n_cols;
227  EST_String t;
228  EST_Litem *p;
229 
230  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
231  {
232  cerr << "Can't open track file " << filename << endl;
233  return misc_read_error;
234  }
235  // set up the character constant values for this stream
236  ts.set_SingleCharSymbols(";");
237 
238  // first read in as list
239 
240  for (n_rows = 0; !ts.eof(); ++n_rows)
241  sl.append(ts.get_upto_eoln().string());
242 
243  tt.open_string(sl.first());
244  for (n_cols = 0; !tt.eof(); ++n_cols)
245  tt.get().string();
246 
247  --n_cols; // first column is time marks
248 
249  // resize track and copy values in
250  tr.resize(n_rows, n_cols);
251 
252  for (p = sl.head(), i = 0; p != 0; ++i, p = p->next())
253  {
254  bool ok;
255  tt.open_string(sl(p));
256  tr.t(i) = tt.get().Float(ok);
257  for (j = 0; !tt.eof(); ++j)
258  tr.a(i, j) = tt.get().Float(ok);
259  if (j != n_cols)
260  {
261  cerr << "Wrong number of points in row " << i << endl;
262  cerr << "Expected " << n_cols << " got " << j << endl;
263  return misc_read_error;
264  }
265  }
266 
267  tr.set_single_break(FALSE);
268  tr.set_equal_space(TRUE);
269  tr.set_file_type(tff_xgraph);
270  tr.set_name(filename);
271 
272  return format_ok;
273 }
274 
275 EST_read_status EST_TrackFile::load_xmg(const EST_String filename, EST_Track &tr, float ishift, float startt)
276 {
277  (void)ishift;
278  (void)startt;
279 
280  EST_TokenStream ts;
281  EST_StrList sl;
282  int i, n;
283  EST_String t, k, v;
284  EST_Litem *p;
285 
286  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
287  {
288  cerr << "Can't open track file " << filename << endl;
289  return misc_read_error;
290  }
291  // set up the character constant values for this stream
292  ts.set_SingleCharSymbols(";");
293 
294  if (ts.peek().string() != "XAO1")
295  return wrong_format;
296 
297  ts.get().string();
298 
299  while ((!ts.eof()) && (ts.peek().string() != "\014"))
300  {
301  k = ts.get().string();
302  v = ts.get().string();
303 #if 0
304  /* Tracks don't represent these explicitly */
305  if (k == "Freq")
306  sr = v.Int() * 1000;
307  else if (k == "YMin")
308  /* tr.amin = atof(v) */;
309  else if (k == "YMax")
310  /*tr.amax = atof(v) */;
311 #endif
312  }
313 
314  if (ts.eof())
315  {
316  cerr << "Unexpected end of file in reading xmg header\n";
317  return misc_read_error;
318  }
319  ts.get().string(); // read control L
320  ts.get_upto_eoln().string(); // read until end of header
321 
322  // read in lines to a list
323  for (n = 0; !ts.eof(); ++n)
324  sl.append(ts.get_upto_eoln().string());
325 
326  // note the track size is total number of points *and* breaks
327  tr.resize(n, 1 ); // REORG - fix this for multi channel work
328 
329  for (p = sl.head(), i = 0; p != 0; ++i, p = p->next())
330  {
331  bool ok;
332  ts.open_string(sl(p));
333  if (ts.peek().string() != "=")
334  {
335  tr.t(i) = ts.get().Float(ok) / 1000.0;
336  tr.a(i) = ts.get().Float(ok);
337  }
338  else
339  {
340  ts.get().string();
341  tr.set_break(i);
342  }
343  }
344 
345  tr.set_single_break(TRUE);
346  tr.set_equal_space(FALSE);
347  tr.set_file_type(tff_xmg);
348  tr.set_name(filename);
349 
350  return format_ok;
351 }
352 
353 EST_read_status EST_TrackFile::load_est(const EST_String filename,
354  EST_Track &tr, float ishift, float startt)
355 {
356  EST_TokenStream ts;
357  EST_read_status r;
358 
359  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
360  {
361  cerr << "Can't open track file " << filename << endl;
362  return misc_read_error;
363  }
364  // set up the character constant values for this stream
365  ts.set_SingleCharSymbols(";");
366  tr.set_name(filename);
367  r = load_est_ts(ts, tr, ishift, startt);
368 
369  if ((r == format_ok) && (!ts.eof()))
370  {
371  cerr << "Not end of file, but expected it\n";
372  return misc_read_error;
373  }
374  else
375  return r;
376 }
377 
378 static float get_float(EST_TokenStream &ts,int swap)
379 {
380  float f;
381  ts.fread(&f,4,1);
382  if (swap) swapfloat(&f);
383  return f;
384 }
385 
386 EST_read_status EST_TrackFile::load_est_ts(EST_TokenStream &ts,
387  EST_Track &tr, float ishift, float startt)
388 {
389  (void)ishift;
390  (void)startt;
391  int i, j;
392  int num_frames, num_channels;
393  EST_Features hinfo;
394  EST_EstFileType t;
395  EST_String v;
396  bool ascii;
397  bool breaks;
398  bool eq_space;
399  EST_read_status r;
400  int swap;
401 
402  if ((r = read_est_header(ts, hinfo, ascii, t)) != format_ok)
403  return r;
404  if (t != est_file_track)
405  return misc_read_error;
406 
407  breaks = hinfo.present("BreaksPresent") ? true : false;
408  eq_space = false;
409  if ((hinfo.present("EqualSpace")) &&
410  ((hinfo.S("EqualSpace") == "true") ||
411  (hinfo.S("EqualSpace") == "1")))
412  eq_space = true;
413 
414  num_frames = hinfo.I("NumFrames");
415  num_channels = hinfo.I("NumChannels");
416  tr.resize(num_frames, num_channels);
417 
418  hinfo.remove("NumFrames");
419  hinfo.remove("EqualSpace");
420  hinfo.remove("NumChannels");
421  hinfo.remove("BreaksPresent");
422  hinfo.remove("DataType");
423 
424  EST_String strn, cname;
425 
427  EST_StrList ch_map;
428 
429  for (p.begin(hinfo); p;)
430  {
431  c = p++;
432 
433  if (c->k.contains("Channel_"))
434  {
435  tr.set_channel_name(c->v.String(),
436  c->k.after("Channel_").Int());
437  hinfo.remove(c->k);
438  }
439  }
440 
441  tr.resize_aux(ch_map);
442 
443 // tr.create_map();
444 
445 // if (((hinfo.S("ByteOrder", "") == "01") ? bo_little : bo_big)
446 
447  if (!hinfo.present("ByteOrder"))
448  swap = FALSE; // ascii or not there for some reason
449  else if (((hinfo.S("ByteOrder") == "01") ? bo_little : bo_big)
450  != EST_NATIVE_BO)
451  swap = TRUE;
452  else
453  swap = FALSE;
454 
455  const int BINARY_CHANNEL_BUFFER_SIZE=1024;
456  float *frame=0;
457  float frame_buffer[BINARY_CHANNEL_BUFFER_SIZE];
458  if( !ascii )
459  {
460  if( num_channels > BINARY_CHANNEL_BUFFER_SIZE )
461  frame = new float[num_channels];
462  else
463  frame = frame_buffer;
464  }
465 
466  // there are too many ifs here
467  for (i = 0; i < num_frames; ++i)
468  {
469  bool ok;
470 
471  // Read Times
472  if (ascii)
473  {
474  if (ts.eof())
475  {
476  cerr << "unexpected end of file when looking for " << num_frames-i << " more frame(s)" << endl;
477  return misc_read_error;
478  }
479  tr.t(i) = ts.get().Float(ok);
480  if (!ok)
481  return misc_read_error;
482  }
483  else
484  tr.t(i) = get_float(ts,swap);
485 
486  // Read Breaks
487  if (breaks)
488  {
489  if (ascii)
490  {
491  v = ts.get().string();
492  if (v == "0")
493  tr.set_break(i);
494  else
495  tr.set_value(i);
496  }
497  else
498  {
499  if (get_float(ts,swap) == 0.0)
500  tr.set_break(i);
501  else
502  tr.set_value(i);
503  }
504  }
505  else
506  tr.set_value(i);
507 
508  // Read Channels
509 // for (j = 0; j < num_channels; ++j)
510 // {
511 // if(ascii)
512 // {
513 // tr.a(i, j) = ts.get().Float(ok);
514 // if (!ok)
515 // return misc_read_error;
516 // }
517 // else
518 // tr.a(i,j) = get_float(ts,swap);
519 // }
520 
521  if( ascii ){
522  for (j = 0; j < num_channels; ++j){
523  tr.a(i, j) = ts.get().Float(ok);
524  if (!ok)
525  return misc_read_error;
526  }
527  }
528  else{
529  ts.fread( frame, sizeof(float), num_channels );
530  if( swap )
531  for( j=0; j<num_channels; ++j ){
532  swapfloat( &frame[j] );
533  tr.a(i,j) = frame[j];
534  }
535  else
536  for( j=0; j<num_channels; ++j )
537  tr.a(i,j) = frame[j];
538  }
539 
540 
541  // Read aux Channels
542  for (j = 0; j < tr.num_aux_channels(); ++j)
543  {
544  if (ascii)
545  {
546  tr.aux(i, j) = ts.get().string();
547  if (!ok)
548  return misc_read_error;
549  }
550  else
551  {
552  cerr << "Warning: Aux Channel reading not yet implemented";
553  cerr << "for binary tracks\n";
554  }
555  }
556  }
557 
558  if( !ascii )
559  if( frame != frame_buffer )
560  delete [] frame;
561 
562  // copy header info into track
563  tr.f_set(hinfo);
564 
565  tr.set_single_break(FALSE);
566  tr.set_equal_space(eq_space);
567 
568  if(ascii)
569  tr.set_file_type(tff_est_ascii);
570  else
571  tr.set_file_type(tff_est_binary);
572 
573  return format_ok;
574 }
575 
576 EST_read_status load_snns_res(const EST_String filename, EST_Track &tr,
577  float ishift, float startt)
578 {
579  (void)startt;
580 
581  EST_TokenStream ts, str;
582  EST_StrList sl;
583  int i, j;
584  EST_String t, k, v;
585 
586  if (ishift < NEARLY_ZERO)
587  {
588  cerr<<
589  "Error: Frame spacing must be specified (or apparent frame shift nearly zero)\n";
590  return misc_read_error;
591  }
592 
593  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
594  {
595  cerr << "Can't open track file " << filename << endl;
596  return misc_read_error;
597  }
598 
599  if (ts.get().string() != "SNNS")
600  return wrong_format;
601  if (ts.get().string() != "result")
602  return wrong_format;
603 
604  ts.get_upto_eoln(); // SNNS bit
605  ts.get_upto_eoln(); // Time info
606 
607  int num_frames=0, num_channels=0;
608  int teaching = 0;
609 
610  while (1)
611  {
612  t = (EST_String)ts.get_upto_eoln();
613  // cout << "t=" << t << endl;
614  if (t.contains("teaching output included"))
615  teaching = 1;
616  if (!t.contains(":"))
617  break;
618  str.open_string(t);
619  k = (EST_String)str.get_upto(":");
620  v = (EST_String)str.get_upto_eoln();
621  if (k == "No. of output units")
622  num_channels = v.Int();
623  if (k == "No. of patterns")
624  num_frames = v.Int();
625 
626  // cout << "key " << k << endl;
627  // cout << "val " << v << endl;
628  }
629 
630  // cout << "num_frames = " << num_frames << endl;
631  // cout << "num_channels = " << num_channels << endl;
632  tr.resize(num_frames, num_channels);
633  // cout << "peek" << ts.peek().string() << endl;
634  // cout << "teaching " << teaching << endl;
635 
636  for (i = 0; (!ts.eof()) && (i < num_frames);)
637  // for (i = 0; i < 10; ++i)
638  {
639  if (ts.peek().string().contains("#")) // comment
640  {
641  ts.get_upto_eoln();
642  continue;
643  }
644  if (teaching) // get rid of teaching patterns
645  for (j = 0; j < num_channels; ++j)
646  ts.get().string();
647 
648  // cout << "i = " << i << " t = " << ts.peek().string() << endl;
649 
650  bool ok;
651 
652  for (j = 0; j < num_channels; ++j)
653  tr.a(i, j) = ts.get().Float(ok);
654 
655  ++i;
656  }
657 
658  tr.fill_time(ishift);
659  tr.set_single_break(FALSE);
660  tr.set_equal_space(TRUE);
661  tr.set_file_type(tff_snns);
662  tr.set_name(filename);
663 
664  return format_ok;
665 }
666 
667 EST_write_status EST_TrackFile::save_esps(const EST_String filename, EST_Track tr)
668 {
669  EST_write_status rc;
670  int i, j;
671  float shift;
672  bool include_time;
673  int extra_channels=0;
674 
675  EST_Track &track_tosave = tr;
676 
677  if (filename == "-")
678  {
679  cerr << "Output to stdout not available for ESPS file types:";
680  cerr << "no output written\n";
681  return write_fail;
682  }
683 
684  if ((include_time = (track_tosave.equal_space() != TRUE)))
685  {
686  shift = EST_Track::default_frame_shift;
687  extra_channels++;
688  }
689  else
690  shift = track_tosave.shift();
691 
692  track_tosave.change_type(0.0,FALSE);
693 
694  float **a = new float*[track_tosave.num_frames()];
695  // pity we need to copy it
696  for (i=0; i < track_tosave.num_frames(); i++)
697  {
698  a[i] = new float[track_tosave.num_channels() + extra_channels];
699 
700  if (include_time)
701  a[i][0] = track_tosave.t(i);
702 
703  for (j=0; j < track_tosave.num_channels(); j++)
704  a[i][j + extra_channels] = track_tosave.a(i,j);
705  }
706 
707  char **f_names = new char*[track_tosave.num_channels() + extra_channels];
708  for (i=0; i < track_tosave.num_channels(); i++)
709  {
710  // cout << "field " << i << "is '" << track_tosave.field_name(i) << "'\n";
711  f_names[i + extra_channels] = wstrdup(track_tosave.channel_name(i, esps_channel_names, 0));
712  }
713 
714  if (include_time)
715  f_names[0] = wstrdup("EST_TIME");
716 
717  rc = put_track_esps(filename, f_names,
718  a, shift, 1.0/shift,
719  track_tosave.num_channels() + extra_channels,
720  track_tosave.num_frames(),
721  !include_time);
722 
723  for (i=0; i < track_tosave.num_frames(); i ++)
724  delete [] a[i];
725  delete [] a;
726  for (i=0; i < track_tosave.num_channels()+extra_channels; i++)
727  delete [] f_names[i];
728  delete [] f_names;
729 
730  return rc;
731 }
732 
733 EST_write_status EST_TrackFile::save_est_ts(FILE *fp, EST_Track tr)
734 {
735  int i, j;
736 
737  fprintf(fp, "EST_File Track\n"); // EST header identifier.
738  fprintf(fp, "DataType ascii\n");
739  fprintf(fp, "NumFrames %d\n", tr.num_frames());
740  fprintf(fp, "NumChannels %d\n", tr.num_channels());
741  fprintf(fp, "NumAuxChannels %d\n", tr.num_aux_channels());
742  fprintf(fp, "EqualSpace %d\n",tr.equal_space());
743 
744  fprintf(fp, "BreaksPresent true\n");
745  for (i = 0; i < tr.num_channels(); ++i)
746  fprintf(fp, "Channel_%d %s\n", i, (const char *)(tr.channel_name(i)));
747 
748  for (i = 0; i < tr.num_aux_channels(); ++i)
749  fprintf(fp, "Aux_Channel_%d %s\n", i,
750  (const char *)(tr.aux_channel_name(i)));
751 
753 
754  for (p.begin(tr); p; ++p)
755  fprintf(fp, "%s %s\n", (const char *)p->k,
756  (const char *) p->v.String());
757 
758  fprintf(fp, "EST_Header_End\n");
759 
760  for (i = 0; i < tr.num_frames(); ++i)
761  {
762  fprintf(fp, "%f\t", tr.t(i));
763  fprintf(fp, "%s\t", (char *)(tr.val(i) ? "1 " : "0 "));
764  for (j = 0; j < tr.num_channels(); ++j)
765  fprintf(fp, "%g ", tr.a_no_check(i, j));
766  for (j = 0; j < tr.num_aux_channels(); ++j)
767  fprintf(fp, "%s ", (const char *)tr.aux(i, j).string());
768  fprintf(fp, "\n");
769  }
770  return write_ok;
771 }
772 
773 EST_write_status EST_TrackFile::save_est_ascii(const EST_String filename,
774  EST_Track tr)
775 {
776  FILE *fd;
777  EST_write_status r;
778 
779  if (filename == "-")
780  fd = stdout;
781  else if ((fd = fopen(filename,"wb")) == NULL)
782  return write_fail;
783 
784  r = save_est_ts(fd,tr);
785 
786  if (fd != stdout)
787  fclose(fd);
788  return r;
789 }
790 
791 EST_write_status EST_TrackFile::save_est_binary(const EST_String filename, EST_Track tr)
792 {
793  FILE *fd;
794  EST_write_status r;
795 
796  if (filename == "-")
797  fd = stdout;
798  else if ((fd = fopen(filename,"wb")) == NULL)
799  return write_fail;
800 
801  r = save_est_binary_ts(fd,tr);
802 
803  if (fd != stdout)
804  fclose(fd);
805  return r;
806 
807 }
808 
809 EST_write_status EST_TrackFile::save_est_binary_ts(FILE *fp, EST_Track tr)
810 {
811  int i,j;
812 
813  // This should be made optional
814  bool breaks = TRUE;
815 
816  fprintf(fp, "EST_File Track\n");
817  fprintf(fp, "DataType binary\n");
818  fprintf(fp, "ByteOrder %s\n", ((EST_NATIVE_BO == bo_big) ? "10" : "01"));
819  fprintf(fp, "NumFrames %d\n", tr.num_frames());
820  fprintf(fp, "NumChannels %d\n",tr.num_channels());
821  fprintf(fp, "EqualSpace %d\n",tr.equal_space());
822  if(breaks)
823  fprintf(fp, "BreaksPresent true\n");
824  fprintf(fp, "CommentChar ;\n\n");
825  for (i = 0; i < tr.num_channels(); ++i)
826  fprintf(fp, "Channel_%d %s\n",i,tr.channel_name(i).str());
827  fprintf(fp, "EST_Header_End\n");
828 
829  for (i = 0; i < tr.num_frames(); ++i)
830  {
831  // time
832  if((int)fwrite(&tr.t(i),4,1,fp) != 1)
833  return misc_write_error;
834 
835  // break marker
836  if (breaks)
837  {
838  float bm = (tr.val(i) ? 1 : 0);
839  if((int)fwrite(&bm,4,1,fp) != 1)
840  return misc_write_error;
841  }
842  // data - restricted to floats at this time
843  for (j = 0; j < tr.num_channels(); ++j)
844  if((int)fwrite(&tr.a_no_check(i, j),4,1,fp) != 1)
845  return misc_write_error;
846 
847  }
848  return write_ok;
849 }
850 
851 EST_write_status EST_TrackFile::save_ascii(const EST_String filename, EST_Track tr)
852 {
853  /* We want to print these "nice" but not lose precision for
854  various precisioned numbers. so we're going to use %g to do this */
855  char fbuf[100];
856 
857  if (tr.equal_space() == TRUE)
858  tr.change_type(0.0, FALSE);
859 
860  ostream *outf;
861  if (filename == "-")
862  outf = &cout;
863  else
864  outf = new ofstream(filename);
865 
866  if (!(*outf))
867  return write_fail;
868 
869  outf->precision(5);
870  outf->setf(ios::fixed, ios::floatfield);
871  outf->width(8);
872 
873  for (int i = 0; i < tr.num_frames(); ++i)
874  {
875  for (int j = 0; j < tr.num_channels(); ++j)
876  {
877  snprintf(fbuf,sizeof(fbuf),"%g",tr.a(i, j));
878  *outf << fbuf << " ";
879  }
880  *outf << endl;
881  }
882 
883  if (outf != &cout)
884  delete outf;
885 
886  return write_ok;
887 }
888 
889 EST_write_status EST_TrackFile::save_xgraph(const EST_String filename, EST_Track tr)
890 {
891 
892  ostream *outf;
893 
894  if (filename == "-")
895  outf = &cout;
896  else
897  outf = new ofstream(filename);
898 
899  if (!(*outf))
900  return write_fail;
901 
902  tr.change_type(0.0, TRUE);
903 
904  for (int j = 0; j < tr.num_channels(); ++j)
905  {
906  *outf << "\""<< tr.channel_name(j) << "\"\n";
907  for (int i = 0; i < tr.num_frames(); ++i)
908  if (tr.val(i))
909  *outf << tr.t(i) << "\t" << tr.a(i, j) << endl;
910  else
911  *outf << "move ";
912  }
913  if (outf != &cout)
914  delete outf;
915 
916  return write_ok;
917 }
918 
919 EST_write_status save_snns_pat(const EST_String filename,
920  EST_TrackList &inpat, EST_TrackList &outpat)
921 {
922  ostream *outf;
923  int num_inputs, num_outputs, num_pats, i;
924  EST_Litem *pi, *po;
925 
926  if (filename == "-")
927  outf = &cout;
928  else
929  outf = new ofstream(filename);
930 
931  if (!(*outf))
932  return write_fail;
933 
934  num_pats = 0;
935  for (pi = inpat.head(); pi ; pi = pi->next())
936  num_pats += inpat(pi).num_frames();
937 
938  *outf << "SNNS pattern definition file V3.2\n";
939 
940  time_t thetime = time(0);
941  char *date = ctime(&thetime);
942 
943  *outf << date;
944  *outf << endl;
945 
946  num_inputs = inpat.first().num_channels();
947  num_outputs = outpat.first().num_channels();
948 
949  *outf << "No. of patterns : " << num_pats << endl;
950  *outf << "No. of input units : "<< num_inputs << endl;
951  *outf << "No. of output units : "<< num_outputs << endl;
952  *outf << endl << endl;
953 
954  for (pi = inpat.head(), po = outpat.head(); pi ;
955  pi = pi->next(), po = po->next())
956  {
957  if (inpat(pi).num_frames() != outpat(pi).num_frames())
958  {
959  cerr << "Error: Input pattern has " << inpat(pi).num_frames()
960  << " output pattern has " << outpat(pi).num_frames() << endl;
961  if (outf != &cout)
962  delete outf;
963  return misc_write_error;
964  }
965  for (i = 0; i < inpat(pi).num_frames(); ++i)
966  {
967  int j;
968  *outf << "#Input pattern " << (i + 1) << ":\n";
969  for (j = 0; j < inpat(pi).num_channels(); ++j)
970  *outf << inpat(pi).a(i, j) << " ";
971  *outf << endl;
972  *outf << "#Output pattern " << (i + 1) << ":\n";
973  for (j = 0; j < outpat(po).num_channels(); ++j)
974  *outf << outpat(po).a(i, j) << " ";
975  *outf << endl;
976  }
977  }
978  if (outf != &cout)
979  delete outf;
980 
981  return write_ok;
982 }
983 
984 /*
985  EST_write_status EST_TrackFile::save_snns_pat(const EST_String filename,
986  EST_TrackList &trlist)
987  {
988  ostream *outf;
989  int num_inputs, num_outputs, i;
990  EST_Litem *p;
991 
992  if (filename == "-")
993  outf = &cout;
994  else
995  outf = new ofstream(filename);
996 
997  if (!(*outf))
998  return write_fail;
999 
1000  *outf << "SNNS pattern definition file V3.2\n";
1001 
1002  char *date;
1003  date = ctime(clock());
1004 
1005  *cout << date << endl;
1006 
1007  *cout << endl << endl;
1008 
1009  num_inputs = tr.first.num_channels();
1010  num_outputs = tr.first.num_channels();
1011 
1012  *cout << "No. of patterns : " << tr.size() << endl;
1013  *cout << "No. of input units : "<< num_inputs << endl;
1014  *cout << "No. of output units : "<< num_outputs << endl;
1015 
1016  for (i = 0, p = trlist.head(); p ; p = p->next(), ++i)
1017  {
1018  *outf << "#Input pattern " << i << ":\n";
1019  for (int j = 0; j < num_inputs; ++j)
1020  *outf << << trlist(p)._name(j) << "\"\n";
1021  for (int i = 0; i < tr.num_frames(); ++i)
1022  if (tr.val(i))
1023  *outf << tr.t(i) << "\t" << tr.a(i, j) << endl;
1024  else
1025  *outf << "move ";
1026  }
1027  if (outf != &cout)
1028  delete outf;
1029 
1030  return write_ok;
1031  }
1032  */
1033 
1034 EST_write_status EST_TrackFile::save_xmg(const EST_String filename, EST_Track tr)
1035 {
1036  ostream *outf;
1037  int i, j;
1038  // float min, max;
1039  int sr = 16000; // REORG - fixed sample rate until xmg is fixed
1040 
1041  // this takes care of rescaling
1042  tr.change_type(0.0, TRUE);
1043 
1044  if (filename == "-")
1045  outf = &cout;
1046  else
1047  outf = new ofstream(filename);
1048 
1049  if (!(*outf))
1050  return write_fail;
1051 
1052  outf->precision(5);
1053  outf->setf(ios::fixed, ios::floatfield);
1054  outf->width(8);
1055 
1056 /* min = max = tr.a(0);
1057  for (i = 0; i < tr.num_frames(); ++i)
1058  {
1059  if (tr.a(i) > max) max = tr.a(i);
1060  if (tr.a(i) < min) min = tr.a(i);
1061  }
1062 */
1063  *outf << "XAO1\n\n"; // xmg header identifier.
1064  *outf << "LineType segments \n";
1065  *outf << "LineStyle solid \n";
1066  *outf << "LineWidth 0 \n";
1067  *outf << "Freq " << sr / 1000 << endl; // a REAL pain!
1068  *outf << "Format Binary \n";
1069  // *outf << "YMin " << ((tr.amin != 0.0) ? tr.amin : min) << endl;
1070  // *outf << "YMax " << ((tr.amax != 0.0) ? tr.amax : max) << endl;
1071  /* if (tr.color != "")
1072  *outf << "LineColor " << tr.color << endl;
1073  */
1074  *outf << char(12) << "\n"; // control L character
1075 
1076  // rm_excess_breaks();
1077  // rm_trailing_breaks();
1078  for (i = 0; i < tr.num_frames(); ++i)
1079  if (tr.val(i))
1080  {
1081  *outf << tr.ms_t(i) << "\t";
1082  for (j = 0; j < tr.num_channels(); ++j)
1083  *outf <<tr.a(i, j) << " ";
1084  *outf << endl;
1085  }
1086  else
1087  *outf << "=\n";
1088  if (outf != &cout)
1089  delete outf;
1090 
1091  return write_ok;
1092 }
1093 
1094 static EST_write_status save_htk_as(const EST_String filename,
1095  EST_Track &orig,
1096  int use_type)
1097 {
1098  // file format is a 12 byte header
1099  // followed by data
1100 
1101  // the data is generally floats, except for DISCRETE
1102  // where it is 2 byte ints
1103 
1104  float s;
1105 
1106  EST_Track track;
1107  int type;
1108  int file_num_channels = orig.num_channels();
1109 
1110  if (orig.f_String("contour_type","none") == "ct_lpc")
1111  type = track_to_htk_lpc(orig, track);
1112  else
1113  {
1114  track = orig;
1115  type = use_type;
1116  }
1117 
1118  if (track.equal_space() != TRUE)
1119  {
1120  track.change_type(0.0, FALSE);
1121  s = rint((HTK_UNITS_PER_SECOND * EST_Track::default_frame_shift/1000.0)/10.0) * 10.0;
1122  type |= HTK_EST_PS;
1123  file_num_channels += 1;
1124  }
1125  else
1126  {
1127  track.change_type(0.0, FALSE);
1128  s = rint((HTK_UNITS_PER_SECOND * track.shift())/10.0) * 10.0;
1129  }
1130 
1131  // hkt files need to be big_endian irrespective of hardware. The
1132  // code here was obviously only ever ran on a Sun. I've tried to
1133  // fix this and it seems to work with floats, don't have data to
1134  // check with shorts though. (Rob, March 2004)
1135 
1136  struct htk_header header;
1137 
1138  header.num_samps = (EST_BIG_ENDIAN ? track.num_frames()
1139  : SWAPINT(track.num_frames()));
1140 
1141 
1142  header.samp_period = (EST_BIG_ENDIAN ? (long) s : SWAPINT((long) s));
1143  if(use_type == HTK_DISCRETE)
1144  header.samp_size = (EST_BIG_ENDIAN ? sizeof(short) :
1145  SWAPSHORT(sizeof(short)));
1146  else
1147  header.samp_size = (EST_BIG_ENDIAN ? (sizeof(float) * file_num_channels) :
1148  SWAPSHORT((sizeof(float) * file_num_channels)));
1149 
1150  header.samp_type = EST_BIG_ENDIAN ? type : SWAPSHORT(type);
1151 
1152  int i, j;
1153  FILE *outf;
1154  if (filename == "-")
1155  outf = stdout;
1156  else if ((outf = fopen(filename,"wb")) == NULL)
1157  {
1158  cerr << "save_htk: cannot open file \"" << filename <<
1159  "\" for writing." << endl;
1160  return misc_write_error;
1161  }
1162 
1163  // write the header
1164  fwrite((char*)&(header.num_samps), 1, sizeof(header.num_samps), outf);
1165  fwrite((char*)&(header.samp_period), 1, sizeof(header.samp_period), outf);
1166  fwrite((char*)&(header.samp_size), 1, sizeof(header.samp_size), outf);
1167  fwrite((char*)&(header.samp_type), 1, sizeof(header.samp_type), outf);
1168 
1169  // write the data
1170  if(use_type == HTK_DISCRETE)
1171  {
1172  if(track.num_channels() < 1)
1173  {
1174  cerr << "No data to write as HTK_DISCRETE !" << endl;
1175  }
1176  else
1177  {
1178  if(track.num_channels() > 1)
1179  {
1180  cerr << "Warning: multiple channel track being written" << endl;
1181  cerr << " as discrete will only save channel 0 !" << endl;
1182  }
1183  for (i = 0; i < track.num_frames(); ++i)
1184  {
1185  short tempshort = (EST_BIG_ENDIAN ? (short)(track.a(i, 0)) :
1186  SWAPSHORT((short)(track.a(i, 0)))) ;
1187  fwrite((unsigned char*) &tempshort, 1, sizeof(short), outf);
1188  }
1189  }
1190  }
1191  else // not HTK_DISCRETE
1192  for (i = 0; i < track.num_frames(); ++i)
1193  {
1194  if ((type & HTK_EST_PS) != 0)
1195  {
1196  if(!EST_BIG_ENDIAN)
1197  swapfloat(&(track.t(i)));
1198  fwrite((unsigned char*) &(track.t(i)), 1, sizeof(float), outf);
1199  }
1200  for (j = 0; j < track.num_channels(); ++j)
1201  {
1202  if(!EST_BIG_ENDIAN)
1203  swapfloat(&(track.a(i,j)));
1204  fwrite((unsigned char*) &(track.a(i, j)), 1, sizeof(float), outf);
1205  }
1206  }
1207 
1208  if (outf != stdout)
1209  fclose(outf);
1210 
1211  return write_ok;
1212 }
1213 
1214 static int htk_sane_header(htk_header *htk)
1215 {
1216  return htk->num_samps > 0 &&
1217  htk->samp_period > 0 &&
1218  htk->samp_size > 0 &&
1219  htk->samp_size < (short)(UNREASONABLE_FRAME_SIZE * sizeof(float));
1220 }
1221 
1222 static int htk_swapped_header(htk_header *header)
1223 {
1224  // Tries to guess if the header is swapped. If so it
1225  // swaps the contents and returns TRUE, other returns FALSE
1226  // HTK doesn't have a magic number so we need heuristics to
1227  // guess when its byte swapped
1228 
1229  if (htk_sane_header(header))
1230  return 0;
1231 
1232  header->num_samps = SWAPINT(header->num_samps);
1233  header->samp_period = SWAPINT(header->samp_period);
1234  header->samp_size = SWAPSHORT(header->samp_size);
1235  header->samp_type = SWAPSHORT(header->samp_type);
1236 
1237  if (htk_sane_header(header))
1238  return 1;
1239 
1240  return -1;
1241 
1242 }
1243 
1244 EST_write_status EST_TrackFile::save_htk(const EST_String filename, EST_Track tmp)
1245 {
1246  return save_htk_as(filename, tmp, HTK_FBANK);
1247 }
1248 
1249 EST_write_status EST_TrackFile::save_htk_fbank(const EST_String filename, EST_Track tmp)
1250 {
1251  return save_htk_as(filename, tmp, HTK_FBANK);
1252 }
1253 
1254 EST_write_status EST_TrackFile::save_htk_mfcc(const EST_String filename, EST_Track tmp)
1255 {
1256  return save_htk_as(filename, tmp, HTK_MFCC);
1257 }
1258 
1259 EST_write_status EST_TrackFile::save_htk_mfcc_e(const EST_String filename, EST_Track tmp)
1260 {
1261  return save_htk_as(filename, tmp, HTK_MFCC | HTK_ENERGY);
1262 }
1263 
1264 EST_write_status EST_TrackFile::save_htk_user(const EST_String filename, EST_Track tmp)
1265 {
1266  return save_htk_as(filename, tmp, HTK_USER);
1267 }
1268 
1269 EST_write_status EST_TrackFile::save_htk_discrete(const EST_String filename, EST_Track tmp)
1270 {
1271  return save_htk_as(filename, tmp, HTK_DISCRETE);
1272 }
1273 
1274 
1275 static EST_read_status load_ema_internal(const EST_String filename, EST_Track &tmp, float ishift, float startt, bool swap)
1276 {
1277  (void)ishift;
1278  (void)startt;
1279 
1280  int i, j, k, nframes, new_order;
1281  EST_TVector<short> file_data;
1282  int sample_width, data_length;
1283  float shift;
1284  FILE *fp;
1285 
1286  if ((fp = fopen(filename, "rb")) == NULL)
1287  {
1288  cerr << "EST_Track load: couldn't open EST_Track input file" << endl;
1289  return misc_read_error;
1290  }
1291 
1292  fseek(fp, 0, SEEK_END);
1293  sample_width = 2;
1294  data_length = ftell(fp)/sample_width;
1295  new_order = 10;
1296  nframes = data_length /new_order;
1297  shift = 0.002;
1298 
1299  cout << "d length: " << data_length << " nfr " << nframes << endl;
1300 
1301  tmp.resize(nframes, new_order);
1302  tmp.fill_time(shift);
1303  tmp.set_equal_space(TRUE);
1304 
1305  file_data.resize(data_length);
1306 
1307  fseek(fp, 0, SEEK_SET);
1308 
1309  if ((int)fread(file_data.memory(), sample_width, data_length, fp) != data_length)
1310  {
1311  fclose(fp);
1312  return misc_read_error;
1313  }
1314 
1315  if (swap)
1316  swap_bytes_short(file_data.memory(), data_length);
1317 
1318  for (i = k = 0; i < nframes; ++i)
1319  for (j = 0; j < new_order; ++j, ++k)
1320  tmp.a(i, j) = (float)file_data.a_no_check(k);
1321 
1322  // name the fields
1323  EST_String t;
1324  // the first 'order' fields are always called c1,c2...
1325  // AWB bug -- the following corrupts memory
1326  /* for (i = 0; i < order; i++)
1327  {
1328  EST_String t2;
1329  t2 = EST_String("c") + itoString(i+1);
1330  tmp.set_field_name(t2, i);
1331  }
1332  i=order;
1333  */
1334  cout << "here \n";
1335 
1336  tmp.set_name(filename);
1337  tmp.set_file_type(tff_ema);
1338 
1339  fclose(fp);
1340  return format_ok;
1341 }
1342 
1343 EST_read_status EST_TrackFile::load_ema(const EST_String filename, EST_Track &tmp, float ishift, float startt)
1344 {
1345  return load_ema_internal(filename, tmp, ishift, startt, FALSE);
1346 }
1347 
1348 
1349 EST_read_status EST_TrackFile::load_ema_swapped(const EST_String filename, EST_Track &tmp, float ishift, float startt)
1350 {
1351  return load_ema_internal(filename, tmp, ishift, startt, TRUE);
1352 }
1353 
1354 #if 0
1355 EST_read_status EST_TrackFile::load_NIST(const EST_String filename, EST_Track &tmp, float ishift, float startt)
1356 {
1357  (void)ishift; // what does this do ?
1358  (void)startt;
1359 
1360  char header[NIST_HDR_SIZE];
1361  int samps,sample_width,data_length,actual_bo;
1362  unsigned char *file_data;
1363  enum EST_sample_type_t actual_sample_type;
1364  char *byte_order, *sample_coding;
1365  int n,i,j,k;
1366  int current_pos;
1367  int offset=0;
1368 
1369  EST_TokenStream ts;
1370  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
1371  {
1372  cerr << "Can't open track file " << filename << endl;
1373  return misc_read_error;
1374  }
1375 
1376  current_pos = ts.tell();
1377  if (ts.fread(header,NIST_HDR_SIZE,1) != 1)
1378  return misc_read_error;
1379 
1380  if (strncmp(header,NIST_SIG,sizeof(NIST_SIG)) != 0)
1381  return wrong_format;
1382 
1383  samps = nist_get_param_int(header,"sample_count",-1);
1384  int num_channels = nist_get_param_int(header,"channel_count",1);
1385  sample_width = nist_get_param_int(header,"sample_n_bytes",2);
1386  int sample_rate =
1387  nist_get_param_int(header,"sample_rate",def_load_sample_rate);
1388  byte_order = nist_get_param_str(header,"sample_byte_format",
1389  (EST_BIG_ENDIAN ? "10" : "01"));
1390  sample_coding = nist_get_param_str(header,"sample_coding","pcm");
1391 
1392  data_length = (samps - offset)*num_channels;
1393  file_data = walloc(unsigned char,sample_width * data_length);
1394 
1395  ts.seek(current_pos+NIST_HDR_SIZE+(sample_width*offset*(num_channels)));
1396 
1397  n = ts.fread(file_data,sample_width,data_length);
1398 
1399  if ((n < 1) && (n != data_length))
1400  {
1401  wfree(file_data);
1402  wfree(sample_coding);
1403  wfree(byte_order);
1404  return misc_read_error;
1405  }
1406  else if ((n < data_length) && (data_length/num_channels == n))
1407  {
1408  fprintf(stderr,"TRACK read: nist header is (probably) non-standard\n");
1409  fprintf(stderr,"TRACK read: assuming different num_channel interpretation\n");
1410  data_length = n; /* wrongly headered file */
1411  }
1412  else if (n < data_length)
1413  {
1414  fprintf(stderr,"TRACK read: short file %s\n",
1415  (const char *)ts.filename());
1416  fprintf(stderr,"WAVE read: at %d got %d instead of %d samples\n",
1417  offset,n,data_length);
1418  data_length = n;
1419  }
1420 
1421  actual_sample_type = nist_to_sample_type(sample_coding);
1422  actual_bo = ((strcmp(byte_order,"10") == 0) ? bo_big : bo_little);
1423 
1424  short *data;
1425  data = convert_raw_data(file_data,data_length,
1426  actual_sample_type,actual_bo);
1427 
1428  // copy into the Track
1429  int num_samples = data_length/num_channels;
1430  tmp.resize(num_samples, num_channels);
1431  tmp.set_equal_space(TRUE);
1432  tmp.fill_time(1/(float)sample_rate);
1433 
1434  cerr << "shift " << 1/(float)sample_rate << endl;
1435 
1436  k=0;
1437  for (i=0; i<num_samples; i++)
1438  {
1439  for (j = 0; j < num_channels; ++j)
1440  tmp.a(i, j) = data[k++]; // channels are simply interleaved
1441  tmp.set_value(i);
1442  }
1443  for (j = 0; j < num_channels; ++j)
1444  tmp.set_channel_name("name", j);
1445 
1446 
1447 
1448  /*
1449  *sample_type = st_short;
1450  *bo = EST_NATIVE_BO;
1451  *word_size = 2;
1452  */
1453 
1454  //cerr << "NIST OK" << endl;
1455 
1456  return format_ok;
1457 }
1458 
1459 EST_write_status EST_TrackFile::save_NIST(const EST_String filename, EST_Track tr)
1460 {
1461  FILE *fd;
1462  int i,j,k=0;
1463  if (filename == "-")
1464  fd = stdout;
1465  else if ((fd = fopen(filename,"wb")) == NULL)
1466  return write_fail;
1467 
1468  // create header
1469  char header[NIST_HDR_SIZE], p[1024];;
1470  const char *t;
1471 
1472  memset(header,0,1024);
1473  strcat(header, NIST_SIG);
1474  sprintf(p, "channel_count -i %d\n", tr.num_channels());
1475  strcat(header, p);
1476  sprintf(p, "sample_count -i %d\n", tr.num_frames());
1477  strcat(header, p);
1478  int sr = (int)(rint(1/(float)tr.shift()));
1479  sprintf(p, "sample_rate -i %d\n", sr);
1480  strcat(header, p);
1481  t = sample_type_to_nist(st_short);
1482  sprintf(p, "sample_coding -s%d %s\n", (signed)strlen(t), t);
1483  strcat(header, p);
1484 
1485  strcat(header, NIST_END_SIG);
1486  /*makes it nice to read */
1487  strcat(header, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
1488 
1489  // write header
1490  if (fwrite(&header, 1024, 1, fd) != 1)
1491  return misc_write_error;
1492 
1493  // data
1494  short data[tr.num_frames() * tr.num_channels()];
1495 
1496 
1497  for (i = 0; i < tr.num_frames(); ++i)
1498  // restricted to shorts at this time
1499  for (j = 0; j < tr.num_channels(); ++j)
1500  data[k++] = (short)(tr.a_no_check(i, j));
1501 
1502  // byte swapping of output not supported - only write native bo
1503  int bo = str_to_bo("native");
1504  return save_raw_data(fd,data,0,tr.num_frames(),tr.num_channels(),
1505  st_short,bo);
1506 
1507  if (fd != stdout)
1508  fclose(fd);
1509  return write_ok;
1510 
1511 }
1512 #endif
1513 
1514 
1515 EST_read_status EST_TrackFile::load_htk(const EST_String filename, EST_Track &tmp, float ishift, float startt)
1516 {
1517  (void)ishift;
1518 
1519  // num_values is total number of fields in file
1520  // num_channels is number of fields in resultant track
1521  // order is order of LPC etc. analysis
1522  // e.g. if order is 12 and we have energy and delta then num_values = (12 + 1) * 2 = 26
1523 
1524  int i,j, order, new_frames, num_values, num_channels;
1525 
1526  EST_String pname;
1527  int swap;
1528  int time_included;
1529 
1530  FILE *fp;
1531  struct htk_header header;
1532  int header_sz = sizeof(header);
1533 
1534  // numbers A and B for decompression of generally compressed files
1535  float *compressA=NULL, compressA_Buffer[REASONABLE_FRAME_SIZE];
1536  float *compressB=NULL, compressB_Buffer[REASONABLE_FRAME_SIZE];
1537  bool fileIsCompressed=false;
1538 
1539  unsigned short samp_type, base_samp_type;
1540 
1541  if ((fp = fopen(filename, "rb")) == NULL){
1542  cerr << "EST_Track load: couldn't open EST_Track input file" << endl;
1543  return misc_read_error;
1544  }
1545 
1546  // try and read the header
1547  if (fread(&header, header_sz, 1, fp) != 1){
1548  fclose(fp);
1549  return wrong_format;
1550  }
1551 
1552  swap = htk_swapped_header(&header); // this is regrettable
1553 
1554  if( swap<0 ){
1555  fclose(fp);
1556  return read_format_error;
1557  }
1558 
1559  samp_type = header.samp_type;
1560  base_samp_type = samp_type & HTK_MASK;
1561 
1562  time_included = (samp_type & HTK_EST_PS) != 0;
1563 
1564  switch(base_samp_type){
1565  case HTK_WAVE:
1566  cerr << "Can't read HTK WAVEFORM format file into track" << endl;
1567  return misc_read_error;
1568  break;
1569 
1570  case HTK_LPC:
1571  pname = "ct_lpc";
1572  break;
1573 
1574  case HTK_LPCREFC:
1575  case HTK_IREFC:
1576  EST_warning( "reading HTK_IREFC and HTK_LPREC parameter types is unsupported" );
1577  fclose( fp );
1578  return read_format_error;
1579  break;
1580 
1581  case HTK_LPCCEP:
1582  pname = "ct_cepstrum";
1583  break;
1584 
1585  case HTK_LPDELCEP:
1586  // equivalent to HTK_LPCCEP + DELTA
1587  base_samp_type = HTK_LPCCEP;
1588  samp_type = HTK_LPCCEP | HTK_DELTA; // set delta bit
1589  pname = "ct_cepstrum";
1590  break;
1591 
1592  case HTK_MFCC:
1593  pname = "ct_other";
1594  break;
1595 
1596  case HTK_FBANK:
1597  case HTK_USER:
1598  pname = "ct_other";
1599  break;
1600 
1601  case HTK_DISCRETE:
1602  cerr << "Can't read HTK DISCRETE format file into track" << endl;
1603  return misc_read_error;
1604  break;
1605 
1606  case HTK_MELSPEC:
1607  pname = "ct_other";
1608  break;
1609 
1610  default:
1611  fclose(fp);
1612  return wrong_format;
1613  break;
1614  }
1615 
1616  // if we get this far we have decided this is a HTK format file
1617 
1618  // handle compressed/uncompressed files differently
1619  if( header.samp_type & HTK_COMP ){
1620 
1621  fileIsCompressed = true;
1622 
1623  num_channels = num_values = header.samp_size / sizeof(short int);
1624 
1625  // get compression numbers A and B
1626  if (num_channels > REASONABLE_FRAME_SIZE){
1627  compressA = new float[num_values];
1628  compressB = new float[num_values];
1629  }
1630  else{
1631  compressA = compressA_Buffer;
1632  compressB = compressB_Buffer;
1633  }
1634 
1635  if( (fread( compressA, sizeof(float), num_values, fp )) != static_cast<size_t>(num_values) ){
1636  fclose( fp );
1637  return read_format_error;
1638  }
1639 
1640  if( (fread( compressB, sizeof(float), num_values, fp )) != static_cast<size_t>(num_values) ){
1641  fclose( fp );
1642  return read_format_error;
1643  }
1644 
1645  if (swap){
1646  swap_bytes_float( compressA, num_values );
1647  swap_bytes_float( compressB, num_values );
1648  }
1649 
1650  // subtract extra frames to account for the two vectors of floats
1651  // used for decompression.
1652  new_frames = header.num_samps - (2*(sizeof(float)-sizeof(short int)));
1653  }
1654  else{
1655  num_channels = num_values = header.samp_size / sizeof(float);
1656  new_frames = header.num_samps;
1657  }
1658 
1659  if (num_values > UNREASONABLE_FRAME_SIZE){
1660  fclose(fp);
1661  return read_format_error;
1662  }
1663 
1664  if (time_included)
1665  num_channels -= 1;
1666 
1667  float shift = ((float)header.samp_period/ (float)HTK_UNITS_PER_SECOND);
1668 
1669  tmp.resize(new_frames, num_channels);
1670 
1671  if ((startt > 0) && (startt < NEARLY_ZERO ))
1672  EST_warning( "setting htk file start to %f", startt );
1673 
1674  tmp.fill_time(shift, startt);
1675 
1676  tmp.set_equal_space(!time_included);
1677 
1678  // check length of file is as expected from header info
1679  long dataBeginPosition = ftell(fp);
1680  if( dataBeginPosition == -1 ){
1681  fclose(fp);
1682  return wrong_format;
1683  }
1684 
1685  if (fseek(fp,0,SEEK_END)){
1686  fclose(fp);
1687  return wrong_format;
1688  }
1689 
1690  long file_length;
1691  if ((file_length = ftell(fp)) == -1){
1692  fclose(fp);
1693  return wrong_format;
1694  }
1695 
1696  long expected_vals;
1697  if( fileIsCompressed ){
1698  expected_vals = (file_length-dataBeginPosition) / sizeof(short int);
1699 
1700  if( header.samp_type & HTK_CRC )
1701  expected_vals -= 1; // just ignore the appended cyclic redundancy checksum
1702  }
1703  else
1704  expected_vals = (file_length-dataBeginPosition) / sizeof(float);
1705 
1706  /*
1707  printf( "%d %d %d %d %d %d\n",
1708  expected_vals, file_length, dataBeginPosition, sizeof(float), num_values, new_frames );
1709  */
1710 
1711  if( expected_vals != (num_values * new_frames) ){
1712  // it probably isn't HTK format after all
1713  fclose(fp);
1714  return wrong_format;
1715  }
1716 
1717  // work out the order of the analysis
1718  // Reorg -- surely you can't increase order
1719  order = num_channels;
1720  if( samp_type & HTK_NO_E )
1721  order++;
1722 
1723  if( samp_type & HTK_AC )
1724  order /= 3;
1725  else if( samp_type & HTK_DELTA )
1726  order /= 2;
1727 
1728  if( samp_type & HTK_ENERGY )
1729  order--;
1730 
1731  // go to start of data
1732  if( fseek(fp, dataBeginPosition, SEEK_SET) == -1 ){
1733  cerr << "Couldn't position htk file at start of data" << endl;
1734  fclose(fp);
1735  return misc_read_error;
1736  }
1737 
1738  if( fileIsCompressed ){
1739  short int *frame, frame_buffer[REASONABLE_FRAME_SIZE];
1740  if( num_values > REASONABLE_FRAME_SIZE )
1741  frame = new short int[num_values];
1742  else
1743  frame = frame_buffer;
1744 
1745  int first_channel = time_included?1:0;
1746 
1747  for( i=0; i<new_frames; i++ ){
1748  if( fread( frame, sizeof(short int), num_values, fp ) != (size_t) num_values ){
1749  cerr << "Could not read data from htk track file" << endl;
1750  fclose(fp);
1751 
1752  if( frame != frame_buffer )
1753  delete [] frame;
1754  if( compressA != compressA_Buffer )
1755  delete [] compressA;
1756  if( compressB != compressB_Buffer )
1757  delete [] compressB;
1758 
1759  return misc_read_error;
1760  }
1761 
1762  if( swap )
1763  swap_bytes_short( frame, num_values );
1764 
1765  if( time_included )
1766  tmp.t(i) = ((float)frame[0]+compressB[0])/compressA[0];
1767 
1768  for( j=0; j<num_channels; ++j ){
1769  int index = j+first_channel;
1770  tmp.a(i,j) = ((float)frame[index]+compressB[index])/compressA[index];
1771  }
1772 
1773  tmp.set_value(i);
1774  }
1775 
1776  if( frame != frame_buffer )
1777  delete [] frame;
1778  if( compressA != compressA_Buffer )
1779  delete [] compressA;
1780  if( compressB != compressB_Buffer )
1781  delete [] compressB;
1782  }
1783  else{
1784  float *frame, frame_buffer[REASONABLE_FRAME_SIZE];
1785 
1786  if (num_values > REASONABLE_FRAME_SIZE)
1787  frame = new float[num_values];
1788  else
1789  frame = frame_buffer;
1790 
1791  int first_channel = time_included?1:0;
1792  for( i=0; i<new_frames; i++ ){
1793  if( fread( frame, sizeof(float), num_values, fp ) != (size_t) num_values ){
1794  cerr << "Could not read data from htk track file" << endl;
1795  fclose(fp);
1796  if (frame != frame_buffer)
1797  delete [] frame;
1798  return misc_read_error;
1799  }
1800  if( swap )
1801  swap_bytes_float( frame, num_values );
1802 
1803  if( time_included )
1804  tmp.t(i) = frame[0];
1805 
1806  for( j=0; j<num_channels; ++j )
1807  tmp.a(i, j) = frame[j+first_channel];
1808 
1809  tmp.set_value(i);
1810  }
1811 
1812  if( frame != frame_buffer )
1813  delete [] frame;
1814  }
1815 
1816  // name the fields
1817  EST_String t;
1818  // the first 'order' fields are always called c1,c2...
1819  // AWB bug -- the following corrupts memory
1820  for (i=0;i<order;i++)
1821  {
1822  EST_String t2;
1823  t2 = EST_String("c") + itoString(i+1);
1824  tmp.set_channel_name(t2, i);
1825  }
1826  i=order;
1827 
1828  // energy present and not suppressed
1829  if ( (samp_type & HTK_ENERGY) && !(samp_type & HTK_NO_E) )
1830  tmp.set_channel_name("E", i++);
1831 
1832  // delta coeffs ?
1833  if (samp_type & HTK_DELTA){
1834  for (j = 0; j < order; j++){
1835  t = EST_String("c") + itoString(j+1) + "_d";
1836  tmp.set_channel_name(t, i++);
1837  }
1838 
1839  // energy ?
1840  if (samp_type & HTK_ENERGY)
1841  tmp.set_channel_name("E_d", i++);
1842  }
1843 
1844  // 'acceleration' coeffs ?
1845  if (samp_type & HTK_AC){
1846  for(j=0;j<order;j++){
1847  t = EST_String("ac")+ itoString(j+1)+ "_d_d";
1848  tmp.set_channel_name(t, i++);
1849  }
1850  // energy ?
1851  if (samp_type & HTK_ENERGY)
1852  tmp.set_channel_name("E_d_d", i++);
1853  }
1854 
1855  // sanity check
1856  if (i != num_channels){
1857  cerr << "Something went horribly wrong - wanted " << num_values
1858  << " channels in track but got " << i << endl;
1859  fclose(fp);
1860  return wrong_format;
1861  }
1862  tmp.f_set("contour_type",pname);
1863  tmp.set_name(filename);
1864  tmp.set_file_type(tff_htk);
1865  fclose(fp);
1866  return format_ok;
1867 }
1868 
1869 /************************************************************************/
1870 /* */
1871 /* Convert single f0 channel tracks into arbitrarily chosen esps FEA */
1872 /* subtype, reputedly to make waves happy. This is evil beyond all */
1873 /* understanding. */
1874 /* */
1875 /************************************************************************/
1876 
1877 // format of the desired track.
1878 static struct EST_TrackMap::ChannelMappingElement espsf0_mapping[] =
1879 {
1880 { channel_f0, 0 },
1881 { channel_voiced, 1 },
1882 { channel_power, 2},
1883 { channel_peak, 3},
1884 { channel_unknown, 0}
1885 };
1886 static EST_TrackMap ESPSF0TrackMap(espsf0_mapping);
1887 
1888 // It seems that the vital thing is to call the track "F0", and so
1889 // we only need 1 channel instead of the normal 5. This saves *lots* of
1890 // space. For the time being we use 2 channels as the prob_voicnug filed is
1891 // used by our input routine.
1892 
1893 int track_to_espsf0(EST_Track &track, EST_Track &f0_track)
1894 {
1895  f0_track.resize(track.num_frames(), 2);
1896 
1897  f0_track.assign_map(ESPSF0TrackMap);
1898 
1899  // k1 is ratio of the first two cross-correlation values
1900  // f0_track.set_channel_name("k1", 4);
1901 
1902  // copy data. Remaining channels zeroed by resize. This is of course stupid
1903  // as if k1 iz zero mathematics is in deep problems.
1904  for (int i = 0; i < track.num_frames(); ++i)
1905  {
1906  f0_track.a(i, channel_voiced) = track.track_break(i) ? 0.1 : 1.2;
1907  f0_track.a(i, channel_f0) = track.track_break(i) ? 0.0: track.a(i,0);
1908  }
1909 
1910  f0_track.set_file_type(tff_esps);
1911  f0_track.fill_time(track.shift());
1912  track.set_name(track.name());
1913 
1914  /* f0_track.resize(track.num_frames(), 5);
1915 
1916  f0_track.assign_map(ESPSF0TrackMap);
1917 
1918  // k1 is ratio of the first two cross-correlation values
1919  f0_track.set_channel_name("k1", 4);
1920 
1921  // copy data. Remaining channels zeroed by resize. This is of course stupid
1922  // as if k1 iz zero mathematics is in deep problems.
1923  for (int i = 0; i < track.num_frames(); ++i)
1924  {
1925  f0_track.a(i, channel_voiced) = track.track_break(i) ? 0.1 : 1.2;
1926  f0_track.a(i, channel_f0) = track.a(i,0);
1927  }
1928 
1929  f0_track.set_file_type("esps");
1930  f0_track.fill_time(track.shift());
1931  track.set_name(track.name());
1932  */
1933 
1934  return 0;
1935 }
1936 
1937 int espsf0_to_track(EST_Track &fz)
1938 {
1939  int f, p, i;
1940  f = p = -1;
1941 
1942  // check to see if prob of voicing channel exists
1943  for (i = 0; i < fz.num_channels(); ++i)
1944  {
1945  if (fz.channel_name(i) == "prob_voice")
1946  p = i;
1947  }
1948  for (i = 0; i < fz.num_channels(); ++i)
1949  {
1950  if (fz.channel_name(i) == "F0")
1951  f = i;
1952  }
1953 
1954  for (i = 0; i < fz.num_frames(); ++i)
1955  {
1956  if (p == -1) // if f0 val is < 1 make this a break
1957  {
1958  if (fz.a(i, f) < 1.0)
1959  fz.set_break(i);
1960  else
1961  fz.set_value(i);
1962  }
1963  else // use prob voicing
1964  {
1965  if (fz.a(i, p) < 0.5)
1966  {
1967  fz.a(i, f) = 0.0;
1968  fz.set_break(i);
1969  }
1970  else
1971  fz.set_value(i);
1972  }
1973  }
1974 
1975  return 0;
1976 }
1977 
1978 int track_to_htk_lpc(EST_Track &track, EST_Track &lpc)
1979 {
1980  int type = HTK_LPC;
1981  int ncoefs, nchannels;
1982 
1983  if (track.has_channel(channel_lpc_N))
1984  ncoefs = track.channel_position(channel_lpc_N) - track.channel_position(channel_lpc_0)+1;
1985  else
1986  ncoefs = track.num_channels()-track.channel_position(channel_lpc_0);
1987 
1988  nchannels = ncoefs;
1989 
1990  if (track.has_channel(channel_power))
1991  {
1992  nchannels++;
1993  type |= HTK_ENERGY;
1994  }
1995 
1996  lpc.resize(track.num_frames(), nchannels);
1997  lpc.set_equal_space(track.equal_space());
1998  lpc.set_single_break(track.single_break());
1999  lpc.set_single_break(track.single_break());
2000 
2001  for(int i = 0; i< track.num_frames(); i++)
2002  for (int c = 0; c < ncoefs; c++)
2003  {
2004  lpc.a(i, c) = track.a(i, channel_lpc_0, c);
2005  lpc.t(i) = track.t(i);
2006  }
2007 
2008 
2009  if (track.has_channel(channel_power))
2010  {
2011  for(int ii = 0; ii< track.num_frames(); ii++)
2012  lpc.a(ii, ncoefs) = track.a(ii, channel_power);
2013  }
2014 
2015  return type;
2016 
2017 }
2018 
2019 EST_write_status save_ind_TrackList(EST_TrackList &tlist, EST_String &otype)
2020 {
2021  for (EST_Litem *p = tlist.head(); p ; p = p->next())
2022  tlist(p).save(tlist(p).name(), otype);
2023 
2024  return write_ok;
2025 }
2026 
2027 EST_read_status read_TrackList(EST_TrackList &tlist, EST_StrList &files,
2028  EST_Option &al)
2029 {
2030  EST_Track s;
2031  EST_Litem *p, *plp;
2032 
2033  for (p = files.head(); p; p = p->next())
2034  {
2035  tlist.append(s);
2036  plp = tlist.tail();
2037  if (read_track(tlist(plp), files(p), al) != format_ok)
2038  exit (-1);
2039 
2040  tlist(plp).set_name(files(p));
2041  }
2042 
2043  return format_ok;
2044 }
2045 
2046 int read_track(EST_Track &tr, const EST_String &in_file, EST_Option &al)
2047 {
2048 
2049  float ishift = 0;
2050  float startt = 0.0;
2051 
2052  if( al.present("-startt") )
2053  startt = al.fval( "-startt" );
2054 
2055  if (al.present("ishift"))
2056  ishift = al.fval("ishift");
2057  else if (al.present("-s"))
2058  ishift = al.fval("-s");
2059  else if (al.present("time_channel"))
2060  ishift = 1.0; // doesn't matter, will be reset by track
2061 
2062  if (al.present("-itype"))
2063  {
2064  if (tr.load(in_file, al.val("-itype", 0), ishift, startt) != format_ok)
2065  return -1;
2066  }
2067  else
2068  {
2069  if (tr.load(in_file, ishift, startt ) != format_ok)
2070  return -1;
2071  }
2072 
2073 // tr.create_map();
2074 
2075  // cout << "f0 "<< tr.has_channel(channel_f0) << ".\n";
2076 // if (al.present("time_channel") && tr.has_channel(al.sval("time_channel")))
2077 // {
2078 // cout << " time from channel " << al.sval("time_channel") << "\n";
2079 // channel_to_time(tr, al.sval("time_channel"), al.fval("time_scale"));
2080 // }
2081 
2082 
2083  // cout << tr;
2084  return 0;
2085 }
2086 
2087 
2088 EST_String EST_TrackFile::options_short(void)
2089 {
2090  EST_String s("");
2091 
2092  for(int n=0; n< EST_TrackFile::map.n() ; n++)
2093  {
2094  const char *nm = EST_TrackFile::map.name(EST_TrackFile::map.token(n));
2095 
2096  if (s != "")
2097  s += ", ";
2098 
2099  s += nm;
2100 
2101  }
2102  return s;
2103 }
2104 
2105 EST_String EST_TrackFile::options_supported(void)
2106 {
2107  EST_String s("AvailablE track file formats:\n");
2108 
2109  for(int n=0; n< EST_TrackFile::map.n() ; n++)
2110  {
2111  const char *nm = EST_TrackFile::map.name(EST_TrackFile::map.token(n));
2112  const char *d = EST_TrackFile::map.info(EST_TrackFile::map.token(n)).description;
2113 
2114  s += EST_String::cat(" ", nm, EST_String(" ")*(13-strlen(nm)), d, "\n");
2115  }
2116  return s;
2117 }
2118 
2119 // note the order here defines the order in which loads are tried.
2121 {
2122 { tff_none, { "none" },
2123 {FALSE, NULL, NULL,
2124  "unknown track file type"}},
2125 {tff_esps, { "esps" },
2126 {TRUE, EST_TrackFile::load_esps, EST_TrackFile::save_esps,
2127  "entropic sps file"}},
2128 {tff_est_ascii, { "est", "est_ascii" },
2129 {TRUE, EST_TrackFile::load_est, EST_TrackFile::save_est_ascii,
2130  "Edinburgh Speech Tools track file"}},
2131 {tff_est_binary, { "est_binary" },
2132 {TRUE, EST_TrackFile::load_est, EST_TrackFile::save_est_binary,
2133  "Edinburgh Speech Tools track file"}}
2134 ,
2135 {tff_htk, { "htk" },
2136 {TRUE, EST_TrackFile::load_htk, EST_TrackFile::save_htk,
2137  "htk file"}},
2138 //{tff_NIST, { "NIST" },
2139 //{TRUE, EST_TrackFile::load_NIST, EST_TrackFile::save_NIST,
2140 // "NIST"}},
2141 {tff_htk_fbank, { "htk_fbank" },
2142 {FALSE, EST_TrackFile::load_htk, EST_TrackFile::save_htk_fbank,
2143  "htk file (as FBANK)"}},
2144 {tff_htk_mfcc, { "htk_mfcc" },
2145 {FALSE, EST_TrackFile::load_htk, EST_TrackFile::save_htk_mfcc,
2146  "htk file (as MFCC)"}},
2147 {tff_htk_mfcc_e, { "htk_mfcc_e" },
2148 {FALSE, EST_TrackFile::load_htk, EST_TrackFile::save_htk_mfcc_e,
2149  "htk file (as MFCC_E)"}},
2150 {tff_htk_user, { "htk_user" },
2151 {FALSE, EST_TrackFile::load_htk, EST_TrackFile::save_htk_user,
2152  "htk file (as USER)"}},
2153 {tff_htk_discrete, { "htk_discrete" },
2154 {FALSE, EST_TrackFile::load_htk, EST_TrackFile::save_htk_discrete,
2155  "htk file (as DISCRETE)"}},
2156 {tff_ssff, {"ssff"},
2157 {TRUE, EST_TrackFile::load_ssff, EST_TrackFile::save_ssff,
2158  "Macquarie University's Simple Signal File Format"}},
2159 {tff_xmg, { "xmg" },
2160 {TRUE, EST_TrackFile::load_xmg, EST_TrackFile::save_xmg,
2161  "xmg file viewer"}},
2162 {tff_xgraph, { "xgraph" },
2163 {FALSE, EST_TrackFile::load_xgraph, EST_TrackFile::save_xgraph,
2164  "xgraph display program format"}},
2165 {tff_ema, { "ema" },
2166 {FALSE, EST_TrackFile::load_ema, NULL,
2167  "ema"}},
2168 {tff_ema_swapped, { "ema_swapped" },
2169 {FALSE, EST_TrackFile::load_ema_swapped, NULL,
2170  "ema, swapped"}},
2171 {tff_ascii, { "ascii" },
2172 {TRUE, EST_TrackFile::load_ascii, EST_TrackFile::save_ascii,
2173  "ascii decimal numbers"}},
2174 { tff_none, {"none"}, {FALSE, NULL, NULL, "unknown track file type"} }
2175 };
2176 
2177 EST_TNamedEnumI<EST_TrackFileType, EST_TrackFile::Info> EST_TrackFile::map(trackfile_names);
2178 
2179 static EST_TValuedEnumDefinition<EST_TrackFileType, const char *,
2180 EST_TrackFile::TS_Info> track_ts_names[] =
2181 {
2182 { tff_none, { "none" },
2183 {FALSE, NULL, NULL,
2184  "unknown track file type"}},
2185 
2186 {tff_est_ascii, {"est"},
2187 {TRUE, EST_TrackFile::load_est_ts, EST_TrackFile::save_est_ts,
2188  "Edinburgh Speech Tools track file"}},
2189 
2190 {tff_est_binary, {"est_binary"},
2191 {TRUE, EST_TrackFile::load_est_ts, EST_TrackFile::save_est_binary_ts,
2192  "Edinburgh Speech Tools track file"}},
2193 
2194 {tff_ssff, {"ssff"},
2195 {TRUE, EST_TrackFile::load_ssff_ts, EST_TrackFile::save_ssff_ts,
2196  "Macquarie University's Simple Signal File Format"}},
2197 
2198 { tff_none, { "none" },
2199 {FALSE, NULL, NULL,
2200  "unknown track file type"}}
2201 };
2202 
2204 EST_TrackFile::ts_map(track_ts_names);
2205 
2206 
2207 #if defined(INSTANTIATE_TEMPLATES)
2208 
2209 #include "../base_class/EST_TNamedEnum.cc"
2211 template class EST_TValuedEnumI<EST_TrackFileType,
2212 const char *, EST_TrackFile::Info>;
2214 template class EST_TValuedEnumI<EST_TrackFileType,
2215 const char *, EST_TrackFile::TS_Info>;
2216 
2217 #endif
2218 
void remove(const EST_String &name)
Definition: EST_Features.h:246
const EST_String S(const EST_String &path) const
Definition: EST_Features.h:157
int present(const EST_String &name) const
const int I(const EST_String &path) const
Definition: EST_Features.h:146
float fval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:98
const char * str(void) const
Get a const-pointer to the actual memory.
Definition: EST_String.h:245
static EST_String cat(const EST_String s1, const EST_String s2=Empty, const EST_String s3=Empty, const EST_String s4=Empty, const EST_String s5=Empty, const EST_String s6=Empty, const EST_String s7=Empty, const EST_String s8=Empty, const EST_String s9=Empty)
Definition: EST_String.cc:1096
int contains(const char *s, int pos=-1) const
Does it contain this substring?
Definition: EST_String.h:375
void begin(const Container &over)
Set the iterator ready to run over this container.
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
const int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:191
const T & first() const
return const reference to first item in list
Definition: EST_TList.h:146
void resize(int n, int set=1)
Definition: EST_TVector.cc:196
INLINE const T & a_no_check(int n) const
read-only const access operator: without bounds checking
Definition: EST_TVector.h:257
const T * memory() const
Definition: EST_TVector.h:241
int eof()
end of file
Definition: EST_Token.h:356
void set_SingleCharSymbols(const EST_String &sc)
set which characters are to be treated as single character symbols
Definition: EST_Token.h:338
EST_Token get_upto(const EST_String &s)
get up to {\tt s} in stream as a single token.
Definition: EST_Token.cc:492
int fread(void *buff, int size, int nitems) EST_WARN_UNUSED_RESULT
Reading binary data, (don't use peek() immediately beforehand)
Definition: EST_Token.cc:355
const EST_String filename() const
The originating filename (if there is one)
Definition: EST_Token.h:372
int open_string(const EST_String &newbuffer)
open a \Ref{EST_TokenStream} for string rather than a file
Definition: EST_Token.cc:251
EST_Token get_upto_eoln(void)
get up to {\tt s} in end of line as a single token.
Definition: EST_Token.cc:516
EST_Token & peek(void)
peek at next token
Definition: EST_Token.cc:830
int tell(void) const
tell, synonym for filepos
Definition: EST_Token.h:363
int open(const EST_String &filename)
open a \Ref{EST_TokenStream} for a file.
Definition: EST_Token.cc:200
EST_TokenStream & get(EST_Token &t)
get next token in stream
Definition: EST_Token.cc:486
int seek(int position)
seek, reposition file pointer
Definition: EST_Token.cc:305
int channel_position(const char *name, int offset=0) const
Definition: EST_Track.cc:392
void set_channel_name(const EST_String &name, int channel)
set the name of the channel.
Definition: EST_Track.cc:166
float & a_no_check(int i, int c=0)
Definition: EST_Track.h:419
EST_read_status load(const EST_String name, float ishift=0.0, float startt=0.0)
Definition: EST_Track.cc:1309
int track_break(int i) const
return true if frame i is a break
Definition: EST_Track.h:633
int val(int i) const
return true if frame i is a value
Definition: EST_Track.cc:539
float & a(int i, int c=0)
Definition: EST_Track.cc:1022
int num_aux_channels() const
return number of auxiliary channels in track
Definition: EST_Track.h:659
void set_name(const EST_String &n)
set name of track - redundant use access to features
Definition: EST_Track.h:198
bool has_channel(const char *name) const
Definition: EST_Track.h:384
bool equal_space() const
return true if track has equal (i.e. fixed) frame spacing *‍/
Definition: EST_Track.h:669
void set_value(int i)
set frame i to be a value
Definition: EST_Track.cc:131
float & t(int i=0)
return time position of frame i
Definition: EST_Track.h:477
void resize_aux(EST_StrList &map, bool preserve=1)
Definition: EST_Track.cc:311
float ms_t(int i) const
return time of frame i in milli-seconds.
Definition: EST_Track.h:481
int num_channels() const
return number of channels in track
Definition: EST_Track.h:656
int num_frames() const
return number of frames in track
Definition: EST_Track.h:650
void change_type(float nshift, bool single_break)
REDO.
Definition: EST_Track.cc:653
void resize(int num_frames, int num_channels, bool preserve=1)
Definition: EST_Track.cc:211
EST_String name() const
name of track - redundant use access to features
Definition: EST_Track.h:195
void fill_time(float t, int start=1)
Definition: EST_Track.cc:786
float shift() const
Definition: EST_Track.cc:599
void set_break(int i)
set frame i to be a break
Definition: EST_Track.cc:122
bool single_break() const
Definition: EST_Track.h:672
const EST_String & string(void) const
Definition: EST_Val.h:150
structure for the table.
Definition: EST_TrackMap.h:74
Definition: htk.h:74