IT++ Logo
audiosample.h
Go to the documentation of this file.
1 
29 #ifndef AUDIOSAMPLE_H
30 #define AUDIOSAMPLE_H
31 
32 #include <climits>
33 #include <itpp/base/ittypes.h>
34 #include <itpp/srccode/g711.h>
35 
48 namespace itpp
49 {
50 
58 enum Audio_Encoding {enc_unknown = 0, enc_mulaw8 = 1, enc_alaw8 = 27,
59  enc_linear8 = 2,enc_linear16 = 3,enc_linear24 = 4,
60  enc_linear32 = 5,enc_float = 6,enc_double = 7};
61 
62 
71 template<typename T, T max_abs> T limit_audio_sample(double s)
72 {
73  //ternary operators allow optimizer to deploy SIMD floating-point instructions
74  s < -1.0 ? -1.0 : s > 1.0 ? 1.0 : s;
75  return (T)(s*max_abs);
76 }
77 
85 template<typename T, T down_scaling> double audio_sample_to_double(T s)
86 {
87  return (1.0/down_scaling) * s;
88 }
89 
99 template<Audio_Encoding> class Audio_Sample;
100 
105 template<> class Audio_Sample<enc_mulaw8>
106 {
107 public:
108  typedef uint8_t enc_sample_type;
109  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
110  static enc_sample_type encode(const double& s)
111  {
112  int16_t l = limit_audio_sample<int16_t, SHRT_MAX>(s);
113  return ulaw_compress(l);
114  }
115  static double decode(const enc_sample_type& s)
116  {
117  return audio_sample_to_double<int16_t, SHRT_MAX>((ulaw_expand(s)));
118  }
119 };
120 
125 template<> class Audio_Sample<enc_linear8>
126 {
127 public:
128  typedef int8_t enc_sample_type;
129  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
130  static enc_sample_type encode(const double& s)
131  {
132  return limit_audio_sample<enc_sample_type, SCHAR_MAX>(s);
133  }
134  static double decode(const enc_sample_type& s)
135  {
136  return audio_sample_to_double<enc_sample_type, SCHAR_MAX>(s);
137  }
138 };
139 
144 template<> class Audio_Sample<enc_linear16>
145 {
146 public:
147  typedef int16_t enc_sample_type;
148  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
149  static enc_sample_type encode(const double& s)
150  {
151  return limit_audio_sample<enc_sample_type, SHRT_MAX>(s);
152  }
153  static double decode(const enc_sample_type& s)
154  {
155  return audio_sample_to_double<enc_sample_type, SHRT_MAX>(s);
156  }
157 };
158 
161 {
162 public:
163  static const int32_t max_abs_value = (1<<23) - 1;
164  explicit Sample_24(uint32_t v = 0):_value(v){}
165  uint32_t value() const {return _value;}
166  void value(uint32_t v){_value = v;}
167 private:
168  uint32_t _value;
169 };
170 
171 
173 template<typename Binary_Out_Stream>
174 Binary_Out_Stream& operator<<(Binary_Out_Stream& s, Sample_24 v)
175 {
176  uint32_t sample = v.value();
177  char *c = reinterpret_cast<char *>(&sample);
178  if(s.get_endianity() == s.get_native_endianity()){
179  //stream endian matches machine endian
180  s.write(c,3);
181  }
182  else{
183  //stream endian differs from machine endian - reverse order of bytes
184  s.put(c[2]); s.put(c[1]); s.put(c[0]);
185  }
186  return s;
187 }
188 
190 template<typename Binary_In_Stream>
191 Binary_In_Stream& operator>>(Binary_In_Stream& s, Sample_24& v)
192 {
193  uint32_t sample;
194  char *c = reinterpret_cast<char *>(&sample);
195  if(s.get_endianity() == s.get_native_endianity()){
196  //stream endian matches machine endian
197  s.read(c,3);
198  }
199  else{
200  //stream endian differs from machine endian - reverse order of bytes
201  s.get(c[2]); s.get(c[1]); s.get(c[0]);
202  }
203  if(s) v.value(sample);
204  return s;
205 }
206 
211 template<> class Audio_Sample<enc_linear24>
212 {
213 public:
214  typedef Sample_24 enc_sample_type;
215  static const std::size_t enc_sample_size = 3; //3 bytes per sample
216  static enc_sample_type encode(const double& s)
217  {
218  return Sample_24(limit_audio_sample<int32_t, Sample_24::max_abs_value>(s));
219  }
220  static double decode(const enc_sample_type& s)
221  {
222  return audio_sample_to_double<int32_t, Sample_24::max_abs_value>(s.value());
223  }
224 };
225 
226 
231 template<> class Audio_Sample<enc_linear32>
232 {
233 public:
234  typedef int32_t enc_sample_type;
235  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
236  static enc_sample_type encode(const double& s)
237  {
238  return limit_audio_sample<enc_sample_type, INT_MAX>(s);
239  }
240  static double decode(const enc_sample_type& s)
241  {
242  return audio_sample_to_double<enc_sample_type, INT_MAX>(s);
243  }
244 };
245 
246 
254 template<> class Audio_Sample<enc_float>
255 {
256 public:
257  typedef float enc_sample_type;
258  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
259  static enc_sample_type encode(const double& s)
260  {//saturate here to avoid Infinity values
261  return (enc_sample_type)(s < -INT_MAX ? -INT_MAX : s > INT_MAX ? INT_MAX : s);
262  }
263  static double decode(const enc_sample_type& s){return s;}
264 };
265 
272 template<> class Audio_Sample<enc_double>
273 {
274 public:
275  typedef double enc_sample_type;
276  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
277  static enc_sample_type encode(const double& s) {return s;}
278  static double decode(const enc_sample_type& s){return s;}
279 };
280 
285 template<> class Audio_Sample<enc_alaw8>
286 {
287 public:
288  typedef uint8_t enc_sample_type;
289  static const std::size_t enc_sample_size = sizeof(enc_sample_type);
290  static enc_sample_type encode(const double& s)
291  {
292  int16_t l = limit_audio_sample<int16_t, SHRT_MAX>(s);
293  return alaw_compress(l);
294  }
295  static double decode(const enc_sample_type& s)
296  {
297  return audio_sample_to_double<int16_t, SHRT_MAX>((alaw_expand(s)));
298  }
299 };
300 
302 inline std::size_t encoded_sample_size(Audio_Encoding e)
303 {
304  switch(e) {
305  case enc_mulaw8:
307  case enc_linear8:
309  case enc_linear16:
311  case enc_linear24:
313  case enc_linear32:
315  case enc_float:
317  case enc_double:
319  case enc_alaw8:
321  case enc_unknown:
322  default:
323  return 0;
324  }
325 }
326 
327 } // namespace itpp
328 
329 #endif // #ifndef AUDIOFILE_H
SourceForge Logo

Generated on Sat Jul 6 2013 10:54:25 for IT++ by Doxygen 1.8.2