Edinburgh Speech Tools  2.1-release
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ch_track_main.cc
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1994,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 : June 1994 */
35 /*-----------------------------------------------------------------------*/
36 /* EST_Track file manipulation program */
37 /* */
38 /*=======================================================================*/
39 
40 #include "EST.h"
41 #include "EST_cmd_line_options.h"
42 
43 #define DEFAULT_TIME_SCALE 0.001
44 
46 void extract_channel(EST_Track &orig, EST_Track &nt, EST_IList &ch_list);
47 
48 EST_write_status save_snns_pat(const EST_String filename,
49  EST_TrackList &inpat, EST_TrackList &outpat);
50 
51 EST_read_status read_TrackList(EST_TrackList &tlist, EST_StrList &files,
52  EST_Option &al);
53 
54 void extract(EST_Track &tr, EST_Option &al);
55 
56 int main(int argc, char *argv[])
57 {
58  EST_String in_file("-"), out_file("-");
59  EST_Option al, settings;
60  EST_String fname, ftmp;
61  EST_StrList files;
62  EST_Track tr;
63  EST_TrackList trlist;
64  EST_Litem *p;
65 
66  parse_command_line(
67  argc, argv,
68  EST_String("[input file] -o [output file] [options]\n")+
69  "Summary: change/copy track files\n"
70  "use \"-\" to make input and output files stdin/out\n"
71  "-h Options help\n"+
72  options_track_input()+ "\n"+
73  options_track_output()+ "\n"
74  "-info Print information about file and header. \n"
75  " This option gives useful information such as file \n"
76  " length, file type, channel names. No output is produced\n\n"
77  "-track_names <string> \n"
78  " File containing new names for output channels\n\n"
79  "-diff Differentiate contour. This performs simple \n"
80  " numerical differentiation on the contour by \n"
81  " subtracting the amplitude of the current frame \n"
82  " from the amplitude of the next. Although quick, \n"
83  " this technique is crude and not recommende as the \n"
84  " estimation of the derivate is done on only one point\n\n"
85  "-delta <int> Make delta coefficients (better form of differentiate).\n"
86  " The argument to this option is the regression length of \n"
87  " of the delta calculation and can be between 2 and 4 \n\n"
88  "-sm <float> Length of smoothing window in seconds. Various types of \n"
89  " smoothing are available for tracks. This options specifies \n"
90  " length of the smooting window which effects the degree of \n"
91  " smoothing, i.e. a longer value means more smoothing \n\n"
92  "-smtype <string> Smooth type, median or mean\n"
93  "-style <string> Convert track to other form. Currently only one form \n"
94  " \"label\" is supported. This uses a specified cut off to \n"
95  " make a label file, with two labels, one for above the \n"
96  " cut off (-pos) and one for below (-neg)\n\n"
97  "-t <float> threshold for track to label conversion \n"
98  "-neg <string> Name of negative label in track to label conversion \n"
99  "-pos <string> Name of positive label in track to label conversion \n"
100  "-pc <string> Combine given tracks in parallel. If option \n"
101  " is longest, pad shorter tracks to longest, else if \n"
102  " first pad/cut to match first input track \n" +
103  options_track_filetypes_long(),
104  files, al);
105 
106 /*redundant options
107  "-time_channel <string>\n"+
108  " Which track in track file holds pitchmark times\n"+
109  "-time_scale <float> \n"+
110  " Scale of pitchmarks (default 0.001 = milliseconds)\n"+
111 */
112 
113 
114  override_lib_ops(settings, al);
115  out_file = al.present("-o") ? al.val("-o") : (EST_String)"-";
116 
117  EST_TokenStream ts;
118 
119 // ts.open(files.first());
120 // tr.load(ts);
121 // cout << tr;
122 
123  if (read_TrackList(trlist, files, al) != read_ok)
124  exit(0);
125 
126  if (files.length() == 0)
127  {
128  cerr << argv[0] << ": no input files specified\n";
129  exit(-1);
130  }
131 
132  if (al.present("-info"))
133  {
134  for (p = trlist.head(); p; p = p->next())
135  track_info(trlist(p));
136  exit(0);
137  }
138 
139  if (al.present("-pc")) // parallelize them
140  ParallelTracks(tr, trlist, al.val("-pc"));
141 
142  else if (al.val("-otype", 0) == "snns")
143  { // sometime this will generalise for multiple input files
144  EST_TrackList inpat, outpat;
145  inpat.append(trlist.nth(0));
146  outpat.append(trlist.nth(1));
147  save_snns_pat(out_file, inpat, outpat);
148  exit(0);
149  }
150  else // concatenate them
151  {
152  tr.resize(0, tr.num_channels());
153  // Reorg -- fix += to resize to largest num_channels (with warning)
154  for (p = trlist.head(); p; p = p->next())
155  tr += trlist(p);
156  }
157 
158  if (al.present("-S"))
159  tr.sample(al.fval("-S"));
160  if (al.present("-sm"))
161  {
162  track_smooth(tr, al.fval("-sm"),al.val("-smtype"));
163  }
164 
165  if (al.present("-diff") && al.present("-delta"))
166  {
167  cerr << "Using -diff and -delta together makes no sense !\n";
168  exit(-1);
169  }
170  if (al.present("-diff"))
171  {
172  tr = differentiate(tr);
173  }
174  if (al.present("-delta"))
175  {
176  EST_Track ntr = tr; // to copy size !;
177  delta(tr,ntr,al.ival("-delta"));
178  tr = ntr;
179  }
180 
181  if (al.present("-c"))
182  {
183  EST_StrList s;
184  EST_Track ntr;
185  EST_IList il;
186  StringtoStrList(al.val("-c"), s, " ,"); // separator can be space or comma
187  StrListtoIList(s, il);
188  extract_channel(tr, ntr, il);
189  tr = ntr;
190  }
191 
192  if (al.present("-start") || al.present("-end")
193  || al.present("-to") || al.present("-from"))
194  extract(tr, al);
195 
196 // tr.assign_map(&LPCTrackMap);
197 // tr.set_space_type("VARI");
198 
199 
200  // optionally rename output tracks before saving
201 
202  if (al.present("-track_names"))
203  {
204  EST_StrList new_names;
205  if(load_StrList(al.val("-track_names"),new_names) != format_ok)
206  {
207  cerr << "Failed to load new track names file." << endl;
208  exit(-1);
209  }
210  /*
211  if (tr.num_channels() != new_names.length())
212  {
213  cerr << "Number of names in output track names file (";
214  cerr << new_names.length() << ") " << endl;
215  cerr << " does not match number of output channels (";
216  cerr << tr.num_channels() << ")" << endl;
217  exit(-1);
218  }
219 
220  EST_Litem *np;
221  int ni;
222  for (np = new_names.head(),ni=0; np; np = np->next(),ni++)
223  tr.set_channel_name(new_names(np),ni);
224  */
225  tr.resize(EST_CURRENT, new_names);
226  }
227 
228  // track_info(tr);
229 
230 /* tr.resize(EST_CURRENT, 10);
231 
232  cout << "new\n";
233  track_info(tr);
234 
235  EST_StrList x;
236  x.append("a");
237  x.append("c");
238  x.append("d");
239 
240 
241 
242  cout << "new\n";
243  track_info(tr);
244 */
245 
246 
247  // Write out file in appropriate format
248 
249  if (al.val("-style",0) == "label")
250  {
251  EST_Relation lab;
252  if (al.present("-t"))
253  track_to_label(tr, lab, al.fval("-t"));
254  else
255  track_to_label(tr, lab);
256  if (al.present("-pos"))
257  change_label(lab, "pos", al.val("-pos"));
258  if (al.present("-neg"))
259  change_label(lab, "neg", al.val("-neg"));
260  if (lab.save(out_file) != write_ok)
261  exit(-1);
262  }
263 /* else if (al.val("-style",0) == "pm")
264  {
265  EST_Relation lab;
266 
267  if (!al.present("-f"))
268  {
269  cerr << "must specify sample rate (with -f) for pm style\n";
270  exit(-1);
271  }
272  int sample_rate = al.ival("-f", 0);
273 
274  track_to_pm(tr, sample_rate, lab);
275 
276  if (lab.save(out_file) != write_ok)
277  exit(-1);
278  }
279 */
280  else
281  {
282  if (tr.save(out_file, al.val("-otype")) != write_ok)
283  exit(-1);
284  }
285 
286  return 0;
287 }
288 
289 void override_lib_ops(EST_Option &a_list, EST_Option &al)
290 {
291  a_list.override_val("ishift", al.val("-s", 0));
292  a_list.override_val("color", al.val("-color", 0));
293  a_list.override_val("in_track_file_type", al.val("-itype", 0));
294  a_list.override_val("out_track_file_type", al.val("-otype", 0));
295  a_list.override_val("tr_to_label_thresh", al.val("-t", 0));
296  a_list.override_fval("time_scale", DEFAULT_TIME_SCALE);
297 
298  if (al.val("-style", 0) == "label")
299  a_list.override_val("lab_file_type", al.val("-otype", 0));
300  if (al.present("-time_scale"))
301  a_list.override_fval("time_scale", al.fval("-time_scale", 1));
302  if (al.present("-time_channel"))
303  a_list.override_val("time_channel", al.sval("-time_channel", 1));
304 }
305 
306 
307 /** @name Making multiple tracks into a single track
308 
309 If multiple input files are specified, by default they are concatenated into
310 the output file.
311 <para>
312 <screen>
313 $ ch_track kdt_010.tr kdt_011.tr kdt_012.tr kdt_013.tr -o out.tr
314 </screen>
315 </para>
316 <para>
317 In the above example, 4 multi channel input files are converted to
318 one single channel output file. Multi-channel tracks can
319 concatenated provided they all have the same number of input channels.
320 
321 </para><para>
322 
323 Multiple input files can be made into a multi-channel output file by
324 using the -pc option:
325 
326 </para><para>
327 <screen>
328 $ ch_track kdt_010.tr kdt_011.tr kdt_012.tr kdt_013.tr -o -pc longest out.tr
329 </screen>
330 </para>
331 <para>
332 The argument to -pc can either be longest, in which the output
333 track is the length of the longest input file, or first in which it
334 is the length of the first input file.
335 
336 */
337 
338 //@{
339 //@}
340 
341 /** @name Extracting channels from multi-channel tracks
342 
343 The -c option is used to specify channels which should be extracted
344 from the input. If the input is a 4 channel track,
345 </para><para>
346 <screen>
347 $ ch_track kdt_m.tr -o a.tr -c "0 2"
348 </screen>
349 </para>
350 <para>
351 will extract the 0th and 2nd channel (counting starts from 0). The
352 argument to -c can be either a single number of a list of numbers
353 (wrapped in quotes).
354 
355  */
356 //@{
357 //@}
358 
359 
360 /** @name Extracting of a single region from a track
361 
362 There are several ways of extracting a region of a track. The
363 simplest way is by using the start, end, to and from commands to
364 delimit a sub portion of the input track. For example
365 </para><para>
366 <screen>
367 $ ch_track kdt_010.tr -o small.tr -start 1.45 -end 1.768
368 </screen>
369 </para>
370 <para>
371 extracts a subtrack starting at 1.45 seconds and extending to 1.768 seconds.
372 alternatively,
373 </para><para>
374 <screen>
375 $ ch_track kdt_010.tr -o small.tr -from 50 -to 100
376 </screen>
377 </para>
378 <para>
379 extracts a subtrack starting at 50 frames and extending to 100
380 frames. Times and frames can be mixed in sub-track extraction. The
381 output track will have the same number of channels as the input track.
382 
383 
384 */
385 //@{
386 //@}
387 
388 /** @name Adding headers and format conversion
389 
390 It is usually a good idea for all track files to have headers as this
391 way different files can be handled safely. ch_track provides a means
392 of adding headers to unheadered files. These files are assumed to
393 be ascii floats with one channel per line.
394 
395 The following adds a header to an ascii file.
396 </para>
397 <para>
398 <screen>
399 $ ch_track kdt_010.atr -o kdt_010.h5.tr -otype est -s 0.01
400 </screen>
401 </para>
402 <para>
403 ch_track can change the frame shift of a fixed frame file, or convert
404 a variable frame shift file into a fixed frame shift. At present this
405 is done with a very crude resampling technique and hence the output
406 file may suffer from anti-aliasing distortion.</para><para>
407 
408 
409 Change to a frame spacing of 0.02 seconds:
410 </para><para>
411 <screen>
412 $ ch_track kdt_010.tr -o kdt_010.tr2 -S 0.02
413 </screen>
414 */
415  //@{
416  //@}
417 
418 //@}
419 
void delta(EST_Track &tr, EST_Track &d, int regression_length=3)
Definition: delta.cc:49
int override_val(const EST_String rkey, const EST_String rval)
add to end of list or overwrite. If rval is empty, do nothing
Definition: EST_Option.cc:48
int ival(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:76
int StrListtoIList(EST_StrList &s, EST_IList &il)
Convert a list of strings to a list of integers.
int num_channels() const
return number of channels in track
Definition: EST_Track.h:656
int override_fval(const EST_String rkey, const float rval)
add to end of list or overwrite. If rval is empty, do nothing
Definition: EST_Option.cc:56
float fval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:98
T & nth(int n)
return the Nth value
Definition: EST_TList.h:147
const EST_String & sval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:87
void resize(int num_frames, int num_channels, bool preserve=1)
Definition: EST_Track.cc:211
void StringtoStrList(EST_String s, EST_StrList &l, EST_String sep)
Convert a EST_String to a EST_StrList by separating tokens in s delimited by the separator sep...
EST_write_status save(const EST_String name, const EST_String EST_filetype="")
Definition: EST_Track.cc:1230
const int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
void sample(float shift)
Definition: EST_Track.cc:671
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:198
EST_write_status save(const EST_String &filename, bool evaluate_ff=false) const
EST_Track differentiate(EST_Track &c, float samp_int=0.0)
EST_read_status load_StrList(EST_String filename, EST_StrList &l)
Load tokens from a file and return them in a EST_StrList.