Edinburgh Speech Tools  2.1-release
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ch_wave_main.cc
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : April 1995 */
35 /*-----------------------------------------------------------------------*/
36 /* Change EST_Wave utility main */
37 /* */
38 /*=======================================================================*/
39 #include <cstdlib>
40 #include <iostream>
41 #include <cmath>
42 #include "EST_Wave.h"
43 #include "EST_cmd_line.h"
44 #include "EST_cmd_line_options.h"
45 #include "EST_sigpr.h"
46 #include "EST_wave_aux.h"
47 #include "EST.h"
48 
49 void wave_extract_channel(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list);
50 
51 
52 void extract_channels(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list);
53 
54 
55 int main (int argc, char *argv[])
56 {
57  EST_Wave sig, sigload;
58  EST_String in_file("-"), out_file("-"), op_file(""), test;
59  EST_Option al;
60  EST_StrList files;
61  EST_Litem *p;
62 
63 
64  parse_command_line
65  (argc, argv,
66  EST_String("[input file0] [input file1] ... -o [output file]\n")+
67  "Summary: change/copy/combine waveform files\n"+
68  "use \"-\" to make input and output files stdin/out\n"+
69  "-h Options help\n\n"+
70  options_wave_input()+
71  options_wave_output()+
72  "-scale <float> Scaling factor. Increase or descrease the amplitude\n"
73  " of the whole waveform by the factor given\n\n"
74 
75  "-scaleN <float> Scaling factor with normalization. \n"
76  " The waveform is scaled to its maximum level, after which \n"
77  " it is scaled by the factor given\n\n"
78 
79  "-lpfilter <int> Low pass filter, with cutoff frequency in Hz \n"
80  " Filtering is performed by a FIR filter which is built at run \n"
81  " time. The order of the filter can be given by -forder. The \n"
82  " default value is 199\n\n"
83 
84  "-hpfilter <int> High pass filter, with cutoff frequency in Hz \n"
85  " Filtering is performed by a FIR filter which is \n"
86  " built at run time. The order of the filter can \n"
87  " be given by -forder. The default value is 199.\n\n"
88 
89  "-forder <int> Order of FIR filter used for lpfilter and \n"
90  " hpfilter. This must be ODD. Sensible values range \n"+
91  " from 19 (quick but with a shallow rolloff) to 199 \n"
92  " (slow but with a steep rolloff). The default is 199.\n\n"
93 
94  "-fafter Do filtering after other operations such as \n"
95  " resampling (default : filter before other operations)\n\n"
96 
97  "-info Print information about file and header. \n"
98  " This option gives useful information such as file \n"
99  " length, sampling rate, number of channels etc\n"
100  " No output is produced\n\n"
101 
102  "-add A new single channel waveform is created by adding \n"
103  " the corresponding sample points of each input waveform\n\n"
104 
105  "-pc <string> Combine input waveforms to form a single \n"
106  " multichannel waveform. The argument to this option controls \n"
107  " how long the new waveform should be. If the option \n"
108  " is LONGEST, the output wave if the length of the \n"
109  " longest input wave and shorter waves are padded with \n"
110  " zeros at the end. If the option is FIRST, the length \n"
111  " of the new waveform is the length of the first file \n"
112  " on the command line, and subsequent waves are padded \n"
113  " or cut to this length\n\n"
114 
115  "-key <ifile> Label file designating subsections, for use with \n"
116  " -divide. The KEYLAB file is a label file which specifies \n"
117  " where chunks (such as individual sentences) in \n"
118  " a waveform begin and end. See section of wave extraction.\n\n"
119 
120  "-divide Divide a single input waveform into multiple output \n"
121  " waveforms. Each output waveform is extracted from the \n"
122  " input waveform by using the KEYLAB file, which \n"
123  " specifies the start and stop times for each chunk. \n"
124  " The output files are named according to the filename \n"
125  " in the KEYLAB file, with extension given by -ext. See \n"
126  " section on wave extraction\n\n"
127 
128  "-ext <string> File extension for divided waveforms\n\n"
129 
130  "-extract <string> Used in conjunction with -key to extract a \n"
131  " single section of waveform from the input \n"
132  " waveform. The argument is the name of a file given \n"
133  " in the file column of the KEYLAB file.\n",
134  files, al);
135 
136  out_file = al.present("-o") ? al.val("-o") : (EST_String)"-";
137 
138  // There will always be at least one (or stdin)
139  // The first is dealt specially in case its *way* big
140  if (read_wave(sig, files.first(), al) != format_ok)
141  exit(-1);
142  if (al.present("-info"))
143  wave_info(sig);
144  // concat or parallelize remaining input files
145 
146  if (files.length() > 1)
147  {
148  for (p= files.head()->next(); p != 0; p=p->next())
149  {
150  if (read_wave(sigload, files(p), al) != format_ok)
151  exit(-1);
152  if (al.present("-info"))
153  wave_info(sigload);
154  else if (al.present("-pc"))
155  {
156  if ((downcase(al.val("-pc")) == "longest") &&
157  (sig.num_samples() < sigload.num_samples()))
158  sig.resize(sigload.num_samples());
159  else /* "first" or sig is longer */
160  sigload.resize(sig.num_samples());
161  sig |= sigload;
162  }
163  else if (al.present("-add"))
164  add_waves(sig, sigload);
165  else
166  sig += sigload;
167  }
168  }
169 
170  if (al.present("-info"))
171  exit(0); // done what I've been asked to so stop
172 
173  // All input files are now in a single wave called sig
174 
175  // default is to filter before any resampling etc.
176  // (this may cause problems for multiplexed data !)
177  if(!al.present("-fafter")){
178  if(al.present("-lpfilter"))
179  FIRlowpass_filter(sig,al.ival("-lpfilter"),al.ival("-forder"));
180  if(al.present("-hpfilter"))
181  FIRhighpass_filter(sig,al.ival("-hpfilter"),al.ival("-forder"));
182  }
183 
184  if (al.present("-c")) // extract a channel from a multi-channel wave
185  {
186  EST_StrList s;
187  EST_IList il;
188  EST_Wave nsig;
189  StringtoStrList(al.val("-c"), s, " ,"); // separator can be space or comma
190  StrListtoIList(s, il);
191  extract_channels(nsig, sig, il);
192  sig = nsig;
193  }
194 
195  if (al.present("-F")) // resample
196  sig.resample(al.ival("-F"));
197 
198  if (al.present("-scale")) // rescale
199  {
200  float scale = al.fval("-scale", 0);
201  sig.rescale(scale);
202  }
203  else if (al.present("-scaleN")) // rescale
204  {
205  float scale = al.fval("-scaleN", 0);
206  if ((scale < 0) || (scale > 1.0))
207  {
208  cerr << "ch_wave: -scaleN must be in range 0 to 1" << endl;
209  exit(-1);
210  }
211  sig.rescale(scale,1);
212  }
213 
214  EST_Relation key;
215 
216  if (al.present("-divide"))
217  {
218  EST_WaveList wl;
219  if (!al.present("-key"))
220  {
221  cerr << "Must have key file specified when dividing waveform\n";
222  exit (-1);
223  }
224  if (key.load(al.val("-key")) != format_ok)
225  exit(-1);
226 
227  if (wave_divide(wl, sig, key, al.val("-ext", 0)) == -1)
228  exit(0);
229  for (p = wl.head(); p; p = p->next())
230  wl(p).save(wl(p).name(), al.val("-otype", 0));
231  exit(0);
232  }
233  else if (al.present("-extract"))
234  {
235  EST_Wave e;
236  if (!al.present("-key"))
237  {
238  cerr << "Must have key file specified when dividing waveform\n";
239  exit (-1);
240  }
241  if (key.load(al.val("-key")) != format_ok)
242  exit(-1);
243 
244  if (wave_extract(e, sig, key, al.val("-extract")) == -1)
245  exit (-1);
246  sig = e;
247  }
248 
249  // if we are filtering after other operations
250  if(al.present("-fafter")){
251  if(al.present("-lpfilter"))
252  FIRlowpass_filter(sig,al.ival("-lpfilter"),al.ival("-forder"));
253  if(al.present("-hpfilter"))
254  FIRhighpass_filter(sig,al.ival("-hpfilter"),al.ival("-forder"));
255  }
256 
257  write_wave(sig, out_file, al);
258  return 0;
259 }
260 
261 
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
Definition: EST_Wave.h:64
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.
void FIRlowpass_filter(EST_Wave &sigin, int freq, int order=DEFAULT_FILTER_ORDER)
Definition: filter.cc:524
float fval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:98
void rescale(float gain, int normalize=0)
Definition: EST_Wave.cc:501
int num_samples() const
return the number of samples in the waveform
Definition: EST_Wave.h:143
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...
const T & first() const
return const reference to first item in list
Definition: EST_TList.h:154
const int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
void FIRhighpass_filter(EST_Wave &in_sig, int freq, int order)
Definition: filter.cc:532
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
void resize(int num_samples, int num_channels=EST_ALL, int set=1)
resize the waveform
Definition: EST_Wave.h:184
EST_read_status load(const EST_String &filename, const EST_String &type="esps")
void resample(int rate)
Resample waveform to rate
Definition: EST_Wave.cc:487