45 #include "EST_cutils.h"
47 #include "EST_wave_utils.h"
48 #include "EST_wave_aux.h"
49 #include "EST_TNamedEnum.h"
50 #include "EST_WaveFile.h"
52 #include "EST_Track.h"
59 const int EST_Wave::default_sample_rate=16000;
79 short *memory,
int offset,
int sample_rate,
80 int free_when_destroyed)
83 p_values.
set_memory(memory, offset, samps, chans, free_when_destroyed);
87 void EST_Wave::default_vals(
int n,
int c)
91 p_sample_rate = default_sample_rate;
96 void EST_Wave::free_wave()
98 if (!p_values.p_sub_matrix)
103 EST_Wave::~EST_Wave()
108 void EST_Wave::copy_setup(
const EST_Wave &w)
110 p_sample_rate = w.p_sample_rate;
114 void EST_Wave::copy_data(
const EST_Wave &w)
116 p_values.
copy(w.p_values);
119 void EST_Wave::copy(
const EST_Wave &w)
130 cerr <<
"Attempt to access sample " << i <<
" of a " <<
num_samples() <<
" sample wave.\n";
137 cerr <<
"Attempt to access channel " << channel <<
" of a " <<
num_channels() <<
" channel wave.\n";
147 return ((
EST_Wave *)
this)->a(i,channel);
152 static short out_of_bound_value = 0;
157 out_of_bound_value = 0;
158 return out_of_bound_value;
161 return a_no_check(i,channel);
164 void EST_Wave::fill(
short v,
int channel)
166 if (channel == EST_ALL)
179 int offset,
int length,
182 EST_read_status stat = read_error;
185 if ((ts.
open(filename)) == -1)
187 cerr <<
"Wave load: can't open file \"" << filename <<
"\"" << endl;
191 stat =
load(ts,offset,length,rate);
197 int offset,
int length,
200 EST_read_status stat = read_error;
203 for(
int n=0; n< EST_WaveFile::map.n() ; n++)
205 EST_WaveFileType
t = EST_WaveFile::map.token(n);
210 EST_WaveFile::Info *info = &(EST_WaveFile::map.info(t));
212 if (! info->recognise)
215 EST_WaveFile::Load_TokenStream * l_fun =info->load;
221 stat = (*l_fun)(ts, *
this,
222 rate, st_short, EST_NATIVE_BO, 1,
227 set_file_type(EST_WaveFile::map.value(t));
230 else if (stat == read_error)
239 int offset,
int length,
242 EST_read_status stat = read_error;
246 ts.
open(stdin,FALSE);
247 else if ((ts.
open(filename)) == -1)
249 cerr <<
"Wave load: can't open file \"" << filename <<
"\"" << endl;
253 stat =
load(ts,type,offset,length,rate);
260 int offset,
int length,
263 EST_WaveFileType t = EST_WaveFile::map.token(type);
267 cerr <<
"Unknown Wave file type " << type << endl;
271 EST_WaveFile::Load_TokenStream * l_fun = EST_WaveFile::map.info(t).load;
275 cerr <<
"Can't load waves to files type " << type << endl;
279 set_file_type(EST_WaveFile::map.value(t));
280 return (*l_fun)(ts, *
this,
281 rate, st_short, EST_NATIVE_BO, 1,
288 const EST_String stype,
int bov,
int nc,
int offset,
291 EST_read_status stat = read_error;
295 ts.
open(stdin,FALSE);
296 else if ((ts.
open(filename)) == -1)
298 cerr <<
"Wave load: can't open file \"" << filename <<
"\"" << endl;
302 stat =
load_file(ts,type,sample_rate,stype,bov,nc,offset,length);
309 const EST_String stype,
int bov,
int nc,
int offset,
313 EST_WaveFileType t = EST_WaveFile::map.token(type);
315 EST_sample_type_t values_type = EST_sample_type_map.token(stype);
319 cerr <<
"Unknown Wave file type " << type << endl;
323 EST_WaveFile::Load_TokenStream * l_fun = EST_WaveFile::map.info(t).load;
327 cerr <<
"Can't load waves to files type " << type << endl;
331 return (*l_fun)(ts, *
this,
337 void EST_Wave::sub_wave(
EST_Wave &sw,
339 int start_c,
int nchan)
343 if (nchan == EST_ALL)
346 p_values.
sub_matrix(sw.p_values, offset, num, start_c, nchan);
357 else if ((fp = fopen(filename,
"wb")) == NULL)
359 cerr <<
"Wave save: can't open output file \"" <<
360 filename <<
"\"" << endl;
364 EST_write_status r =
save(fp,type);
372 EST_String save_type = (type ==
"") ? DEF_FILE_TYPE : type;
374 EST_WaveFileType t = EST_WaveFile::map.token(save_type);
378 cerr <<
"Wave: unknown filetype in saving " << save_type << endl;
382 EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save;
386 cerr <<
"Can't save waves to files type " << save_type << endl;
390 return (*s_fun)(fp, *
this, st_short, EST_NATIVE_BO);
393 EST_write_status EST_Wave::save_file(
const EST_String filename,
401 else if ((fp = fopen(filename, mode)) == NULL)
403 cerr <<
"Wave save: can't open output file \"" <<
404 filename <<
"\"" << endl;
408 EST_write_status r = save_file(fp,ftype,stype,obo);
414 EST_write_status EST_Wave::save_file(FILE *fp,
418 EST_WaveFileType t = EST_WaveFile::map.token(ftype);
419 EST_sample_type_t
sample_type = EST_sample_type_map.token(stype);
423 cerr <<
"Unknown Wave file type " << ftype << endl;
427 EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save;
431 cerr <<
"Can't save waves to files type " << ftype << endl;
438 EST_write_status EST_Wave::save_file_data(FILE *fp,
442 EST_WaveFileType t = EST_WaveFile::map.token(ftype);
443 EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
447 cerr <<
"Unknown Wave file type " << ftype << endl;
451 EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save_data;
455 cerr <<
"Can't save wave data to files type " << ftype << endl;
463 EST_write_status EST_Wave::save_file_header(FILE *fp,
467 EST_WaveFileType t = EST_WaveFile::map.token(ftype);
468 EST_sample_type_t sample_type = EST_sample_type_map.token(stype);
472 cerr <<
"Unknown Wave file type " << ftype << endl;
476 EST_WaveFile::Save_TokenStream * s_fun = EST_WaveFile::map.info(t).save_header;
480 cerr <<
"Can't save wave header to files type " << ftype << endl;
490 if (new_freq != p_sample_rate)
492 if (p_values.rateconv(p_sample_rate, new_freq) != 0)
493 cerr <<
"rateconv: failed to convert from " << p_sample_rate <<
494 " to " << new_freq <<
"\n";
511 if (abs(a_no_check(i,j)) > max)
512 max = abs(a_no_check(i,j));
513 if (fabs(max/32766.0-gain) < 0.001)
516 factor *= 32766.0/(float)max;
522 ns = (int)(((
float)a_no_check(i,j) * factor) + 0.5);
524 a_no_check(i,j)= -32766;
526 a_no_check(i,j)= 32766;
534 int ns, start_sample, end_sample;
535 float target1, target2, increment, factor;
537 int fc_length = fc.
length();
540 cerr << ((int)(fc.
t(fc_length-1) * p_sample_rate)) << endl;
542 if( ((
int)(fc.
t(fc_length-1) * p_sample_rate)) >
num_samples() )
543 EST_error(
"Factor contour track exceeds waveform length (%d samples)",
546 start_sample =
static_cast<unsigned int>( fc.
t( 0 )*p_sample_rate );
549 for (
int k = 1; k<fc_length; ++k ){
550 end_sample =
static_cast<unsigned int>( fc.
t( k )*p_sample_rate );
553 increment = (target2-target1)/(end_sample-start_sample+1);
556 for(
int i=start_sample; i<end_sample; ++i, factor+=increment )
557 for(
int j=0; j<_num_channels; ++j ){
558 ns = (int)(((
float)a_no_check(i,j) * factor) + 0.5);
560 a_no_check(i,j)= -32766;
562 a_no_check(i,j)= 32766;
566 start_sample = end_sample;
586 cerr <<
"Cannot concatenate waveforms with differing numbers of channels\n";
614 resize(r_samples, r_channels);
618 a(i,k+o_channels) += w.
a(i, k);
623 ostream& operator << (ostream& p_values,
const EST_Wave &sig)
626 p_values << sig(i) <<
"\n";
632 { (void)a; (void)b;
return 1; }
634 { (void)a; (void)b;
return 0; }
INLINE const T & a_no_check(int row, int col) const
const access with no bounds check, care recommend
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
EST_read_status load(const EST_String filename, int offset=0, int length=0, int rate=default_sample_rate)
EST_Wave & operator+=(const EST_Wave &a)
void set_sample_rate(const int n)
Set sampling rate to n
int length() const
return the size of the waveform, i.e. the number of samples.
float & t(int i=0)
return time position of frame i
int length() const
return number of frames in track
float & a(int i, int c=0)
EST_TMatrix & add_rows(const EST_TMatrix &s)
The two versions of what might have been operator +=.
void set_memory(T *buffer, int offset, int rows, int columns, int free_when_destroyed=0)
void close(void)
Close stream.
int tell(void) const
tell, synonym for filepos
void rescale(float gain, int normalize=0)
EST_write_status save(const EST_String filename, const EST_String EST_filetype="")
EST_Wave()
default constructor
EST_Wave & operator=(const EST_Wave &w)
Assignment operator.
int num_channels() const
return the number of channels in the waveform
int open(const EST_String &filename)
open a EST_TokenStream for a file.
float t(int i) const
return the time position in seconds of the ith sample
int num_samples() const
return the number of samples in the waveform
void fill(const T &v)
fill matrix with value v
short & a(int i, int channel=0)
void copy(const EST_TSimpleMatrix< T > &a)
copy one matrix into another
void sub_matrix(EST_TMatrix< T > &sm, int r=0, int numr=EST_ALL, int c=0, int numc=EST_ALL)
Make the matrix sm a window into this matrix.
void resize(int num_samples, int num_channels=EST_ALL, int set=1)
resize the waveform
short & a_safe(int i, int channel=0)
int sample_rate() const
return the sampling rate (frequency)
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)
void resize(int rows, int cols, int set=1)
resize matrix
EST_Wave & operator|=(const EST_Wave &a)
void resample(int rate)
Resample waveform to rate
EST_String sample_type() const
int seek(int position)
seek, reposition file pointer