Edinburgh Speech Tools  2.1-release
ch_wave_main.cc
Go to the documentation of this file.
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 using namespace std;
50 
51 void wave_extract_channel(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list);
52 
53 
54 void extract_channels(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list);
55 
56 
57 int main (int argc, char *argv[])
58 {
59  EST_Wave sig, sigload;
60  EST_String in_file("-"), out_file("-"), op_file(""), test;
61  EST_Option al;
62  EST_StrList files;
63  EST_Litem *p;
64 
65 
67  (argc, argv,
68  EST_String("[input file0] [input file1] ... -o [output file]\n")+
69  "Summary: change/copy/combine waveform files\n"+
70  "use \"-\" to make input and output files stdin/out\n"+
71  "-h Options help\n\n"+
74  "-scale <float> Scaling factor. Increase or descrease the amplitude\n"
75  " of the whole waveform by the factor given\n\n"
76 
77  "-scaleN <float> Scaling factor with normalization. \n"
78  " The waveform is scaled to its maximum level, after which \n"
79  " it is scaled by the factor given\n\n"
80 
81  "-lpfilter <int> Low pass filter, with cutoff frequency in Hz \n"
82  " Filtering is performed by a FIR filter which is built at run \n"
83  " time. The order of the filter can be given by -forder. The \n"
84  " default value is 199\n\n"
85 
86  "-hpfilter <int> High pass filter, with cutoff frequency in Hz \n"
87  " Filtering is performed by a FIR filter which is \n"
88  " built at run time. The order of the filter can \n"
89  " be given by -forder. The default value is 199.\n\n"
90 
91  "-forder <int> Order of FIR filter used for lpfilter and \n"
92  " hpfilter. This must be ODD. Sensible values range \n"+
93  " from 19 (quick but with a shallow rolloff) to 199 \n"
94  " (slow but with a steep rolloff). The default is 199.\n\n"
95 
96  "-fafter Do filtering after other operations such as \n"
97  " resampling (default : filter before other operations)\n\n"
98 
99  "-info Print information about file and header. \n"
100  " This option gives useful information such as file \n"
101  " length, sampling rate, number of channels etc\n"
102  " No output is produced\n\n"
103 
104  "-add A new single channel waveform is created by adding \n"
105  " the corresponding sample points of each input waveform\n\n"
106 
107  "-pc <string> Combine input waveforms to form a single \n"
108  " multichannel waveform. The argument to this option controls \n"
109  " how long the new waveform should be. If the option \n"
110  " is LONGEST, the output wave if the length of the \n"
111  " longest input wave and shorter waves are padded with \n"
112  " zeros at the end. If the option is FIRST, the length \n"
113  " of the new waveform is the length of the first file \n"
114  " on the command line, and subsequent waves are padded \n"
115  " or cut to this length\n\n"
116 
117  "-key <ifile> Label file designating subsections, for use with \n"
118  " -divide. The KEYLAB file is a label file which specifies \n"
119  " where chunks (such as individual sentences) in \n"
120  " a waveform begin and end. See section of wave extraction.\n\n"
121 
122  "-divide Divide a single input waveform into multiple output \n"
123  " waveforms. Each output waveform is extracted from the \n"
124  " input waveform by using the KEYLAB file, which \n"
125  " specifies the start and stop times for each chunk. \n"
126  " The output files are named according to the filename \n"
127  " in the KEYLAB file, with extension given by -ext. See \n"
128  " section on wave extraction\n\n"
129 
130  "-ext <string> File extension for divided waveforms\n\n"
131 
132  "-extract <string> Used in conjunction with -key to extract a \n"
133  " single section of waveform from the input \n"
134  " waveform. The argument is the name of a file given \n"
135  " in the file column of the KEYLAB file.\n",
136  files, al);
137 
138  out_file = al.present("-o") ? al.val("-o") : (EST_String)"-";
139 
140  // There will always be at least one (or stdin)
141  // The first is dealt specially in case its *way* big
142  if (read_wave(sig, files.first(), al) != format_ok)
143  exit(-1);
144  if (al.present("-info"))
145  wave_info(sig);
146  // concat or parallelize remaining input files
147 
148  if (files.length() > 1)
149  {
150  for (p= files.head()->next(); p != 0; p=p->next())
151  {
152  if (read_wave(sigload, files(p), al) != format_ok)
153  exit(-1);
154  if (al.present("-info"))
155  wave_info(sigload);
156  else if (al.present("-pc"))
157  {
158  if ((downcase(al.val("-pc")) == "longest") &&
159  (sig.num_samples() < sigload.num_samples()))
160  sig.resize(sigload.num_samples());
161  else /* "first" or sig is longer */
162  sigload.resize(sig.num_samples());
163  sig |= sigload;
164  }
165  else if (al.present("-add"))
166  add_waves(sig, sigload);
167  else
168  sig += sigload;
169  }
170  }
171 
172  if (al.present("-info"))
173  exit(0); // done what I've been asked to so stop
174 
175  // All input files are now in a single wave called sig
176 
177  // default is to filter before any resampling etc.
178  // (this may cause problems for multiplexed data !)
179  if(!al.present("-fafter")){
180  if(al.present("-lpfilter"))
181  FIRlowpass_filter(sig,al.ival("-lpfilter"),al.ival("-forder"));
182  if(al.present("-hpfilter"))
183  FIRhighpass_filter(sig,al.ival("-hpfilter"),al.ival("-forder"));
184  }
185 
186  if (al.present("-c")) // extract a channel from a multi-channel wave
187  {
188  EST_StrList s;
189  EST_IList il;
190  EST_Wave nsig;
191  StringtoStrList(al.val("-c"), s, " ,"); // separator can be space or comma
192  StrListtoIList(s, il);
193  extract_channels(nsig, sig, il);
194  sig = nsig;
195  }
196 
197  if (al.present("-F")) // resample
198  sig.resample(al.ival("-F"));
199 
200  if (al.present("-scale")) // rescale
201  {
202  float scale = al.fval("-scale", 0);
203  sig.rescale(scale);
204  }
205  else if (al.present("-scaleN")) // rescale
206  {
207  float scale = al.fval("-scaleN", 0);
208  if ((scale < 0) || (scale > 1.0))
209  {
210  cerr << "ch_wave: -scaleN must be in range 0 to 1" << endl;
211  exit(-1);
212  }
213  sig.rescale(scale,1);
214  }
215 
216  EST_Relation key;
217 
218  if (al.present("-divide"))
219  {
220  EST_WaveList wl;
221  if (!al.present("-key"))
222  {
223  cerr << "Must have key file specified when dividing waveform\n";
224  exit (-1);
225  }
226  if (key.load(al.val("-key")) != format_ok)
227  exit(-1);
228 
229  if (wave_divide(wl, sig, key, al.val("-ext", 0)) == -1)
230  exit(0);
231  for (p = wl.head(); p; p = p->next())
232  wl(p).save(wl(p).name(), al.val("-otype", 0));
233  exit(0);
234  }
235  else if (al.present("-extract"))
236  {
237  EST_Wave e;
238  if (!al.present("-key"))
239  {
240  cerr << "Must have key file specified when dividing waveform\n";
241  exit (-1);
242  }
243  if (key.load(al.val("-key")) != format_ok)
244  exit(-1);
245 
246  if (wave_extract(e, sig, key, al.val("-extract")) == -1)
247  exit (-1);
248  sig = e;
249  }
250 
251  // if we are filtering after other operations
252  if(al.present("-fafter")){
253  if(al.present("-lpfilter"))
254  FIRlowpass_filter(sig,al.ival("-lpfilter"),al.ival("-forder"));
255  if(al.present("-hpfilter"))
256  FIRhighpass_filter(sig,al.ival("-hpfilter"),al.ival("-forder"));
257  }
258 
259  write_wave(sig, out_file, al);
260  return 0;
261 }
262 
263 
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
Definition: EST_Wave.h:64
int main(int argc, char *argv[])
Definition: ch_wave_main.cc:57
int ival(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:82
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:526
float fval(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:104
ssize_t num_samples() const
return the number of samples in the waveform
Definition: EST_Wave.h:143
void rescale(float gain, int normalize=0)
Definition: EST_Wave.cc:506
EST_UItem * next()
Definition: EST_UList.h:55
int wave_extract(EST_Wave &part, EST_Wave &sig, EST_Relation &keylab, const EST_String &file)
EST_String downcase(const EST_String &s)
Definition: EST_String.cc:942
void wave_info(EST_Wave &w)
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:152
EST_String options_wave_input(void)
void FIRhighpass_filter(EST_Wave &in_sig, int freq, int order)
Definition: filter.cc:534
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
int length() const
Definition: EST_UList.cc:57
int wave_divide(EST_WaveList &wl, EST_Wave &sig, EST_Relation &keylab, const EST_String &ext)
EST_write_status write_wave(EST_Wave &sig, const EST_String &in_file, EST_Option &al)
void resize(int num_samples, int num_channels=EST_ALL, int set=1)
resize the waveform
Definition: EST_Wave.h:184
void add_waves(EST_Wave &s, const EST_Wave &m)
EST_read_status read_wave(EST_Wave &sig, const EST_String &in_file, EST_Option &al)
EST_String options_wave_output(void)
#define format_ok
int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
EST_UItem * head() const
Definition: EST_UList.h:97
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:492
EST_String
int parse_command_line(int argc, char *argv[], const EST_String &usage, EST_StrList &files, EST_Option &al, int make_stdio=1)
Definition: cmd_line.cc:101
void extract_channels(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list)
Definition: EST_wave_aux.cc:84
void wave_extract_channel(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list)