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 /* */ 34 /* Author : Paul Taylor and Alan W Black */ 35 /* Rewritten : Richard Caley */ 36 /* ------------------------------------------------------------------- */ 37 /* EST_Wave Class header file */ 38 /* */ 39 /*************************************************************************/ 40 41 #ifndef __Wave_H__ 42 #define __Wave_H__ 43 44 #include <cstdio> 45 #include "EST_Featured.h" 46 #include "EST_rw_status.h" 47 #include "EST_types.h" 48 49 class EST_Track; 50 class EST_String; 51 class EST_TokenStream; 52 53 54 /** A class for storing digital waveforms. The waveform is stored as 55 an array of 16 bit shorts. Multiple channels are supported, but if no 56 channel information is given the 0th channel is accessed. 57 <p> 58 59 The waveforms can be of any sample rate, and can be changed to another 60 sampling rate using the <tt>resample</tt> function. 61 62 */ 63 64 class EST_Wave : public EST_Featured 65 { 66 protected: 67 EST_SMatrix p_values; 68 69 int p_sample_rate; 70 71 void default_vals(int n=0, int c=1); 72 void free_wave(); 73 void copy_data(const EST_Wave &w); 74 void copy_setup(const EST_Wave &w); 75 76 public: 77 78 static const int default_sample_rate; 79 static const int default_num_channels; 80 81 /// default constructor 82 EST_Wave(); 83 /// copy constructor 84 EST_Wave(const EST_Wave &a); 85 86 EST_Wave(int n, int c, int sr); 87 88 /// Construct from memory supplied by caller 89 EST_Wave(int samps, int chans, 90 short *memory, int offset=0, int sample_rate=default_sample_rate, 91 int free_when_destroyed=0); 92 93 ~EST_Wave(); 94 95 96 /**@name Access functions for finding amplitudes of samples */ 97 //@{ 98 99 /** return amplitude of sample <tt>i</tt> from channel <tt> 100 channel</tt>. By default the 0th channel is selected. This 101 function can be used for assignment. 102 */ 103 short &a(int i, int channel = 0); 104 short a(int i, int channel = 0) const; 105 INLINE short &a_no_check(int i, int channel = 0) 106 { return p_values.a_no_check(i,channel); } 107 INLINE short a_no_check(int i, int channel = 0) const 108 { return p_values.a_no_check(i,channel); } 109 INLINE short &a_no_check_1(int i, int channel = 0) 110 { return p_values.a_no_check_1(i,channel); } 111 INLINE short a_no_check_1(int i, int channel = 0) const 112 { return p_values.a_no_check_1(i,channel); } 113 114 115 /** explicit set_a, easier to wrap than assignment 116 */ 117 INLINE short set_a(int i, int channel = 0, short val = 0) 118 { return a(i,channel) = val; } 119 120 /** return amplitude of sample <tt>i</tt> from channel <tt> 121 channel</tt>. By default the 0th channel is selected. 122 */ operator()123 short operator()(int i, int channel) const 124 { return a(i,channel); } 125 126 /** return amplitude of sample <tt>i</tt> from channel 0. 127 */ operator()128 short operator()(int i) const 129 { return a(i,0); } 130 131 /** Version of a() that returns zero if index is out of array 132 bounds. This is particularly useful in signal processing when 133 you want to have windows going off the end of the waveform. */ 134 short &a_safe(int i, int channel = 0); 135 136 /// return the time position in seconds of the ith sample t(int i)137 float t(int i) const { return (float)i/(float)p_sample_rate; } 138 //@} 139 140 /**@name Information functions */ 141 //@{ 142 /// return the number of samples in the waveform num_samples()143 int num_samples() const { return p_values.num_rows();} 144 /// return the number of channels in the waveform num_channels()145 int num_channels() const { return p_values.num_columns(); } 146 /// return the sampling rate (frequency) sample_rate()147 int sample_rate() const { return p_sample_rate; } 148 /// Set sampling rate to <tt>n</tt> set_sample_rate(const int n)149 void set_sample_rate(const int n){p_sample_rate = n;} 150 /// return the size of the waveform, i.e. the number of samples. length()151 int length() const { return num_samples();} 152 /// return the time position of the last sample. end()153 float end(){ return t(num_samples()-1); } 154 155 /// Can we look N samples to the left? have_left_context(unsigned int n)156 bool have_left_context(unsigned int n) const 157 { return p_values.have_rows_before(n); } 158 159 /** returns the file format of the file from which the waveform 160 was read. If the waveform has not been read from a file, this is set 161 to the default type */ 162 sample_type()163 EST_String sample_type() const { return f_String("sample_type","short"); } set_sample_type(const EST_String t)164 void set_sample_type(const EST_String t) { f_set("sample_type", t); } 165 file_type()166 EST_String file_type() const { return f_String("file_type","riff"); } set_file_type(const EST_String t)167 void set_file_type(const EST_String t) { f_set("file_type", t); } 168 169 /// A string identifying the waveform, commonly used to store the filename name()170 EST_String name() const { return f_String("name"); } 171 172 /// Sets name. set_name(const EST_String n)173 void set_name(const EST_String n){ f_set("name", n); } 174 175 //@} 176 values()177 const EST_SMatrix &values() const { return p_values; } values()178 EST_SMatrix &values() { return p_values; } 179 180 /**@name Waveform manipulation functions */ 181 //@{ 182 183 /// resize the waveform 184 void resize(int num_samples, int num_channels = EST_ALL, int set=1) 185 { p_values.resize(num_samples, num_channels, set); } 186 187 /// Resample waveform to <tt>rate</tt> 188 void resample(int rate); 189 190 /** multiply all samples by a factor <tt>gain</tt>. This checks for 191 overflows and puts them to the maximum positive or negative value 192 as appropriate. 193 */ 194 void rescale(float gain,int normalize=0); 195 196 // multiply samples by a factor contour. The factor_contour track 197 // should contains factor targets at time points throughout the wave, 198 // between which linear interpolation is used to calculate the factor 199 // for each sample. 200 void rescale( const EST_Track &factor_contour ); 201 202 /// clear waveform and set size to 0. clear()203 void clear() {resize(0,EST_ALL);} 204 205 void copy(const EST_Wave &from); 206 207 void fill(short v=0, int channel=EST_ALL); 208 209 void empty(int channel=EST_ALL) { fill(0,channel); } 210 sample(EST_TVector<short> & sv,int n)211 void sample(EST_TVector<short> &sv, int n) 212 { p_values.row(sv, n); } channel(EST_TVector<short> & cv,int n)213 void channel(EST_TVector<short> &cv, int n) 214 { p_values.column(cv, n); } 215 216 void copy_channel(int n, short *buf, int offset=0, int num=EST_ALL) const 217 { p_values.copy_column(n, buf, offset, num); } 218 void copy_sample(int n, short *buf, int offset=0, int num=EST_ALL) const 219 { p_values.copy_row(n, buf, offset, num); } 220 221 void set_channel(int n, const short *buf, int offset=0, int num=EST_ALL) 222 { p_values.set_column(n, buf, offset, num); } 223 void set_sample(int n, const short *buf, int offset=0, int num=EST_ALL) 224 { p_values.set_row(n, buf, offset, num); } 225 226 227 void sub_wave(EST_Wave &sw, 228 int offset=0, int num=EST_ALL, 229 int start_c=0, int nchan=EST_ALL); 230 231 void sub_wave(EST_Wave &sw, 232 int offset=0, int num=EST_ALL, 233 int start_c=0, int nchan=EST_ALL) const 234 { ((EST_Wave *)this)->sub_wave(sw, offset, num, start_c, nchan); } 235 236 //@} 237 238 /**@name File i/o functions */ 239 //@{ 240 241 /** Load a file into the waveform. The load routine attempts to 242 automatically determine which file type is being loaded. A 243 portion of the waveform can be loaded by setting <tt> 244 offset</tt> to the sample position from the beginning and 245 <length> to the number of required samples after this. */ 246 247 EST_read_status load(const EST_String filename, 248 int offset=0, 249 int length = 0, 250 int rate = default_sample_rate); 251 252 EST_read_status load(EST_TokenStream &ts, 253 int offset=0, 254 int length = 0, 255 int rate = default_sample_rate); 256 257 EST_read_status load(const EST_String filename, 258 const EST_String filetype, 259 int offset=0, 260 int length = 0, 261 int rate = default_sample_rate); 262 263 EST_read_status load(EST_TokenStream &ts, 264 const EST_String filetype, 265 int offset=0, 266 int length = 0, 267 int rate = default_sample_rate); 268 269 /** Load a file of type <tt>filetype</tt> into the waveform. This 270 can be used to load unheadered files, in which case the fields 271 <tt>sample_rate, sample_type, bo</tt> and <tt>nc</tt> are used 272 to specify the sample rate, type, byte order and number of 273 channels. A portion of the waveform can be loaded by setting 274 <tt> offset</tt> to the sample position from the beginning and 275 <length> to the number of required samples after this. 276 */ 277 278 EST_read_status load_file(const EST_String filename, 279 const EST_String filetype, int sample_rate, 280 const EST_String sample_type, int bo, int nc, 281 int offset = 0, int length = 0); 282 EST_read_status load_file(EST_TokenStream &ts, 283 const EST_String filetype, int sample_rate, 284 const EST_String sample_type, int bo, int nc, 285 int offset = 0, int length = 0); 286 287 /* Save waveform to a file called <tt>filename</tt> of file 288 format <tt>EST_filetype</tt>. 289 */ 290 EST_write_status save(const EST_String filename, 291 const EST_String EST_filetype = ""); 292 293 EST_write_status save(FILE *fp, 294 const EST_String EST_filetype = ""); 295 296 EST_write_status save_file(const EST_String filename, 297 EST_String filetype, 298 EST_String sample_type, int bo); 299 300 EST_write_status save_file(FILE *fp, 301 EST_String filetype, 302 EST_String sample_type, int bo); 303 //@} 304 305 /// Assignment operator 306 EST_Wave& operator = (const EST_Wave& w); 307 /** Add to existing wave in serial. Waveforms must have the same 308 number of channels. 309 */ 310 EST_Wave& operator +=(const EST_Wave &a); 311 /** Add wave in parallel, i.e. make wave <tt>a</tt> become new 312 channels in existing waveform. 313 */ 314 EST_Wave& operator |=(const EST_Wave &a); 315 316 /// print waveform 317 friend ostream& operator << (ostream& p_values, const EST_Wave &sig); 318 319 // integrity check *** debug integrity()320 void integrity() const { p_values.integrity() ; } 321 322 }; 323 324 typedef EST_TList<EST_Wave> EST_WaveList; 325 326 int operator != (EST_Wave a, EST_Wave b); 327 int operator == (EST_Wave a, EST_Wave b); 328 329 #endif /* __Wave_H__ */ 330