foobar2000 SDK  2015-08-03
audio_chunk.h
Go to the documentation of this file.
1 PFC_DECLARE_EXCEPTION(exception_unexpected_audio_format_change, exception_io_data, "Unexpected audio format change" );
3 
5 class NOVTABLE audio_chunk {
6 public:
7 
8  enum {
9  sample_rate_min = 1000, sample_rate_max = 2822400
10  };
11  static bool g_is_valid_sample_rate(t_uint32 p_val) {return p_val >= sample_rate_min && p_val <= sample_rate_max;}
12 
14  enum
15  {
16  channel_front_left = 1<<0,
17  channel_front_right = 1<<1,
18  channel_front_center = 1<<2,
19  channel_lfe = 1<<3,
20  channel_back_left = 1<<4,
21  channel_back_right = 1<<5,
22  channel_front_center_left = 1<<6,
23  channel_front_center_right = 1<<7,
24  channel_back_center = 1<<8,
25  channel_side_left = 1<<9,
26  channel_side_right = 1<<10,
27  channel_top_center = 1<<11,
28  channel_top_front_left = 1<<12,
29  channel_top_front_center = 1<<13,
30  channel_top_front_right = 1<<14,
31  channel_top_back_left = 1<<15,
32  channel_top_back_center = 1<<16,
33  channel_top_back_right = 1<<17,
34 
35  channel_config_mono = channel_front_center,
36  channel_config_stereo = channel_front_left | channel_front_right,
37  channel_config_5point1 = channel_front_left | channel_front_right | channel_front_center | channel_lfe | channel_back_left | channel_back_right,
38  channel_config_5point1_side = channel_front_left | channel_front_right | channel_front_center | channel_lfe | channel_side_left | channel_side_right,
39  channel_config_7point1 = channel_config_5point1 | channel_side_left | channel_side_right,
40 
41  defined_channel_count = 18,
42  };
43 
45  static unsigned g_guess_channel_config(unsigned count);
47  static unsigned g_guess_channel_config_xiph(unsigned count);
48 
50  static uint32_t g_channel_config_to_wfx(unsigned p_config);
52  static unsigned g_channel_config_from_wfx(uint32_t p_wfx);
53 
55  static unsigned g_extract_channel_flag(unsigned p_config,unsigned p_index);
57  static unsigned g_count_channels(unsigned p_config);
59  static unsigned g_channel_index_from_flag(unsigned p_config,unsigned p_flag);
60 
61  static const char * g_channel_name(unsigned p_flag);
62  static const char * g_channel_name_byidx(unsigned p_index);
63  static unsigned g_find_channel_idx(unsigned p_flag);
64  static void g_formatChannelMaskDesc(unsigned flags, pfc::string_base & out);
65 
66 
67 
70  virtual audio_sample * get_data() = 0;
73  virtual const audio_sample * get_data() const = 0;
75  virtual t_size get_data_size() const = 0;
77  virtual void set_data_size(t_size p_new_size) = 0;
79  void allocate(size_t size) { set_data_size( size ); }
80 
82  virtual unsigned get_srate() const = 0;
84  virtual void set_srate(unsigned val) = 0;
86  virtual unsigned get_channels() const = 0;
88  inline unsigned get_channel_count() const {return get_channels();}
90  virtual unsigned get_channel_config() const = 0;
92  virtual void set_channels(unsigned p_count,unsigned p_config) = 0;
93 
97  virtual t_size get_sample_count() const = 0;
98 
100  virtual void set_sample_count(t_size val) = 0;
101 
103  inline unsigned get_sample_rate() const {return get_srate();}
105  inline void set_sample_rate(unsigned val) {set_srate(val);}
106 
108  void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
109 
110 
112  inline void grow_data_size(t_size p_requested) {if (p_requested > get_data_size()) set_data_size(p_requested);}
113 
114 
116  inline double get_duration() const
117  {
118  double rv = 0;
119  t_size srate = get_srate (), samples = get_sample_count();
120  if (srate>0 && samples>0) rv = (double)samples/(double)srate;
121  return rv;
122  }
123 
125  inline bool is_empty() const {return get_channels()==0 || get_srate()==0 || get_sample_count()==0;}
126 
128  bool is_valid() const;
129 
131  bool is_spec_valid() const;
132 
134  size_t get_used_size() const {return get_sample_count() * get_channels();}
136  size_t get_data_length() const {return get_sample_count() * get_channels();}
137 #pragma deprecated( get_data_length )
138 
140  inline void reset() {
141  set_sample_count(0);
142  set_srate(0);
143  set_channels(0);
144  set_data_size(0);
145  }
146 
148  void set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config);
149 
151  inline void set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate) {set_data(src,samples,nch,srate,g_guess_channel_config(nch));}
152 
153  void set_data_int16(const int16_t * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config);
154 
156  inline void set_data_fixedpoint(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
157  this->set_data_fixedpoint_ms(ptr, bytes, srate, nch, bps, channel_config);
158  }
159 
160  void set_data_fixedpoint_signed(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config);
161 
162  enum
163  {
164  FLAG_LITTLE_ENDIAN = 1,
165  FLAG_BIG_ENDIAN = 2,
166  FLAG_SIGNED = 4,
167  FLAG_UNSIGNED = 8,
168  };
169 
170  inline static unsigned flags_autoendian() {
171  return pfc::byte_order_is_big_endian ? FLAG_BIG_ENDIAN : FLAG_LITTLE_ENDIAN;
172  }
173 
174  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);//p_flags - see FLAG_* above
175 
176  void set_data_fixedpoint_ms(const void * ptr, size_t bytes, unsigned sampleRate, unsigned channels, unsigned bps, unsigned channelConfig);
177 
178  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);//signed/unsigned flags dont apply
179 
180  inline void set_data_32(const float * src,t_size samples,unsigned nch,unsigned srate) {return set_data(src,samples,nch,srate);}
181 
182  void pad_with_silence_ex(t_size samples,unsigned hint_nch,unsigned hint_srate);
183  void pad_with_silence(t_size samples);
184  void insert_silence_fromstart(t_size samples);
185  t_size skip_first_samples(t_size samples);
186  void set_silence(t_size samples);
187  void set_silence_seconds( double seconds );
188 
189  bool process_skip(double & skipDuration);
190 
193  bool to_raw_data(class mem_block_container & out, t_uint32 bps, bool useUpperBits = true, float scale = 1.0) const;
194 
197  bool toFixedPoint(class mem_block_container & out, uint32_t bps, uint32_t bpsValid, bool useUpperBits = true, float scale = 1.0) const;
198 
201  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);
202 
203 
205  audio_sample get_peak(audio_sample p_peak) const;
206  audio_sample get_peak() const;
207 
209  void scale(audio_sample p_value);
210 
212  void copy(const audio_chunk & p_source) {
213  set_data(p_source.get_data(),p_source.get_sample_count(),p_source.get_channels(),p_source.get_srate(),p_source.get_channel_config());
214  }
215 
216  const audio_chunk & operator=(const audio_chunk & p_source) {
217  copy(p_source);
218  return *this;
219  }
220 
221  struct spec_t {
222  uint32_t sampleRate;
223  uint32_t chanCount, chanMask;
224 
225  static bool equals( const spec_t & v1, const spec_t & v2 );
226  bool operator==(const spec_t & other) const { return equals(*this, other);}
227  bool operator!=(const spec_t & other) const { return !equals(*this, other);}
228  bool is_valid() const;
229  };
230  static spec_t makeSpec(uint32_t rate, uint32_t channels);
231  static spec_t makeSpec(uint32_t rate, uint32_t channels, uint32_t chanMask);
232 
233  spec_t get_spec() const;
234  void set_spec(const spec_t &);
235 protected:
238 };
239 
241 template<typename container_t = pfc::mem_block_aligned_t<audio_sample, 16> >
244  container_t m_data;
245  unsigned m_srate,m_nch,m_setup;
247 public:
248  audio_chunk_impl_t() : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {}
249  audio_chunk_impl_t(const audio_sample * src,unsigned samples,unsigned nch,unsigned srate) : m_srate(0), m_nch(0), m_samples(0)
250  {set_data(src,samples,nch,srate);}
251  audio_chunk_impl_t(const audio_chunk & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
252  audio_chunk_impl_t(const t_self & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
253 
254  virtual audio_sample * get_data() {return m_data.get_ptr();}
255  virtual const audio_sample * get_data() const {return m_data.get_ptr();}
256  virtual t_size get_data_size() const {return m_data.get_size();}
257  virtual void set_data_size(t_size new_size) {m_data.set_size(new_size);}
258 
259  virtual unsigned get_srate() const {return m_srate;}
260  virtual void set_srate(unsigned val) {m_srate=val;}
261  virtual unsigned get_channels() const {return m_nch;}
262  virtual unsigned get_channel_config() const {return m_setup;}
263  virtual void set_channels(unsigned val,unsigned setup) {m_nch = val;m_setup = setup;}
264  void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
265 
266  virtual t_size get_sample_count() const {return m_samples;}
267  virtual void set_sample_count(t_size val) {m_samples = val;}
268 
269  const t_self & operator=(const audio_chunk & p_source) {copy(p_source);return *this;}
270  const t_self & operator=(const t_self & p_source) {copy(p_source);return *this;}
271 };
272 
275 
278 public:
279  audio_chunk_memref_impl(const audio_sample * p_data,t_size p_samples,t_uint32 p_sample_rate,t_uint32 p_channels,t_uint32 p_channel_config) :
280  m_data(p_data), m_samples(p_samples), m_sample_rate(p_sample_rate), m_channels(p_channels), m_channel_config(p_channel_config)
281  {
282  PFC_ASSERT(is_valid());
283  }
284 
285  audio_sample * get_data() {throw pfc::exception_not_implemented();}
286  const audio_sample * get_data() const {return m_data;}
287  t_size get_data_size() const {return m_samples * m_channels;}
288  void set_data_size(t_size p_new_size) {throw pfc::exception_not_implemented();}
289 
290  unsigned get_srate() const {return m_sample_rate;}
291  void set_srate(unsigned val) {throw pfc::exception_not_implemented();}
292  unsigned get_channels() const {return m_channels;}
293  unsigned get_channel_config() const {return m_channel_config;}
294  void set_channels(unsigned p_count,unsigned p_config) {throw pfc::exception_not_implemented();}
295 
296  t_size get_sample_count() const {return m_samples;}
297 
298  void set_sample_count(t_size val) {throw pfc::exception_not_implemented();}
299 
300 private:
302  t_uint32 m_sample_rate,m_channels,m_channel_config;
304 };
305 
306 
307 // Compatibility typedefs.
311 
314 public:
315  duration_counter() : m_offset() {
316  }
317  void set(double v) {
318  m_sampleCounts.remove_all();
319  m_offset = v;
320  }
321  void reset() {
322  set(0);
323  }
324 
325  void add(double v) {m_offset += v;}
326  void subtract(double v) {m_offset -= v;}
327 
328  double query() const;
329  uint64_t queryAsSampleCount( uint32_t rate );
330 
331  void add(const audio_chunk & c) {
332  add(c.get_sample_count(), c.get_sample_rate());
333  }
334  void add(t_uint64 sampleCount, t_uint32 sampleRate) {
335  PFC_ASSERT( sampleRate > 0 );
336  if (sampleRate > 0 && sampleCount > 0) {
337  m_sampleCounts.find_or_add(sampleRate) += sampleCount;
338  }
339  }
340  void add(const duration_counter & other) {
341  add(other.m_offset);
342  for(t_map::const_iterator walk = other.m_sampleCounts.first(); walk.is_valid(); ++walk) {
343  add(walk->m_value, walk->m_key);
344  }
345  }
346  void subtract(const duration_counter & other) {
347  subtract(other.m_offset);
348  for(t_map::const_iterator walk = other.m_sampleCounts.first(); walk.is_valid(); ++walk) {
349  subtract(walk->m_value, walk->m_key);
350  }
351  }
352  void subtract(t_uint64 sampleCount, t_uint32 sampleRate) {
353  PFC_ASSERT( sampleRate > 0 );
354  if (sampleRate > 0 && sampleCount > 0) {
355  t_uint64 * val = m_sampleCounts.query_ptr(sampleRate);
356  if (val == NULL) throw pfc::exception_invalid_params();
357  if (*val < sampleCount) throw pfc::exception_invalid_params();
358  else if (*val == sampleCount) {
359  m_sampleCounts.remove(sampleRate);
360  } else {
361  *val -= sampleCount;
362  }
363 
364  }
365  }
366  void subtract(const audio_chunk & c) {
367  subtract(c.get_sample_count(), c.get_sample_rate());
368  }
369  template<typename t_source> duration_counter & operator+=(const t_source & source) {add(source); return *this;}
370  template<typename t_source> duration_counter & operator-=(const t_source & source) {subtract(source); return *this;}
371  template<typename t_source> duration_counter & operator=(const t_source & source) {reset(); add(source); return *this;}
372 private:
373  double m_offset;
376 };
377 
379 public:
380  audio_chunk_partial_ref(const audio_chunk & chunk, t_size base, t_size count) : audio_chunk_temp_impl(chunk.get_data() + base * chunk.get_channels(), count, chunk.get_sample_rate(), chunk.get_channels(), chunk.get_channel_config()) {}
381 };
virtual t_size get_data_size() const
Retrieves size of allocated buffer space, in audio_samples.
Definition: audio_chunk.h:256
audio_chunk_memref_impl(const audio_sample *p_data, t_size p_samples, t_uint32 p_sample_rate, t_uint32 p_channels, t_uint32 p_channel_config)
Definition: audio_chunk.h:279
Implementation of audio_chunk. Takes pfc allocator template as template parameter.
Definition: audio_chunk.h:242
duration_counter & operator-=(const t_source &source)
Definition: audio_chunk.h:370
audio_chunk_memref_impl audio_chunk_temp_impl
Definition: audio_chunk.h:310
void set_data_32(const float *src, t_size samples, unsigned nch, unsigned srate)
Definition: audio_chunk.h:180
uint64_t t_uint64
Definition: int_types.h:3
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
void add(const duration_counter &other)
Definition: audio_chunk.h:340
void reset()
Resets all audio_chunk data.
Definition: audio_chunk.h:140
pfc::map_t< t_uint32, t_uint64 > t_map
Definition: audio_chunk.h:374
void allocate(size_t size)
Sanity helper, same as set_data_size.
Definition: audio_chunk.h:79
unsigned get_sample_rate() const
Helper, same as get_srate().
Definition: audio_chunk.h:103
virtual void set_srate(unsigned val)
Sets sample rate of contained audio data.
Definition: audio_chunk.h:260
void set_sample_count(t_size val)
Sets number of valid samples in the buffer. WARNING: sample count * channel count should never be abo...
Definition: audio_chunk.h:298
container_t m_data
Definition: audio_chunk.h:244
const audio_sample * m_data
Definition: audio_chunk.h:303
Interface to container of a chunk of audio data. See audio_chunk_impl for an implementation.
Definition: audio_chunk.h:5
audio_chunk_impl_t audio_chunk_impl
Definition: audio_chunk.h:273
size_t get_data_length() const
Same as get_used_size(); old confusingly named version.
Definition: audio_chunk.h:136
Implements const methods of audio_chunk only, referring to an external buffer. For temporary use only...
Definition: audio_chunk.h:277
audio_chunk_impl_t(const audio_chunk &p_source)
Definition: audio_chunk.h:251
Duration counter class - accumulates duration using sample values, without any kind of rounding error...
Definition: audio_chunk.h:313
virtual unsigned get_channel_config() const
Retrieves channel map of contained audio data. Conditions where number of channels specified by chann...
Definition: audio_chunk.h:262
static const bool byte_order_is_big_endian
virtual unsigned get_channels() const =0
Retrieves channel count of contained audio data.
void subtract(double v)
Definition: audio_chunk.h:326
audio_sample * get_data()
Retrieves audio data buffer pointer (non-const version). Returned pointer is for temporary use only; ...
Definition: audio_chunk.h:285
bool is_valid() const
Definition: iterators.h:24
unsigned get_srate() const
Retrieves sample rate of contained audio data.
Definition: audio_chunk.h:290
virtual unsigned get_srate() const =0
Retrieves sample rate of contained audio data.
void set_data(const audio_sample *src, t_size samples, unsigned nch, unsigned srate)
Helper, sets chunk data to contents of specified buffer, with specified number of channels / sample r...
Definition: audio_chunk.h:151
void set_channels(unsigned p_count, unsigned p_config)
Sets channel count / channel map.
Definition: audio_chunk.h:294
virtual void set_channels(unsigned val, unsigned setup)
Sets channel count / channel map.
Definition: audio_chunk.h:263
void copy(const audio_chunk &p_source)
Helper; copies content of another audio chunk to this chunk.
Definition: audio_chunk.h:212
bool operator==(const spec_t &other) const
Definition: audio_chunk.h:226
audio_chunk_impl_t< pfc::mem_block_aligned_incremental_t< audio_sample, 16 > > audio_chunk_fast_impl
Definition: audio_chunk.h:274
duration_counter & operator=(const t_source &source)
Definition: audio_chunk.h:371
audio_chunk_impl_t< container_t > t_self
Definition: audio_chunk.h:243
PFC_DECLARE_EXCEPTION(exception_unexpected_audio_format_change, exception_io_data,"Unexpected audio format change")
Thrown when audio_chunk sample rate or channel mapping changes in mid-stream and the code receiving a...
virtual unsigned get_channel_config() const =0
Retrieves channel map of contained audio data. Conditions where number of channels specified by chann...
audio_chunk_fast_impl audio_chunk_impl_temporary
Definition: audio_chunk.h:308
static unsigned flags_autoendian()
Definition: audio_chunk.h:170
size_t t_size
Definition: int_types.h:48
t_size get_data_size() const
Retrieves size of allocated buffer space, in audio_samples.
Definition: audio_chunk.h:287
virtual audio_sample * get_data()=0
Retrieves audio data buffer pointer (non-const version). Returned pointer is for temporary use only; ...
void subtract(const duration_counter &other)
Definition: audio_chunk.h:346
virtual t_size get_sample_count() const
Retrieves number of valid samples in the buffer. Note that a "sample" means a unit of interleaved PC...
Definition: audio_chunk.h:266
void add(double v)
Definition: audio_chunk.h:325
virtual void set_sample_count(t_size val)
Sets number of valid samples in the buffer. WARNING: sample count * channel count should never be abo...
Definition: audio_chunk.h:267
virtual unsigned get_srate() const
Retrieves sample rate of contained audio data.
Definition: audio_chunk.h:259
void add(const audio_chunk &c)
Definition: audio_chunk.h:331
void add(t_uint64 sampleCount, t_uint32 sampleRate)
Definition: audio_chunk.h:334
audio_chunk_partial_ref(const audio_chunk &chunk, t_size base, t_size count)
Definition: audio_chunk.h:380
void set_data_fixedpoint(const void *ptr, t_size bytes, unsigned srate, unsigned nch, unsigned bps, unsigned channel_config)
Helper, sets chunk data to contents of specified buffer, using default win32/wav conventions for sign...
Definition: audio_chunk.h:156
audio_chunk_impl audio_chunk_i
Definition: audio_chunk.h:309
audio_chunk_impl_t(const t_self &p_source)
Definition: audio_chunk.h:252
audio_chunk_impl_t(const audio_sample *src, unsigned samples, unsigned nch, unsigned srate)
Definition: audio_chunk.h:249
void set_data_size(t_size p_new_size)
Resizes audio data buffer to specified size. Throws std::bad_alloc on failure.
Definition: audio_chunk.h:288
float audio_sample
Definition: audio_sample.h:6
unsigned get_channels() const
Retrieves channel count of contained audio data.
Definition: audio_chunk.h:292
duration_counter & operator+=(const t_source &source)
Definition: audio_chunk.h:369
iterator first()
Definition: map.h:229
void subtract(t_uint64 sampleCount, t_uint32 sampleRate)
Definition: audio_chunk.h:352
void subtract(const audio_chunk &c)
Definition: audio_chunk.h:366
bool operator!=(const spec_t &other) const
Definition: audio_chunk.h:227
virtual void set_data_size(t_size new_size)
Resizes audio data buffer to specified size. Throws std::bad_alloc on failure.
Definition: audio_chunk.h:257
const t_self & operator=(const t_self &p_source)
Definition: audio_chunk.h:270
virtual audio_sample * get_data()
Retrieves audio data buffer pointer (non-const version). Returned pointer is for temporary use only; ...
Definition: audio_chunk.h:254
virtual unsigned get_channels() const
Retrieves channel count of contained audio data.
Definition: audio_chunk.h:261
t_size get_sample_count() const
Retrieves number of valid samples in the buffer. Note that a "sample" means a unit of interleaved PC...
Definition: audio_chunk.h:296
Generic interface for a memory block; used by various other interfaces to return memory blocks while ...
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 grow_data_size(t_size p_requested)
Helper; resizes audio data buffer when its current size is smaller than requested.
Definition: audio_chunk.h:112
double get_duration() const
Retrieves duration of contained audio data, in seconds.
Definition: audio_chunk.h:116
virtual const audio_sample * get_data() const
Retrieves audio data buffer pointer (const version). Returned pointer is for temporary use only; it i...
Definition: audio_chunk.h:255
void set_srate(unsigned val)
Sets sample rate of contained audio data.
Definition: audio_chunk.h:291
const audio_sample * get_data() const
Retrieves audio data buffer pointer (const version). Returned pointer is for temporary use only; it i...
Definition: audio_chunk.h:286
unsigned get_channel_config() const
Retrieves channel map of contained audio data. Conditions where number of channels specified by chann...
Definition: audio_chunk.h:293
This is free and unencumbered software released into the public domain Anyone is free to copy
Definition: pfc-license.txt:3
const t_self & operator=(const audio_chunk &p_source)
Definition: audio_chunk.h:269
unsigned get_channel_count() const
Helper - for consistency - same as get_channels().
Definition: audio_chunk.h:88
void set_channels(unsigned val)
Definition: audio_chunk.h:264
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...
void set_channels(unsigned val)
Helper; sets channel count to specified value and uses default channel map for this channel count...
Definition: audio_chunk.h:108
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
size_t get_used_size() const
Returns actual amount of audio data contained in the buffer (sample count * channel count)...
Definition: audio_chunk.h:134
const audio_chunk & operator=(const audio_chunk &p_source)
Definition: audio_chunk.h:216
bool equals(const t1 &v1, const t2 &v2)
Definition: pathUtils.h:27