Edinburgh Speech Tools  2.4-release
EST_Wave.cc
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 : May 1996 */
35 /*-----------------------------------------------------------------------*/
36 /* EST_Wave Class source file */
37 /* */
38 /*=======================================================================*/
39 
40 #include <iostream>
41 #include <cstdlib>
42 #include <cstdio>
43 #include <cmath>
44 #include <cstring>
45 #include "EST_cutils.h"
46 #include "EST_Wave.h"
47 #include "EST_wave_utils.h"
48 #include "EST_wave_aux.h"
49 #include "EST_TNamedEnum.h"
50 #include "EST_WaveFile.h"
51 
52 #include "EST_Track.h"
53 
54 #include "waveP.h"
55 
56 #define sgn(x) (x>0?1:x?-1:0)
57 
58 const EST_String DEF_FILE_TYPE = "riff";
59 const EST_String DEF_SAMPLE_TYPE = "short";
60 
61 const int EST_Wave::default_sample_rate=16000;
62 
64 {
65  default_vals();
66 }
67 
69 {
70  default_vals();
71  copy(w);
72 }
73 
74 EST_Wave::EST_Wave(int n, int c, int sr)
75 {
76  default_vals(n,c);
77  set_sample_rate(sr);
78 }
79 
80 EST_Wave::EST_Wave(int samps, int chans,
81  short *memory, int offset, int sample_rate,
82  int free_when_destroyed)
83 {
84  default_vals();
85  p_values.set_memory(memory, offset, samps, chans, free_when_destroyed);
87 }
88 
89 void EST_Wave::default_vals(int n, int c)
90 {
91  // real defaults
92  p_values.resize(n,c);
93  p_sample_rate = default_sample_rate;
94 
95  init_features();
96 }
97 
98 void EST_Wave::free_wave()
99 {
100  if (!p_values.p_sub_matrix)
101  p_values.resize(0,0);
102  clear_features();
103 }
104 
105 EST_Wave::~EST_Wave()
106 {
107  free_wave();
108 }
109 
110 void EST_Wave::copy_setup(const EST_Wave &w)
111 {
112  p_sample_rate = w.p_sample_rate;
113  copy_features(w);
114 }
115 
116 void EST_Wave::copy_data(const EST_Wave &w)
117 {
118  p_values.copy(w.p_values);
119 }
120 
121 void EST_Wave::copy(const EST_Wave &w)
122 {
123  copy_setup(w);
124 
125  copy_data(w);
126 }
127 
128 short &EST_Wave::a(int i, int channel)
129 {
130  if (i<0 || i>= num_samples())
131  {
132  cerr << "Attempt to access sample " << i << " of a " << num_samples() << " sample wave.\n";
133  if (num_samples()>0)
134  return *(p_values.error_return);
135  }
136 
137  if (channel<0 || channel>= num_channels())
138  {
139  cerr << "Attempt to access channel " << channel << " of a " << num_channels() << " channel wave.\n";
140  if (num_samples()>0)
141  return *(p_values.error_return);
142  }
143 
144  return p_values.a_no_check(i,channel);
145 }
146 
147 short EST_Wave::a(int i, int channel) const
148 {
149  return ((EST_Wave *)this)->a(i,channel);
150 }
151 
152 short &EST_Wave::a_safe(int i, int channel)
153 {
154  static short out_of_bound_value = 0;
155 
156  if ((i < 0) || (i >= num_samples()))
157  { // need to give them something but they might have changed it
158  // so reinitialise it to 0 first
159  out_of_bound_value = 0;
160  return out_of_bound_value;
161  }
162  else
163  return a_no_check(i,channel);
164 }
165 
166 void EST_Wave::fill(short v, int channel)
167 {
168  if (channel == EST_ALL)
169  {
170  if (v == 0) // this is *much* more efficient and common
171  memset(values().memory(),0,num_samples()*num_channels()*2);
172  else
173  p_values.fill(v);
174  }
175  else
176  for (int i = 0; i < num_samples(); ++i)
177  p_values.a_no_check(i,channel) = v;
178 }
179 
180 EST_read_status EST_Wave::load(const EST_String filename,
181  int offset, int length,
182  int rate)
183 {
184  EST_read_status stat = read_error;
185  EST_TokenStream ts;
186 
187  if ((ts.open(filename)) == -1)
188  {
189  cerr << "Wave load: can't open file \"" << filename << "\"" << endl;
190  return stat;
191  }
192 
193  stat = load(ts,offset,length,rate);
194  ts.close();
195  return stat;
196 }
197 
198 EST_read_status EST_Wave::load(EST_TokenStream &ts,
199  int offset, int length,
200  int rate)
201 {
202  EST_read_status stat = read_error;
203  int pos = ts.tell();
204 
205  for(int n=0; n< EST_WaveFile::map.n() ; n++)
206  {
207  EST_WaveFileType t = EST_WaveFile::map.token(n);
208 
209  if (t == wff_none)
210  continue;
211 
212  EST_WaveFile::Info *info = &(EST_WaveFile::map.info(t));
213 
214  if (! info->recognise)
215  continue;
216 
217  EST_WaveFile::Load_TokenStream * l_fun =info->load;
218 
219  if (l_fun == NULL)
220  continue;
221 
222  ts.seek(pos);
223  stat = (*l_fun)(ts, *this,
224  rate, st_short, EST_NATIVE_BO, 1,
225  offset, length);
226 
227  if (stat == read_ok)
228  {
229  set_file_type(EST_WaveFile::map.value(t));
230  break;
231  }
232  else if (stat == read_error)
233  break;
234  }
235 
236  return stat;
237 }
238 
239 EST_read_status EST_Wave::load(const EST_String filename,
240  const EST_String type,
241  int offset, int length,
242  int rate)
243 {
244  EST_read_status stat = read_error;
245  EST_TokenStream ts;
246 
247  if (filename == "-")
248  ts.open(stdin,FALSE);
249  else if ((ts.open(filename)) == -1)
250  {
251  cerr << "Wave load: can't open file \"" << filename << "\"" << endl;
252  return stat;
253  }
254 
255  stat = load(ts,type,offset,length,rate);
256  ts.close();
257  return stat;
258 }
259 
260 EST_read_status EST_Wave::load(EST_TokenStream &ts,
261  const EST_String type,
262  int offset, int length,
263  int rate)
264 {
265  EST_WaveFileType t = EST_WaveFile::map.token(type);
266 
267  if (t == wff_none)
268  {
269  cerr << "Unknown Wave file type " << type << endl;
270  return read_error;
271  }
272 
273  EST_WaveFile::Load_TokenStream * l_fun = EST_WaveFile::map.info(t).load;
274 
275  if (l_fun == NULL)
276  {
277  cerr << "Can't load waves to files type " << type << endl;
278  return read_error;
279  }
280 
281  set_file_type(EST_WaveFile::map.value(t));
282  return (*l_fun)(ts, *this,
283  rate, st_short, EST_NATIVE_BO, 1,
284  offset, length);
285 
286 }
287 
288 EST_read_status EST_Wave::load_file(const EST_String filename,
289  const EST_String type, int sample_rate,
290  const EST_String stype, int bov, int nc, int offset,
291  int length)
292 {
293  EST_read_status stat = read_error;
294  EST_TokenStream ts;
295 
296  if (filename == "-")
297  ts.open(stdin,FALSE);
298  else if ((ts.open(filename)) == -1)
299  {
300  cerr << "Wave load: can't open file \"" << filename << "\"" << endl;
301  return stat;
302  }
303 
304  stat = load_file(ts,type,sample_rate,stype,bov,nc,offset,length);
305  ts.close();
306  return stat;
307 }
308 
309 EST_read_status EST_Wave::load_file(EST_TokenStream &ts,
310  const EST_String type, int sample_rate,
311  const EST_String stype, int bov, int nc, int offset,
312  int length)
313 
314 {
315  EST_WaveFileType t = EST_WaveFile::map.token(type);
316 
317  EST_sample_type_t values_type = EST_sample_type_map.token(stype);
318 
319  if (t == wff_none)
320  {
321  cerr << "Unknown Wave file type " << type << endl;
322  return read_error;
323  }
324 
325  EST_WaveFile::Load_TokenStream * l_fun = EST_WaveFile::map.info(t).load;
326 
327  if (l_fun == NULL)
328  {
329  cerr << "Can't load waves to files type " << type << endl;
330  return read_error;
331  }
332 
333  return (*l_fun)(ts, *this,
334  sample_rate, values_type, bov, nc,
335  offset, length);
336 
337 }
338 
339 void EST_Wave::sub_wave(EST_Wave &sw,
340  int offset, int num,
341  int start_c, int nchan)
342 {
343  if (num == EST_ALL)
344  num = num_samples()-offset;
345  if (nchan == EST_ALL)
346  nchan = num_channels()-start_c;
347 
348  p_values.sub_matrix(sw.p_values, offset, num, start_c, nchan);
350 }
351 
352 EST_write_status EST_Wave::save(const EST_String filename,
353  const EST_String type)
354 {
355  FILE *fp;
356 
357  if (filename == "-")
358  fp = stdout;
359  else if ((fp = fopen(filename,"wb")) == NULL)
360  {
361  cerr << "Wave save: can't open output file \"" <<
362  filename << "\"" << endl;
363  return write_fail;
364  }
365 
366  EST_write_status r = save(fp,type);
367  if (fp != stdout)
368  fclose(fp);
369  return r;
370 }
371 
372 EST_write_status EST_Wave::save(FILE *fp, const EST_String type)
373 {
374  EST_String save_type = (type == "") ? DEF_FILE_TYPE : type;
375 
376  EST_WaveFileType t = EST_WaveFile::map.token(save_type);
377 
378  if (t == wff_none)
379  {
380  cerr << "Wave: unknown filetype in saving " << save_type << endl;
381  return write_fail;
382  }
383 
384  EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save;
385 
386  if (s_fun == NULL)
387  {
388  cerr << "Can't save waves to files type " << save_type << endl;
389  return write_fail;
390  }
391 
392  return (*s_fun)(fp, *this, st_short, EST_NATIVE_BO);
393 }
394 
395 EST_write_status EST_Wave::save_file(const EST_String filename,
396  EST_String ftype,
397  EST_String stype, int obo, const char *mode)
398 {
399  FILE *fp;
400 
401  if (filename == "-")
402  fp = stdout;
403  else if ((fp = fopen(filename, mode)) == NULL)
404  {
405  cerr << "Wave save: can't open output file \"" <<
406  filename << "\"" << endl;
407  return write_fail;
408  }
409 
410  EST_write_status r = save_file(fp,ftype,stype,obo);
411  if (fp != stdout)
412  fclose(fp);
413  return r;
414 }
415 
416 EST_write_status EST_Wave::save_file(FILE *fp,
417  EST_String ftype,
418  EST_String stype, int obo)
419 {
420  EST_WaveFileType t = EST_WaveFile::map.token(ftype);
421  EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
422 
423  if (t == wff_none)
424  {
425  cerr << "Unknown Wave file type " << ftype << endl;
426  return write_fail;
427  }
428 
429  EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save;
430 
431  if (s_fun == NULL)
432  {
433  cerr << "Can't save waves to files type " << ftype << endl;
434  return write_fail;
435  }
436 
437  return (*s_fun)(fp, *this, sample_type, obo);
438 }
439 
440 EST_write_status EST_Wave::save_file_data(FILE *fp,
441  EST_String ftype,
442  EST_String stype, int obo)
443 {
444  EST_WaveFileType t = EST_WaveFile::map.token(ftype);
445  EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
446 
447  if (t == wff_none)
448  {
449  cerr << "Unknown Wave file type " << ftype << endl;
450  return write_fail;
451  }
452 
453  EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save_data;
454 
455  if (s_fun == NULL)
456  {
457  cerr << "Can't save wave data to files type " << ftype << endl;
458  return write_fail;
459  }
460 
461  return (*s_fun)(fp, *this, sample_type, obo);
462 }
463 
464 
465 EST_write_status EST_Wave::save_file_header(FILE *fp,
466  EST_String ftype,
467  EST_String stype, int obo)
468 {
469  EST_WaveFileType t = EST_WaveFile::map.token(ftype);
470  EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
471 
472  if (t == wff_none)
473  {
474  cerr << "Unknown Wave file type " << ftype << endl;
475  return write_fail;
476  }
477 
478  EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save_header;
479 
480  if (s_fun == NULL)
481  {
482  cerr << "Can't save wave header to files type " << ftype << endl;
483  return write_fail;
484  }
485 
486  return (*s_fun)(fp, *this, sample_type, obo);
487 }
488 
489 void EST_Wave::resample(int new_freq)
490 {
491  // Resample wave to new sample rate
492  if (new_freq != p_sample_rate)
493  {
494  if (p_values.rateconv(p_sample_rate, new_freq) != 0)
495  cerr << "rateconv: failed to convert from " << p_sample_rate <<
496  " to " << new_freq << "\n";
497  else
498  set_sample_rate(new_freq);
499  }
500 
501 }
502 
503 void EST_Wave::compress(float mu, float lim)
504 {
505  int x;
506 
507  for (int i = 0; i < num_samples(); ++i)
508  {
509  for (int j = 0; j< num_channels(); ++j)
510  {
511  x = a_no_check(i,j);
512  a_no_check(i,j) = lim * (sgn(x)*(log(1+(mu/lim)*abs(x))/log(1+mu)));
513  }
514  }
515 }
516 
517 void EST_Wave::rescale(float gain, int normalize)
518 {
519  int ns;
520  float factor = gain;
521  float nsf;
522 
523  if (normalize)
524  {
525  int max = 0;
526  for (int i = 0; i < num_samples(); ++i)
527  for (int j = 0; j < num_channels(); ++j)
528  if (abs(a_no_check(i,j)) > max)
529  max = abs(a_no_check(i,j));
530  if (fabs(max/32766.0-gain) < 0.001)
531  return; /* already normalized */
532  else
533  factor *= 32766.0/(float)max;
534  }
535 
536  for (int i = 0; i < num_samples(); ++i)
537  for (int j = 0; j < num_channels(); ++j)
538  {
539  if (factor == 1.0)
540  ns = a_no_check(i,j); // avoid float fluctuations
541  else if (factor == -1.0)
542  ns = -a_no_check(i,j); // avoid float fluctuations
543  else
544  {
545  nsf = (float)a_no_check(i,j) * factor;
546  if (nsf < 0.0)
547  ns = (int)(nsf - 0.5);
548  else
549  ns = (int)(nsf + 0.5);
550  }
551  if (ns < -32766)
552  a_no_check(i,j)= -32766;
553  else if (ns > 32766)
554  a_no_check(i,j)= 32766;
555  else
556  a_no_check(i,j)= ns;
557  }
558 }
559 
560 void EST_Wave::rescale( const EST_Track &fc )
561 {
562  int ns, start_sample, end_sample;
563  float target1, target2, increment, factor, nsf;
564 
565  int fc_length = fc.length();
566  int _num_channels = num_channels();
567 
568  cerr << ((int)(fc.t(fc_length-1) * p_sample_rate)) << endl;
569 
570  if( ((int)(fc.t(fc_length-1) * p_sample_rate)) > num_samples() )
571  EST_error( "Factor contour track exceeds waveform length (%d samples)",
572  (fc.t(fc_length-1) * p_sample_rate) - num_samples() );
573 
574  start_sample = static_cast<unsigned int>( fc.t( 0 )*p_sample_rate );
575  target1 = fc.a(0,0); // could use separate channels for each waveform channel
576 
577  for ( int k = 1; k<fc_length; ++k ){
578  end_sample = static_cast<unsigned int>( fc.t( k )*p_sample_rate );
579  target2 = fc.a(k);
580 
581  increment = (target2-target1)/(end_sample-start_sample+1);
582 
583  factor = target1;
584  for( int i=start_sample; i<end_sample; ++i, factor+=increment )
585  for( int j=0; j<_num_channels; ++j ){
586  if (factor == 1.0)
587  ns = a_no_check(i,j); // avoid float fluctuations
588  else if (factor == -1.0)
589  ns = -a_no_check(i,j); // avoid float fluctuations
590  else
591  {
592  nsf = (float)a_no_check(i,j) * factor;
593  if (nsf < 0.0)
594  ns = (int)(nsf - 0.5);
595  else
596  ns = (int)(nsf + 0.5);
597  }
598  if (ns < -32766)
599  a_no_check(i,j)= -32766;
600  else if (ns > 32766)
601  a_no_check(i,j)= 32766;
602  else
603  a_no_check(i,j)= ns;
604  }
605  start_sample = end_sample;
606  target1 = target2;
607  }
608 }
609 
610 
611 
613 {
614  copy(w);
615  return *this;
616 }
617 
619 {
620  EST_Wave w2;
621  const EST_Wave *toadd = &w;
622 
623  if (w.num_channels() != num_channels())
624  {
625  cerr << "Cannot concatenate waveforms with differing numbers of channels\n";
626  return *this;
627  }
628 
629  if (p_sample_rate != w.sample_rate())
630  {
631  w2 = w;
632  w2.resample(p_sample_rate);
633  toadd= &w2;
634  }
635 
636  p_values.add_rows(toadd->p_values);
637 
638  return *this;
639 }
640 
641 // add wave p_values to existing wave in parallel to create multi-channel wave.
643 {
644  int i, k;
645  EST_Wave w = wi; // to allow resampling of const
646 
647  w.resample(p_sample_rate); // far too difficult otherwise
648 
649  int o_channels = num_channels();
650  int r_channels = num_channels()+w.num_channels();
651  int r_samples = Gof(num_samples(), w.num_samples());
652 
653  resize(r_samples, r_channels);
654 
655  for (k = 0; k < w.num_channels(); ++k)
656  for (i=0; i < w.num_samples(); i++)
657  a(i,k+o_channels) += w.a(i, k);
658 
659  return *this;
660 }
661 
662 ostream& operator << (ostream& p_values, const EST_Wave &sig)
663 {
664  for (int i = 0; i < sig.num_samples(); ++i)
665  p_values << sig(i) << "\n";
666 
667  return p_values;
668 }
669 
670 int operator != (EST_Wave a, EST_Wave b)
671  { (void)a; (void)b; return 1; }
672 int operator == (EST_Wave a, EST_Wave b)
673  { (void)a; (void)b; return 0; }
EST_Wave::sample_rate
int sample_rate() const
return the sampling rate (frequency)
Definition: EST_Wave.h:147
EST_TMatrix::a_no_check
const INLINE T & a_no_check(int row, int col) const
const access with no bounds check, care recommend
Definition: EST_TMatrix.h:184
EST_Wave::a_safe
short & a_safe(int i, int channel=0)
Definition: EST_Wave.cc:152
EST_Wave
Definition: EST_Wave.h:64
EST_TMatrix::fill
void fill(const T &v)
fill matrix with value v
Definition: EST_TMatrix.cc:314
EST_Wave::num_channels
int num_channels() const
return the number of channels in the waveform
Definition: EST_Wave.h:145
EST_Track::t
float & t(int i=0)
return time position of frame i
Definition: EST_Track.h:477
EST_Track::length
int length() const
return number of frames in track
Definition: EST_Track.h:653
EST_TSimpleMatrix::copy
void copy(const EST_TSimpleMatrix< T > &a)
copy one matrix into another
Definition: EST_TSimpleMatrix.cc:71
EST_Wave::resize
void resize(int num_samples, int num_channels=EST_ALL, int set=1)
resize the waveform
Definition: EST_Wave.h:184
EST_Wave::length
int length() const
return the size of the waveform, i.e. the number of samples.
Definition: EST_Wave.h:151
EST_TMatrix::set_memory
void set_memory(T *buffer, int offset, int rows, int columns, int free_when_destroyed=0)
Definition: EST_TMatrix.cc:371
EST_TMatrix::add_rows
EST_TMatrix & add_rows(const EST_TMatrix &s)
The two versions of what might have been operator +=.
Definition: EST_TMatrix.cc:167
EST_Wave::operator+=
EST_Wave & operator+=(const EST_Wave &a)
Definition: EST_Wave.cc:618
EST_Wave::t
float t(int i) const
return the time position in seconds of the ith sample
Definition: EST_Wave.h:137
EST_TokenStream
Definition: EST_Token.h:235
EST_Wave::num_samples
int num_samples() const
return the number of samples in the waveform
Definition: EST_Wave.h:143
EST_Track::a
float & a(int i, int c=0)
Definition: EST_Track.cc:1022
EST_Wave::rescale
void rescale(float gain, int normalize=0)
Definition: EST_Wave.cc:517
EST_Wave::EST_Wave
EST_Wave()
default constructor
Definition: EST_Wave.cc:63
EST_TVector::error_return
static T * error_return
Definition: EST_TVector.h:230
EST_Wave::a
short & a(int i, int channel=0)
Definition: EST_Wave.cc:128
EST_Wave::sample_type
EST_String sample_type() const
Definition: EST_Wave.h:163
EST_TokenStream::close
void close(void)
Close stream.
Definition: EST_Token.cc:406
EST_TSimpleMatrix::resize
void resize(int rows, int cols, int set=1)
resize matrix
Definition: EST_TSimpleMatrix.cc:86
EST_TokenStream::open
int open(const EST_String &filename)
open a \Ref{EST_TokenStream} for a file.
Definition: EST_Token.cc:200
EST_TokenStream::seek
int seek(int position)
seek, reposition file pointer
Definition: EST_Token.cc:305
EST_Wave::operator=
EST_Wave & operator=(const EST_Wave &w)
Assignment operator.
Definition: EST_Wave.cc:612
EST_Wave::load_file
EST_read_status load_file(const EST_String filename, const EST_String filetype, int sample_rate, const EST_String sample_type, int bo, int nc, int offset=0, int length=0)
Definition: EST_Wave.cc:288
EST_String
Definition: EST_String.h:70
EST_Wave::set_sample_rate
void set_sample_rate(const int n)
Set sampling rate to n
Definition: EST_Wave.h:149
EST_TMatrix::sub_matrix
void sub_matrix(EST_TMatrix< T > &sm, int r=0, int numr=EST_ALL, int c=0, int numc=EST_ALL)
Make the matrix {\tt sm} a window into this matrix.
Definition: EST_TMatrix.cc:578
EST_Track
Definition: EST_Track.h:89
EST_TokenStream::tell
int tell(void) const
tell, synonym for filepos
Definition: EST_Token.h:363
EST_Wave::load
EST_read_status load(const EST_String filename, int offset=0, int length=0, int rate=default_sample_rate)
Definition: EST_Wave.cc:180
EST_Wave::compress
void compress(float mu, float limit)
Dynamic Range Compression - SaiKrishna May 2017.
Definition: EST_Wave.cc:503
EST_Wave::resample
void resample(int rate)
Resample waveform to rate
Definition: EST_Wave.cc:489
EST_Wave::operator|=
EST_Wave & operator|=(const EST_Wave &a)
Definition: EST_Wave.cc:642