Edinburgh Speech Tools  2.1-release
EST_wave_aux.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 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 and Alan Black */
34 /* Date : June 1996 */
35 /*-----------------------------------------------------------------------*/
36 /* more EST_Wave class methods */
37 /* */
38 /*=======================================================================*/
39 
40 #include <cstring>
41 #include "EST_unix.h"
42 #include <cstdlib>
43 #include "EST_cutils.h"
44 #include "EST_string_aux.h"
45 #include "EST_Wave.h"
46 #include "EST_wave_utils.h"
47 #include "EST_wave_aux.h"
48 #include "EST_io_aux.h"
49 #include "EST_error.h"
50 
51 using namespace std;
52 
53 void extract(EST_Wave &sig, EST_Option &al);
54 
55 /* Allow EST_Wave to be used in an EST_Val */
57 
58 static EST_TValuedEnumDefinition<EST_sample_type_t, const char *,NO_INFO> st_names[] = {
59 {st_unknown, {"undef"},0},
60 {st_schar, {"schar","byte"},0},
61 {st_uchar, {"uchar"},0},
62 {st_short, {"short"},0},
63 {st_shorten, {"shorten"},0},
64 {st_int, {"int"},0},
65 {st_float, {"float"},0},
66 {st_double, {"double"},0},
67 {st_mulaw, {"mulaw"},0},
68 {st_adpcm, {"adpcm"},0},
69 {st_alaw, {"alaw"},0},
70 {st_ascii, {"ascii"},0},
71 {st_unknown, {0},0}
72 };
73 
75 
77 {
78  for (int i = 0; i < sig.num_samples() -1; ++i)
79  sig.a(i) = sig.a(i + 1) - sig.a(i);
80  sig.resize(sig.num_samples()-1);
81 }
82 
83 
84 void extract_channels(EST_Wave &single, const EST_Wave &multi,
85  EST_IList &ch_list)
86 {
87 
88  if (&single == &multi)
89  {
90  // some nasty person has passed us the same wave for output and input.
91  EST_Wave tmp;
92  extract_channels(tmp, multi, ch_list);
93  single.copy(tmp);
94  return;
95  }
96 
97  int channel, i;
98  int c = multi.num_channels();
99  int num_samples = multi.num_samples();
100 
101  short *buf = new short [num_samples];
102  EST_Litem *p;
103 
104  single.resize(num_samples, ch_list.length());
105  single.set_sample_rate(multi.sample_rate());
106  single.set_file_type(multi.file_type());
107 
108  for (i = 0, p = ch_list.head(); p; p = p->next(), ++i)
109  {
110  channel = ch_list(p);
111 
112  if (channel < 0 || channel >= c)
113  EST_error("Can't extract channel %d from %d channel waveform\n",
114  channel, c);
115 
116  multi.copy_channel(channel, buf);
117  single.set_channel(i, buf);
118  }
119  delete[] buf;
120 }
121 
122 int wave_extract_channel(EST_Wave &single, const EST_Wave &multi, int channel)
123 {
124  if (&single == &multi)
125  {
126  // some nasty person has passed us the same wave for output and input.
127  EST_Wave tmp;
128  int v = wave_extract_channel(tmp, multi, channel);
129  if(v==0)
130  single.copy(tmp);
131  return v;
132  }
133 
134  int c = multi.num_channels();
135 
136  if (channel < 0 || channel >= c)
137  {
138  cerr << "Can't extract channel " << channel << " from " <<
139  c << " channel waveform\n";
140  return -1;
141  }
142 
143  EST_Wave subwave;
144 
145  multi.sub_wave(subwave, 0, EST_ALL, channel, 1);
146 
147  single.copy(subwave);
148 
149  return 0;
150 }
151 
152 void extract_channels(EST_Wave &single, const EST_Wave &multi, int channel)
153 {
154  EST_IList a;
155  a.append(channel);
156  extract_channels(single, multi, a);
157 }
158 
160 {
161  if (&s == &m)
162  {
163  // some nasty person has passed us the same wave for output and input.
164  EST_Wave tmp;
165  wave_combine_channels(tmp,m);
166  s = tmp;
167  return;
168  }
169  s.resize(m.num_samples(), 1, FALSE);
171 
172  for(int i=0; i<m.num_samples(); i++)
173  {
174  double sum=0.0;
175  for(int j=0; j<m.num_channels(); j++)
176  sum += m.a(i,j);
177  s.a(i,0) = (int)(sum/m.num_channels() + 0.5);
178  }
179 }
180 
181 void add_waves(EST_Wave &s, const EST_Wave &m)
182 {
183  int new_samples = Gof(s.num_samples(), m.num_samples());
184  int new_channels = Gof(s.num_channels(), m.num_channels());
185 
186  s.resize(new_samples, new_channels, 1);
187 
188  for (int i = 0; i < m.num_samples(); i++)
189  for (int j = 0; j < m.num_channels(); j++)
190  s.a(i, j) += m.a(i, j);
191 }
192 
193 void invert(EST_Wave &sig)
194 {
195  sig.rescale(-1.0);
196 }
197 
198 void reverse(EST_Wave &sig)
199 {
200  int i, n;
201  short t;
202  n = (int)floor((float)(sig.num_samples())/2.0);
203 
204  for (i = 0; i < n; ++i)
205  {
206  t = sig.a_no_check(i);
207  sig.a_no_check(i) = sig.a_no_check(sig.num_samples() - 1 -i);
208  sig.a_no_check(sig.num_samples() - 1 -i) = t;
209  }
210 }
211 
212 void extract(EST_Wave &sig, EST_Option &al)
213 {
214  int from, to;
215  EST_Wave sub_wave, w2;
216 
217  if (al.present("-start"))
218  from = (int)(sig.sample_rate() * al.fval("-start"));
219  else if (al.present("-from"))
220  from = al.ival("-from");
221  else
222  from = 0;
223 
224  if (al.present("-end"))
225  to = (int)(sig.sample_rate() * al.fval("-end"));
226  else if (al.present("-to"))
227  to = al.ival("-to");
228  else
229  to = sig.num_samples();
230 
231  sig.sub_wave(sub_wave, from, to - from);
232  w2 = sub_wave;
233  sig = w2;
234 }
235 
237 {
238  EST_String t;
239  cout << "Duration: " <<
240  ftoString((float)w.num_samples()/(float)w.sample_rate(),4,1) << endl;
241 
242  cout << "Sample rate: " << w.sample_rate() << endl;
243  cout << "Number of samples: " << w.num_samples() << endl;
244  cout << "Number of channels: " << w.num_channels() << endl;
245  cout << "Header type: " << w.file_type() << endl;
246  cout << "Data type: " << w.sample_type() << endl;
247 }
248 
249 static EST_String options_wave_filetypes(void)
250 {
251  // Returns list of currently support wave file types
252  // Should be extracted from the list in EST_Wave (but that's
253  // not very clear :-(
254 
255  return "nist, est, esps, snd, riff, aiff, audlab, raw, ascii";
256 }
257 
259 {
260  return
261  EST_String("")+
262  "-start <float> Extract sub-wave starting at this time, specified in \n"
263  " seconds\n\n"
264  "-end <float> Extract sub-wave ending at this time, specified in \n"
265  " seconds\n\n"
266  "-from <int> Extract sub-wave starting at this sample point\n\n"
267  "-to <int> Extract sub-wave ending at this sample point\n\n";
268 }
270 {
271  // The standard waveform input options
272  return
273  EST_String("")+
274  "-itype <string> Input file type (optional). If set to raw, this \n"
275  " indicates that the input file does not have a header. While \n"
276  " this can be used to specify file types other than raw, this is \n"
277  " rarely used for other purposes\n"
278  " as the file type of all the existing supported \n"
279  " types can be determined automatically from the \n"
280  " file's header. If the input file is unheadered, \n"
281  " files are assumed to be shorts (16bit). \n"
282  " Supported types are \n"
283  " "+options_wave_filetypes()+"\n\n"
284  "-n <int> Number of channels in an unheadered input file \n\n"
285  "-f <int> Sample rate in Hertz for an unheadered input file \n\n"
286  "-ibo <string> Input byte order in an unheadered input file: \n"
287  " possibliities are: MSB , LSB, native or nonnative. \n"
288  " Suns, HP, SGI Mips, M68000 are MSB (big endian) \n"
289  " Intel, Alpha, DEC Mips, Vax are LSB (little \n"
290  " endian)\n\n"
291  "-iswap Swap bytes. (For use on an unheadered input file)\n\n"
292  "-istype <string> Sample type in an unheadered input file:\n"
293  " short, alaw, mulaw, byte, ascii\n\n"
294  "-c <string> Select a single channel (starts from 0). \n"
295  " Waveforms can have multiple channels. This option \n"
296  " extracts a single channel for progcessing and \n"
297  " discards the rest. \n\n"+
298  options_subwave();
299 
300 // old option
301 // "-ulaw Assume unheadered input is 8k ulaw\n\n"
302 // this facility moved into na_play
303 // "-r* Select subrange of file. (ESPS compatible)\n\n"
304 
305 }
306 
308 {
309  return
310  EST_String("")+
311  "-o <ofile> Output filename. If not specified output is\n"
312  " to stdout.\n\n"
313  "-otype <string> Output file type, (optional). If no type is\n"
314  " Specified the type of the input file is assumed.\n"
315  " Supported types are: \n"
316  " "+options_wave_filetypes()+"\n\n"
317  "-F <int> Output sample rate in Hz. If this is different \n"
318  " from the input sample rate, resampling will occur \n\n"
319  "-obo <string> Output byte order: MSB, LSB, native, or nonnative. \n"
320  " Suns, HP, SGI Mips, M68000 are MSB (big endian) \n"
321  " Intel, Alpha, DEC Mips, Vax are LSB \n"
322  " (little endian)\n\n"
323  "-oswap Swap bytes when saving to output\n\n"+
324  "-ostype <string> Output sample type: short, alaw, mulaw, byte or ascii\n\n";
325 }
326 
328 #if defined(INSTANTIATE_TEMPLATES)
329 #include "../base_class/EST_TNamedEnum.cc"
331 #endif
332 
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
Definition: EST_Wave.h:64
void set_sample_rate(const int n)
Set sampling rate to n
Definition: EST_Wave.h:149
void invert(EST_Wave &sig)
void wave_info(EST_Wave &w)
Utility IO Function header file.
void add_waves(EST_Wave &s, const EST_Wave &m)
int ival(const EST_String &rkey, int m=1) const
Definition: EST_Option.cc:82
EST_TNamedEnum< EST_sample_type_t > EST_sample_type_map(st_names)
void copy(const EST_Wave &from)
Definition: EST_Wave.cc:121
void set_file_type(const EST_String t)
Definition: EST_Wave.h:167
char NO_INFO
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 extract_channels(EST_Wave &single, const EST_Wave &multi, EST_IList &ch_list)
Definition: EST_wave_aux.cc:84
#define VAL_REGISTER_CLASS(NAME, CLASS)
Definition: EST_Val_defs.h:62
const int EST_ALL
int wave_extract_channel(EST_Wave &single, const EST_Wave &multi, int channel)
void rescale(float gain, int normalize=0)
Definition: EST_Wave.cc:506
short & a(ssize_t i, ssize_t channel=0)
Definition: EST_Wave.cc:128
void sub_wave(EST_Wave &sw, int offset=0, ssize_t num=EST_ALL, ssize_t start_c=0, ssize_t nchan=EST_ALL)
Definition: EST_Wave.cc:342
EST_String ftoString(float n, int pres=3, int width=0, int l=0)
Make a EST_String object from an float, with variable precision.
Definition: util_io.cc:149
EST_String file_type() const
Definition: EST_Wave.h:166
EST_UItem * next()
Definition: EST_UList.h:55
EST_String options_wave_output(void)
void set_channel(ssize_t n, const short *buf, int offset=0, ssize_t num=EST_ALL)
Definition: EST_Wave.h:221
EST_String options_subwave(void)
INLINE short & a_no_check(ssize_t i, ssize_t channel=0)
Definition: EST_Wave.h:105
#define FALSE
Definition: EST_bool.h:119
#define EST_error
Definition: EST_error.h:104
void copy_channel(ssize_t n, short *buf, int offset=0, ssize_t num=EST_ALL) const
Definition: EST_Wave.h:216
getString int
Definition: EST_item_aux.cc:50
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:196
#define Declare_TNamedEnum(ENUM)
int length() const
Definition: EST_UList.cc:57
void resize(int num_samples, int num_channels=EST_ALL, int set=1)
resize the waveform
Definition: EST_Wave.h:184
void reverse(EST_Wave &sig)
int sample_rate() const
return the sampling rate (frequency)
Definition: EST_Wave.h:147
void wave_combine_channels(EST_Wave &s, const EST_Wave &m)
#define Gof(a, b)
Definition: EST_cutils.h:95
void differentiate(EST_Wave &sig)
Definition: EST_wave_aux.cc:76
int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
ssize_t num_channels() const
return the number of channels in the waveform
Definition: EST_Wave.h:145
EST_sample_type_t
Definition: EST_wave_aux.h:105
EST_UItem * head() const
Definition: EST_UList.h:97
EST_String
void extract(EST_Wave &sig, EST_Option &al)
EST_String options_wave_input(void)
float sum(const EST_FMatrix &a)
sum of elements
Definition: vec_mat_aux.cc:147
EST_String sample_type() const
Definition: EST_Wave.h:163
#define Instantiate_TNamedEnum(ENUM)
Utility EST_String Functions header file.