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