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