foobar2000 SDK  2015-01-14
audio_chunk.cpp
Go to the documentation of this file.
1 #include "foobar2000.h"
2 
3 void audio_chunk::set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config)
4 {
5  t_size size = samples * nch;
6  set_data_size(size);
7  if (src)
8  pfc::memcpy_t(get_data(),src,size);
9  else
11  set_sample_count(samples);
12  set_channels(nch,channel_config);
13  set_srate(srate);
14 }
15 
16 inline bool check_exclusive(unsigned val, unsigned mask)
17 {
18  return (val&mask)!=0 && (val&mask)!=mask;
19 }
20 
21 static void _import8u(uint8_t const * in, audio_sample * out, size_t count) {
22  for(size_t walk = 0; walk < count; ++walk) {
23  uint32_t i = *(in++);
24  i -= 0x80; // to signed
25  *(out++) = (float) (int32_t) i / (float) 0x80;
26  }
27 }
28 
29 static void _import8s(uint8_t const * in, audio_sample * out, size_t count) {
30  for(size_t walk = 0; walk < count; ++walk) {
31  int32_t i = (int8_t) *(in++);
32  *(out++) = (float) i / (float) 0x80;
33  }
34 }
35 
36 static audio_sample _import24s(uint32_t i) {
37  i ^= 0x800000; // to unsigned
38  i -= 0x800000; // and back to signed / fill MSBs proper
39  return (float) (int32_t) i / (float) 0x800000;
40 }
41 
42 static void _import24(const void * in_, audio_sample * out, size_t count) {
43  const uint8_t * in = (const uint8_t*) in_;
44 #if 1
45  while(count > 0 && !pfc::is_ptr_aligned_t<4>(in)) {
46  uint32_t i = *(in++);
47  i |= (uint32_t) *(in++) << 8;
48  i |= (uint32_t) *(in++) << 16;
49  *(out++) = _import24s(i);
50  --count;
51  }
52  {
53  for(size_t loop = count >> 2; loop; --loop) {
54  uint32_t i1 = * (uint32_t*) in; in += 4;
55  uint32_t i2 = * (uint32_t*) in; in += 4;
56  uint32_t i3 = * (uint32_t*) in; in += 4;
57  *out++ = _import24s( i1 & 0xFFFFFF );
58  *out++ = _import24s( (i1 >> 24) | ((i2 & 0xFFFF) << 8) );
59  *out++ = _import24s( (i2 >> 16) | ((i3 & 0xFF) << 16) );
60  *out++ = _import24s( i3 >> 8 );
61  }
62  count &= 3;
63  }
64  for( ; count ; --count) {
65  uint32_t i = *(in++);
66  i |= (uint32_t) *(in++) << 8;
67  i |= (uint32_t) *(in++) << 16;
68  *(out++) = _import24s(i);
69  }
70 #else
71  if (count > 0) {
72  int32_t i = *(in++);
73  i |= (int32_t) *(in++) << 8;
74  i |= (int32_t) (int8_t) *in << 16;
75  *out++ = (audio_sample) i / (audio_sample) 0x800000;
76  --count;
77 
78  // Now we have in ptr at offset_of_next - 1 and we can read as int32 then discard the LSBs
79  for(;count;--count) {
80  int32_t i = *( int32_t*) in; in += 3;
81  *out++ = (audio_sample) (i >> 8) / (audio_sample) 0x800000;
82  }
83  }
84 #endif
85 }
86 
87 template<bool byteSwap, bool isSigned> static void _import16any(const void * in, audio_sample * out, size_t count) {
88  uint16_t const * inPtr = (uint16_t const*) in;
89  const audio_sample factor = 1.0f / (audio_sample) 0x8000;
90  for(size_t walk = 0; walk < count; ++walk) {
91  uint16_t v = *inPtr++;
92  if (byteSwap) v = pfc::byteswap_t(v);
93  if (!isSigned) v ^= 0x8000; // to signed
94  *out++ = (audio_sample) (int16_t) v * factor;
95  }
96 }
97 
98 template<bool byteSwap, bool isSigned> static void _import32any(const void * in, audio_sample * out, size_t count) {
99  uint32_t const * inPtr = (uint32_t const*) in;
100  const audio_sample factor = 1.0f / (audio_sample) 0x80000000;
101  for(size_t walk = 0; walk < count; ++walk) {
102  uint32_t v = *inPtr++;
103  if (byteSwap) v = pfc::byteswap_t(v);
104  if (!isSigned) v ^= 0x80000000; // to signed
105  *out++ = (audio_sample) (int32_t) v * factor;
106  }
107 }
108 
109 template<bool byteSwap, bool isSigned> static void _import24any(const void * in, audio_sample * out, size_t count) {
110  uint8_t const * inPtr = (uint8_t const*) in;
111  const audio_sample factor = 1.0f / (audio_sample) 0x800000;
112  for(size_t walk = 0; walk < count; ++walk) {
113  uint32_t v;
114  if (byteSwap) v = (uint32_t) inPtr[2] | ( (uint32_t) inPtr[1] << 8 ) | ( (uint32_t) inPtr[0] << 16 );
115  else v = (uint32_t) inPtr[0] | ( (uint32_t) inPtr[1] << 8 ) | ( (uint32_t) inPtr[2] << 16 );
116  inPtr += 3;
117  if (isSigned) v ^= 0x800000; // to unsigned
118  v -= 0x800000; // then subtract to get proper MSBs
119  *out++ = (audio_sample) (int32_t) v * factor;
120  }
121 }
122 
123 void audio_chunk::set_data_fixedpoint_ex(const void * source,t_size size,unsigned srate,unsigned nch,unsigned bps,unsigned flags,unsigned p_channel_config)
124 {
125  PFC_ASSERT( check_exclusive(flags,FLAG_SIGNED|FLAG_UNSIGNED) );
127 
128  bool byteSwap = !!(flags & FLAG_BIG_ENDIAN);
129  if (pfc::byte_order_is_big_endian) byteSwap = !byteSwap;
130 
131  t_size count = size / (bps/8);
132  set_data_size(count);
133  audio_sample * buffer = get_data();
134  bool isSigned = !!(flags & FLAG_SIGNED);
135 
136  switch(bps)
137  {
138  case 8:
139  // byte order irrelevant
140  if (isSigned) _import8s( (const uint8_t*) source , buffer, count);
141  else _import8u( (const uint8_t*) source , buffer, count);
142  break;
143  case 16:
144  if (byteSwap) {
145  if (isSigned) {
146  _import16any<true, true>( source, buffer, count );
147  } else {
148  _import16any<true, false>( source, buffer, count );
149  }
150  } else {
151  if (isSigned) {
152  //_import16any<false, true>( source, buffer, count );
153  audio_math::convert_from_int16((const int16_t*)source,count,buffer,1.0);
154  } else {
155  _import16any<false, false>( source, buffer, count);
156  }
157  }
158  break;
159  case 24:
160  if (byteSwap) {
161  if (isSigned) {
162  _import24any<true, true>( source, buffer, count );
163  } else {
164  _import24any<true, false>( source, buffer, count );
165  }
166  } else {
167  if (isSigned) {
168  //_import24any<false, true>( source, buffer, count);
169  _import24( source, buffer, count);
170  } else {
171  _import24any<false, false>( source, buffer, count);
172  }
173  }
174  break;
175  case 32:
176  if (byteSwap) {
177  if (isSigned) {
178  _import32any<true, true>( source, buffer, count );
179  } else {
180  _import32any<true, false>( source, buffer, count );
181  }
182  } else {
183  if (isSigned) {
184  audio_math::convert_from_int32((const int32_t*)source,count,buffer,1.0);
185  } else {
186  _import32any<false, false>( source, buffer, count);
187  }
188  }
189  break;
190  default:
191  //unknown size, cant convert
192  pfc::memset_t(buffer,(audio_sample)0,count);
193  break;
194  }
195  set_sample_count(count/nch);
196  set_srate(srate);
197  set_channels(nch,p_channel_config);
198 }
199 
200 void audio_chunk::set_data_fixedpoint_ms(const void * ptr, size_t bytes, unsigned sampleRate, unsigned channels, unsigned bps, unsigned channelConfig) {
201  //set_data_fixedpoint_ex(ptr,bytes,sampleRate,channels,bps,(bps==8 ? FLAG_UNSIGNED : FLAG_SIGNED) | flags_autoendian(), channelConfig);
202  PFC_ASSERT( bps != 0 );
203  size_t count = bytes / (bps/8);
204  this->set_data_size( count );
205  audio_sample * buffer = this->get_data();
206  switch(bps) {
207  case 8:
208  _import8u((const uint8_t*)ptr, buffer, count);
209  break;
210  case 16:
211  audio_math::convert_from_int16((const int16_t*) ptr, count, buffer, 1.0);
212  break;
213  case 24:
214  _import24( ptr, buffer, count);
215  break;
216  case 32:
217  audio_math::convert_from_int32((const int32_t*) ptr, count, buffer, 1.0);
218  break;
219  default:
220  PFC_ASSERT(!"Unknown bit depth!");
221  memset(buffer, 0, sizeof(audio_sample) * count);
222  break;
223  }
224  set_sample_count(count/channels);
225  set_srate(sampleRate);
226  set_channels(channels,channelConfig);
227 }
228 
229 void audio_chunk::set_data_fixedpoint_signed(const void * ptr,t_size bytes,unsigned sampleRate,unsigned channels,unsigned bps,unsigned channelConfig) {
230  PFC_ASSERT( bps != 0 );
231  size_t count = bytes / (bps/8);
232  this->set_data_size( count );
233  audio_sample * buffer = this->get_data();
234  switch(bps) {
235  case 8:
236  _import8s((const uint8_t*)ptr, buffer, count);
237  break;
238  case 16:
239  audio_math::convert_from_int16((const int16_t*) ptr, count, buffer, 1.0);
240  break;
241  case 24:
242  _import24( ptr, buffer, count);
243  break;
244  case 32:
245  audio_math::convert_from_int32((const int32_t*) ptr, count, buffer, 1.0);
246  break;
247  default:
248  PFC_ASSERT(!"Unknown bit depth!");
249  memset(buffer, 0, sizeof(audio_sample) * count);
250  break;
251  }
252  set_sample_count(count/channels);
253  set_srate(sampleRate);
254  set_channels(channels,channelConfig);
255 }
256 
257 void audio_chunk::set_data_int16(const int16_t * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config) {
258  const size_t count = samples * nch;
259  this->set_data_size( count );
260  audio_sample * buffer = this->get_data();
261  audio_math::convert_from_int16(src, count, buffer, 1.0);
262  set_sample_count(samples);
263  set_srate(srate);
264  set_channels(nch,channel_config);
265 }
266 
267 template<class t_float>
268 static void process_float_multi(audio_sample * p_out,const t_float * p_in,const t_size p_count)
269 {
270  for(size_t n=0;n<p_count;n++) p_out[n] = (audio_sample)p_in[n];
271 }
272 
273 template<class t_float>
274 static void process_float_multi_swap(audio_sample * p_out,const t_float * p_in,const t_size p_count)
275 {
276  for(size_t n=0;n<p_count;n++) {
277  p_out[n] = (audio_sample) pfc::byteswap_t(p_in[n]);
278  }
279 }
280 
281 
282 void audio_chunk::set_data_floatingpoint_ex(const void * ptr,t_size size,unsigned srate,unsigned nch,unsigned bps,unsigned flags,unsigned p_channel_config)
283 {
284  PFC_ASSERT(bps==32 || bps==64 || bps == 16 || bps == 24);
286  PFC_ASSERT( ! (flags & (FLAG_SIGNED|FLAG_UNSIGNED) ) );
287 
288  bool use_swap = pfc::byte_order_is_big_endian ? !!(flags & FLAG_LITTLE_ENDIAN) : !!(flags & FLAG_BIG_ENDIAN);
289 
290  const t_size count = size / (bps/8);
291  set_data_size(count);
292  audio_sample * out = get_data();
293 
294  if (bps == 32)
295  {
296  if (use_swap)
297  process_float_multi_swap(out,reinterpret_cast<const float*>(ptr),count);
298  else
299  process_float_multi(out,reinterpret_cast<const float*>(ptr),count);
300  }
301  else if (bps == 64)
302  {
303  if (use_swap)
304  process_float_multi_swap(out,reinterpret_cast<const double*>(ptr),count);
305  else
306  process_float_multi(out,reinterpret_cast<const double*>(ptr),count);
307  } else if (bps == 16) {
308  const uint16_t * in = reinterpret_cast<const uint16_t*>(ptr);
309  if (use_swap) {
310  for(size_t walk = 0; walk < count; ++walk) out[walk] = audio_math::decodeFloat16(pfc::byteswap_t(in[walk]));
311  } else {
312  for(size_t walk = 0; walk < count; ++walk) out[walk] = audio_math::decodeFloat16(in[walk]);
313  }
314  } else if (bps == 24) {
315  const uint8_t * in = reinterpret_cast<const uint8_t*>(ptr);
316  if (use_swap) {
317  for(size_t walk = 0; walk < count; ++walk) out[walk] = audio_math::decodeFloat24ptrbs(&in[walk*3]);
318  } else {
319  for(size_t walk = 0; walk < count; ++walk) out[walk] = audio_math::decodeFloat24ptr(&in[walk*3]);
320  }
321  } else pfc::throw_exception_with_message< exception_io_data >("invalid bit depth");
322 
323  set_sample_count(count/nch);
324  set_srate(srate);
325  set_channels(nch,p_channel_config);
326 }
327 
329 {
330  unsigned nch = get_channels();
331  if (nch==0 || nch>256) return false;
332  if (!g_is_valid_sample_rate(get_srate())) return false;
333  t_size samples = get_sample_count();
334  if (samples==0 || samples >= 0x80000000 / (sizeof(audio_sample) * nch) ) return false;
335  t_size size = get_data_size();
336  if (samples * nch > size) return false;
337  if (!get_data()) return false;
338  return true;
339 }
340 
342  return this->get_spec().is_valid();
343 }
344 
345 void audio_chunk::pad_with_silence_ex(t_size samples,unsigned hint_nch,unsigned hint_srate) {
346  if (is_empty())
347  {
348  if (hint_srate && hint_nch) {
349  return set_data(0,samples,hint_nch,hint_srate);
350  } else throw exception_io_data();
351  }
352  else
353  {
354  if (hint_srate && hint_srate != get_srate()) samples = MulDiv_Size(samples,get_srate(),hint_srate);
355  if (samples > get_sample_count())
356  {
357  t_size old_size = get_sample_count() * get_channels();
358  t_size new_size = samples * get_channels();
359  set_data_size(new_size);
360  pfc::memset_t(get_data() + old_size,(audio_sample)0,new_size - old_size);
361  set_sample_count(samples);
362  }
363  }
364 }
365 
367  if (samples > get_sample_count())
368  {
369  t_size old_size = get_sample_count() * get_channels();
370  t_size new_size = pfc::multiply_guarded(samples,(size_t)get_channels());
371  set_data_size(new_size);
372  pfc::memset_t(get_data() + old_size,(audio_sample)0,new_size - old_size);
373  set_sample_count(samples);
374  }
375 }
376 
378  t_size items = samples * get_channels();
379  set_data_size(items);
380  pfc::memset_null_t(get_data(), items);
381  set_sample_count(samples);
382 }
383 
384 void audio_chunk::set_silence_seconds( double seconds ) {
385  set_silence( (size_t) audio_math::time_to_samples( seconds, this->get_sample_rate() ) );
386 }
387 
389  t_size old_size = get_sample_count() * get_channels();
390  t_size delta = samples * get_channels();
391  t_size new_size = old_size + delta;
392  set_data_size(new_size);
393  audio_sample * ptr = get_data();
394  pfc::memmove_t(ptr+delta,ptr,old_size);
395  pfc::memset_t(ptr,(audio_sample)0,delta);
396  set_sample_count(get_sample_count() + samples);
397 }
398 
399 bool audio_chunk::process_skip(double & skipDuration) {
400  t_uint64 skipSamples = audio_math::time_to_samples(skipDuration, get_sample_rate());
401  if (skipSamples == 0) {skipDuration = 0; return true;}
402  const t_size mySamples = get_sample_count();
403  if (skipSamples < mySamples) {
404  skip_first_samples((t_size)skipSamples);
405  skipDuration = 0;
406  return true;
407  }
408  if (skipSamples == mySamples) {
409  skipDuration = 0;
410  return false;
411  }
412  skipDuration -= audio_math::samples_to_time(mySamples, get_sample_rate());
413  return false;
414 }
415 
417 {
418  t_size samples_old = get_sample_count();
419  if (samples_delta >= samples_old)
420  {
421  set_sample_count(0);
422  set_data_size(0);
423  return samples_old;
424  }
425  else
426  {
427  t_size samples_new = samples_old - samples_delta;
428  unsigned nch = get_channels();
429  audio_sample * ptr = get_data();
430  pfc::memmove_t(ptr,ptr+nch*samples_delta,nch*samples_new);
431  set_sample_count(samples_new);
432  set_data_size(nch*samples_new);
433  return samples_delta;
434  }
435 }
436 
438  return pfc::max_t(p_peak, get_peak());
439 }
440 
443 }
444 
446 {
447  audio_sample * ptr = get_data();
448  audio_math::scale(ptr,get_sample_count() * get_channels(),ptr,p_value);
449 }
450 
451 
452 namespace {
453 
454 struct sampleToIntDesc {
455  unsigned bps, bpsValid;
456  bool useUpperBits;
457  float scale;
458 };
459 template<typename int_t> class sampleToInt {
460 public:
461  sampleToInt(sampleToIntDesc const & d) {
462  clipLo = - ( (int_t) 1 << (d.bpsValid-1));
463  clipHi = ( (int_t) 1 << (d.bpsValid-1)) - 1;
464  scale = (float) ( (int64_t) 1 << (d.bpsValid - 1) ) * d.scale;
465  if (d.useUpperBits) {
466  shift = d.bps - d.bpsValid;
467  } else {
468  shift = 0;
469  }
470  }
471  inline int_t operator() (audio_sample s) const {
472  int_t v;
473  if (sizeof(int_t) > 4) v = (int_t) audio_math::rint64( s * scale );
474  else v = (int_t)audio_math::rint32( s * scale );
475  return pfc::clip_t<int_t>( v, clipLo, clipHi) << shift;
476  }
477 private:
478  int_t clipLo, clipHi;
479  int8_t shift;
480  float scale;
481 };
482 }
483 static void render_24bit(const audio_sample * in, t_size inLen, void * out, sampleToIntDesc const & d) {
484  t_uint8 * outWalk = reinterpret_cast<t_uint8*>(out);
485  sampleToInt<int32_t> gen(d);
486  for(t_size walk = 0; walk < inLen; ++walk) {
487  int32_t v = gen(in[walk]);
488  *(outWalk ++) = (t_uint8) (v & 0xFF);
489  *(outWalk ++) = (t_uint8) ((v >> 8) & 0xFF);
490  *(outWalk ++) = (t_uint8) ((v >> 16) & 0xFF);
491  }
492 }
493 static void render_8bit(const audio_sample * in, t_size inLen, void * out, sampleToIntDesc const & d) {
494  sampleToInt<int32_t> gen(d);
495  t_int8 * outWalk = reinterpret_cast<t_int8*>(out);
496  for(t_size walk = 0; walk < inLen; ++walk) {
497  *outWalk++ = (t_int8)gen(in[walk]);
498  }
499 }
500 static void render_16bit(const audio_sample * in, t_size inLen, void * out, sampleToIntDesc const & d) {
501  sampleToInt<int32_t> gen(d);
502  int16_t * outWalk = reinterpret_cast<int16_t*>(out);
503  for(t_size walk = 0; walk < inLen; ++walk) {
504  *outWalk++ = (int16_t)gen(in[walk]);
505  }
506 }
507 
508 template<typename internal_t>
509 static void render_32bit_(const audio_sample * in, t_size inLen, void * out, sampleToIntDesc const & d) {
510  sampleToInt<internal_t> gen(d); // must use int64 for clipping
511  int32_t * outWalk = reinterpret_cast<int32_t*>(out);
512  for(t_size walk = 0; walk < inLen; ++walk) {
513  *outWalk++ = (int32_t)gen(in[walk]);
514  }
515 }
516 
517 bool audio_chunk::g_toFixedPoint(const audio_sample * in, void * out, size_t count, uint32_t bps, uint32_t bpsValid, bool useUpperBits, float scale) {
518  const sampleToIntDesc d = {bps, bpsValid, useUpperBits, scale};
519  if (bps == 0) {
520  PFC_ASSERT(!"How did we get here?");
521  return false;
522  } else if (bps <= 8) {
523  render_8bit(in, count, out, d);
524  } else if (bps <= 16) {
525  render_16bit(in, count, out, d);
526  } else if (bps <= 24) {
527  render_24bit(in, count, out, d);
528  } else if (bps <= 32) {
529  if (bpsValid <= 28) { // for speed
530  render_32bit_<int32_t>(in, count, out, d);
531  } else {
532  render_32bit_<int64_t>(in, count, out, d);
533  }
534  } else {
535  PFC_ASSERT(!"How did we get here?");
536  return false;
537  }
538 
539  return true;
540 }
541 
542 bool audio_chunk::toFixedPoint(class mem_block_container & out, uint32_t bps, uint32_t bpsValid, bool useUpperBits, float scale) const {
543  bps = (bps + 7) & ~7;
544  if (bps < bpsValid) return false;
545  const size_t count = get_sample_count() * get_channel_count();
546  out.set_size( count * (bps/8) );
547  return g_toFixedPoint(get_data(), out.get_ptr(), count, bps, bpsValid, useUpperBits, scale);
548 }
549 
550 bool audio_chunk::to_raw_data(mem_block_container & out, t_uint32 bps, bool useUpperBits, float scale) const {
551  uint32_t bpsValid = bps;
552  bps = (bps + 7) & ~7;
553  const size_t count = get_sample_count() * get_channel_count();
554  out.set_size( count * (bps/8) );
555  void * outPtr = out.get_ptr();
556  audio_sample const * inPtr = get_data();
557  if (bps == 32) {
558  float * f = (float*) outPtr;
559  for(size_t w = 0; w < count; ++w) f[w] = inPtr[w] * scale;
560  return true;
561  } else {
562  return g_toFixedPoint(inPtr, outPtr, count, bps, bpsValid, useUpperBits, scale);
563  }
564 }
565 
566 audio_chunk::spec_t audio_chunk::makeSpec(uint32_t rate, uint32_t channels) {
567  return makeSpec( rate, channels, g_guess_channel_config(channels) );
568 }
569 
570 audio_chunk::spec_t audio_chunk::makeSpec(uint32_t rate, uint32_t channels, uint32_t mask) {
571  spec_t spec = {};
572  spec.sampleRate = rate; spec.chanCount = channels; spec.chanMask = mask;
573  return spec;
574 }
575 
576 bool audio_chunk::spec_t::equals( const spec_t & v1, const spec_t & v2 ) {
577  return v1.sampleRate == v2.sampleRate && v1.chanCount == v2.chanCount && v1.chanMask == v2.chanMask;
578 }
579 
581  spec_t spec = {};
582  spec.sampleRate = this->get_sample_rate();
583  spec.chanCount = this->get_channel_count();
584  spec.chanMask = this->get_channel_config();
585  return spec;
586 }
587 void audio_chunk::set_spec(const spec_t & spec) {
589  set_channels( spec.chanCount, spec.chanMask );
590 }
591 
593  if (this->chanCount==0 || this->chanCount>256) return false;
594  if (!audio_chunk::g_is_valid_sample_rate(this->sampleRate)) return false;
595  return true;
596 }
597 
598 double duration_counter::query() const {
599  double acc = m_offset;
600  for(t_map::const_iterator walk = m_sampleCounts.first(); walk.is_valid(); ++walk) {
601  acc += audio_math::samples_to_time(walk->m_value, walk->m_key);
602  }
603  return acc;
604 }
605 
606 uint64_t duration_counter::queryAsSampleCount( uint32_t rate ) {
607  uint64_t samples = 0;
608  double acc = m_offset;
609  for(t_map::const_iterator walk = m_sampleCounts.first(); walk.is_valid(); ++walk) {
610  if (walk->m_key == rate) samples += walk->m_value;
611  else acc += audio_math::samples_to_time(walk->m_value, walk->m_key);
612  }
613  return samples + audio_math::time_to_samples(acc, rate );
614 }
audio_sample decodeFloat24ptrbs(const void *sourcePtr)
virtual void set_size(t_size p_size)=0
static void render_24bit(const audio_sample *in, t_size inLen, void *out, sampleToIntDesc const &d)
static void render_16bit(const audio_sample *in, t_size inLen, void *out, sampleToIntDesc const &d)
static void _import24(const void *in_, audio_sample *out, size_t count)
Definition: audio_chunk.cpp:42
uint8_t t_uint8
Definition: int_types.h:9
uint64_t t_uint64
Definition: int_types.h:3
void set_silence_seconds(double seconds)
audio_sample get_peak() const
virtual void set_srate(unsigned val)=0
Sets sample rate of contained audio data.
t_int multiply_guarded(t_int v1, t_int v2)
Definition: primitives.h:593
t_size MulDiv_Size(t_size x, t_size y, t_size z)
Definition: int_types.h:52
unsigned get_sample_rate() const
Helper, same as get_srate().
Definition: audio_chunk.h:103
void set_data_fixedpoint_ex(const void *ptr, t_size bytes, unsigned p_sample_rate, unsigned p_channels, unsigned p_bits_per_sample, unsigned p_flags, unsigned p_channel_config)
static bool g_toFixedPoint(const audio_sample *in, void *out, size_t count, uint32_t bps, uint32_t bpsValid, bool useUpperBits=true, float scale=1.0)
Convert a buffer of audio_samples to fixed-point PCM format.
void pad_with_silence(t_size samples)
T byteswap_t(T p_source)
void set_data_fixedpoint_signed(const void *ptr, t_size bytes, unsigned srate, unsigned nch, unsigned bps, unsigned channel_config)
bool process_skip(double &skipDuration)
void set_data_fixedpoint_ms(const void *ptr, size_t bytes, unsigned sampleRate, unsigned channels, unsigned bps, unsigned channelConfig)
static const bool byte_order_is_big_endian
virtual unsigned get_channels() const =0
Retrieves channel count of contained audio data.
bool is_valid() const
Definition: iterators.h:24
audio_sample decodeFloat16(uint16_t source)
uint64_t queryAsSampleCount(uint32_t rate)
virtual unsigned get_srate() const =0
Retrieves sample rate of contained audio data.
double samples_to_time(t_uint64 p_samples, t_uint32 p_sample_rate)
Definition: audio_sample.h:37
static bool equals(const spec_t &v1, const spec_t &v2)
void set_spec(const spec_t &)
static t_int64 rint64(audio_sample val)
Definition: audio_sample.h:44
static void render_32bit_(const audio_sample *in, t_size inLen, void *out, sampleToIntDesc const &d)
bool toFixedPoint(class mem_block_container &out, uint32_t bps, uint32_t bpsValid, bool useUpperBits=true, float scale=1.0) const
Convert audio_chunk contents to fixed-point PCM format.
virtual unsigned get_channel_config() const =0
Retrieves channel map of contained audio data. Conditions where number of channels specified by chann...
void set_data(const audio_sample *src, t_size samples, unsigned nch, unsigned srate, unsigned channel_config)
Helper, sets chunk data to contents of specified buffer, with specified number of channels / sample r...
Definition: audio_chunk.cpp:3
size_t t_size
Definition: int_types.h:48
void insert_silence_fromstart(t_size samples)
audio_sample decodeFloat24ptr(const void *sourcePtr)
Definition: audio_sample.cpp:4
void scale(audio_sample p_value)
Helper function; scales entire chunk content by specified value.
static void _import16any(const void *in, audio_sample *out, size_t count)
Definition: audio_chunk.cpp:87
void memmove_t(T *p_dst, const T *p_src, t_size p_count)
Definition: primitives.h:649
void set_data_floatingpoint_ex(const void *ptr, t_size bytes, unsigned p_sample_rate, unsigned p_channels, unsigned p_bits_per_sample, unsigned p_flags, unsigned p_channel_config)
virtual audio_sample * get_data()=0
Retrieves audio data buffer pointer (non-const version). Returned pointer is for temporary use only; ...
void memset_null_t(T *p_buffer, t_size p_count)
Definition: primitives.h:638
bool is_spec_valid() const
Returns whether the chunk contains valid sample rate & channel info (but allows an empty chunk)...
static void _import24any(const void *in, audio_sample *out, size_t count)
void SHARED_EXPORT scale(const audio_sample *p_source, t_size p_count, audio_sample *p_output, audio_sample p_scale)
p_source/p_output can point to same buffer
Definition: audio_math.cpp:63
bool is_valid() const
Returns whether the chunk contents are valid (for bug check purposes).
virtual const void * get_ptr() const =0
float audio_sample
Definition: audio_sample.h:6
static spec_t makeSpec(uint32_t rate, uint32_t channels)
static unsigned g_guess_channel_config(unsigned count)
Helper function; guesses default channel map for the specified channel count. Returns 0 on failure...
static void process_float_multi_swap(audio_sample *p_out, const t_float *p_in, const t_size p_count)
static void process_float_multi(audio_sample *p_out, const t_float *p_in, const t_size p_count)
virtual void set_channels(unsigned p_count, unsigned p_config)=0
Sets channel count / channel map.
audio_sample SHARED_EXPORT calculate_peak(const audio_sample *p_source, t_size p_count)
Definition: audio_math.cpp:108
static void _import32any(const void *in, audio_sample *out, size_t count)
Definition: audio_chunk.cpp:98
virtual t_size get_data_size() const =0
Retrieves size of allocated buffer space, in audio_samples.
double query() const
static audio_sample _import24s(uint32_t i)
Definition: audio_chunk.cpp:36
t_size skip_first_samples(t_size samples)
static t_int32 rint32(audio_sample val)
Definition: audio_sample.h:52
spec_t get_spec() const
virtual void set_data_size(t_size p_new_size)=0
Resizes audio data buffer to specified size. Throws std::bad_alloc on failure.
void SHARED_EXPORT convert_from_int32(const t_int32 *p_source, t_size p_count, audio_sample *p_output, audio_sample p_scale)
Definition: audio_math.cpp:101
static void _import8s(uint8_t const *in, audio_sample *out, size_t count)
Definition: audio_chunk.cpp:29
void pad_with_silence_ex(t_size samples, unsigned hint_nch, unsigned hint_srate)
void memcpy_t(t_dst *p_dst, const t_src *p_src, t_size p_count)
Definition: primitives.h:611
Generic interface for a memory block; used by various other interfaces to return memory blocks while ...
bool check_exclusive(unsigned val, unsigned mask)
Definition: audio_chunk.cpp:16
bool is_empty() const
Returns whether the chunk is empty (contains no audio data).
Definition: audio_chunk.h:125
static bool g_is_valid_sample_rate(t_uint32 p_val)
Definition: audio_chunk.h:11
void SHARED_EXPORT convert_from_int16(const t_int16 *p_source, t_size p_count, audio_sample *p_output, audio_sample p_scale)
Definition: audio_math.cpp:81
static void render_8bit(const audio_sample *in, t_size inLen, void *out, sampleToIntDesc const &d)
t_uint64 time_to_samples(double p_time, t_uint32 p_sample_rate)
Definition: audio_sample.h:33
T max_t(const T &item1, const T &item2)
Definition: primitives.h:553
void set_data_int16(const int16_t *src, t_size samples, unsigned nch, unsigned srate, unsigned channel_config)
void memset_t(T *p_buffer, const t_val &p_val, t_size p_count)
Definition: primitives.h:627
unsigned get_channel_count() const
Helper - for consistency - same as get_channels().
Definition: audio_chunk.h:88
virtual t_size get_sample_count() const =0
Retrieves number of valid samples in the buffer. Note that a "sample" means a unit of interleaved PC...
virtual void set_sample_count(t_size val)=0
Sets number of valid samples in the buffer. WARNING: sample count * channel count should never be abo...
void set_silence(t_size samples)
static void _import8u(uint8_t const *in, audio_sample *out, size_t count)
Definition: audio_chunk.cpp:21
void set_sample_rate(unsigned val)
Helper, same as set_srate().
Definition: audio_chunk.h:105
uint32_t t_uint32
Definition: int_types.h:5
bool to_raw_data(class mem_block_container &out, t_uint32 bps, bool useUpperBits=true, float scale=1.0) const
Simple function to get original PCM stream back. Assumes host's endianness, integers are signed - inc...
int8_t t_int8
Definition: int_types.h:8
bool is_valid() const