00001 #ifndef _AUDIO_CHUNK_H_
00002 #define _AUDIO_CHUNK_H_
00003
00005 class NOVTABLE audio_chunk {
00006 public:
00007
00009 enum
00010 {
00011 channel_front_left = 1<<0,
00012 channel_front_right = 1<<1,
00013 channel_front_center = 1<<2,
00014 channel_lfe = 1<<3,
00015 channel_back_left = 1<<4,
00016 channel_back_right = 1<<5,
00017 channel_front_center_left = 1<<6,
00018 channel_front_center_right = 1<<7,
00019 channel_back_center = 1<<8,
00020 channel_side_left = 1<<9,
00021 channel_side_right = 1<<10,
00022 channel_top_center = 1<<11,
00023 channel_top_front_left = 1<<12,
00024 channel_top_front_center = 1<<13,
00025 channel_top_front_right = 1<<14,
00026 channel_top_back_left = 1<<15,
00027 channel_top_back_center = 1<<16,
00028 channel_top_back_right = 1<<17,
00029
00030 channel_config_mono = channel_front_center,
00031 channel_config_stereo = channel_front_left | channel_front_right,
00032 channel_config_5point1 = channel_front_left | channel_front_right | channel_back_left | channel_back_right | channel_front_center | channel_lfe,
00033
00034 defined_channel_count = 18,
00035 };
00036
00038 static unsigned g_guess_channel_config(unsigned count);
00039
00040 #ifdef _WIN32
00042 static DWORD g_channel_config_to_wfx(unsigned p_config);
00044 static unsigned g_channel_config_from_wfx(DWORD p_wfx);
00045 #endif
00046
00048 static unsigned g_extract_channel_flag(unsigned p_config,unsigned p_index);
00050 static unsigned g_count_channels(unsigned p_config);
00052 static unsigned g_channel_index_from_flag(unsigned p_config,unsigned p_flag);
00053
00054
00055
00058 virtual audio_sample * get_data() = 0;
00061 virtual const audio_sample * get_data() const = 0;
00063 virtual t_size get_data_size() const = 0;
00065 virtual void set_data_size(t_size p_new_size) = 0;
00066
00068 virtual unsigned get_srate() const = 0;
00070 virtual void set_srate(unsigned val) = 0;
00072 virtual unsigned get_channels() const = 0;
00074 virtual unsigned get_channel_config() const = 0;
00076 virtual void set_channels(unsigned p_count,unsigned p_config) = 0;
00077
00081 virtual t_size get_sample_count() const = 0;
00082
00084 virtual void set_sample_count(t_size val) = 0;
00085
00087 inline unsigned get_sample_rate() const {return get_srate();}
00089 inline void set_sample_rate(unsigned val) {set_srate(val);}
00090
00092 void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
00093
00094
00096 inline void grow_data_size(t_size p_requested) {if (p_requested > get_data_size()) set_data_size(p_requested);}
00097
00098
00100 inline double get_duration() const
00101 {
00102 double rv = 0;
00103 t_size srate = get_srate (), samples = get_sample_count();
00104 if (srate>0 && samples>0) rv = (double)samples/(double)srate;
00105 return rv;
00106 }
00107
00109 inline bool is_empty() const {return get_channels()==0 || get_srate()==0 || get_sample_count()==0;}
00110
00112 bool is_valid() const;
00113
00115 inline t_size get_data_length() const {return get_sample_count() * get_channels();}
00116
00118 inline void reset() {
00119 set_sample_count(0);
00120 set_srate(0);
00121 set_channels(0);
00122 set_data_size(0);
00123 }
00124
00126 void set_data(const audio_sample * src,t_size samples,unsigned nch,unsigned srate,unsigned channel_config);
00127
00129 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));}
00130
00132 inline void set_data_fixedpoint(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
00133 set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,(bps==8 ? FLAG_UNSIGNED : FLAG_SIGNED) | flags_autoendian(), channel_config);
00134 }
00135
00136 inline void set_data_fixedpoint_unsigned(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
00137 return set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,FLAG_UNSIGNED | flags_autoendian(), channel_config);
00138 }
00139
00140 inline void set_data_fixedpoint_signed(const void * ptr,t_size bytes,unsigned srate,unsigned nch,unsigned bps,unsigned channel_config) {
00141 return set_data_fixedpoint_ex(ptr,bytes,srate,nch,bps,FLAG_SIGNED | flags_autoendian(), channel_config);
00142 }
00143
00144 enum
00145 {
00146 FLAG_LITTLE_ENDIAN = 1,
00147 FLAG_BIG_ENDIAN = 2,
00148 FLAG_SIGNED = 4,
00149 FLAG_UNSIGNED = 8,
00150 };
00151
00152 inline static unsigned flags_autoendian() {
00153 return pfc::byte_order_is_big_endian ? FLAG_BIG_ENDIAN : FLAG_LITTLE_ENDIAN;
00154 }
00155
00156 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);
00157
00158 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);
00159
00160 inline void set_data_32(const float * src,t_size samples,unsigned nch,unsigned srate) {return set_data(src,samples,nch,srate);}
00161
00162 void pad_with_silence_ex(t_size samples,unsigned hint_nch,unsigned hint_srate);
00163 void pad_with_silence(t_size samples);
00164 void insert_silence_fromstart(t_size samples);
00165 t_size skip_first_samples(t_size samples);
00166
00167
00169 audio_sample get_peak(audio_sample p_peak = 0) const;
00170
00172 void scale(audio_sample p_value);
00173
00175 void copy(const audio_chunk & p_source) {
00176 set_data(p_source.get_data(),p_source.get_sample_count(),p_source.get_channels(),p_source.get_srate(),p_source.get_channel_config());
00177 }
00178
00179 const audio_chunk & operator=(const audio_chunk & p_source) {
00180 copy(p_source);
00181 return *this;
00182 }
00183 protected:
00184 audio_chunk() {}
00185 ~audio_chunk() {}
00186 };
00187
00189 template<template<typename> class t_alloc = pfc::alloc_standard>
00190 class audio_chunk_impl_t : public audio_chunk {
00191 typedef audio_chunk_impl_t<t_alloc> t_self;
00192 pfc::array_t<audio_sample,t_alloc> m_data;
00193 unsigned m_srate,m_nch,m_setup;
00194 t_size m_samples;
00195 public:
00196 audio_chunk_impl_t() : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {}
00197 audio_chunk_impl_t(const audio_sample * src,unsigned samples,unsigned nch,unsigned srate) : m_srate(0), m_nch(0), m_samples(0)
00198 {set_data(src,samples,nch,srate);}
00199 audio_chunk_impl_t(const audio_chunk & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
00200 audio_chunk_impl_t(const t_self & p_source) : m_srate(0), m_nch(0), m_samples(0), m_setup(0) {copy(p_source);}
00201
00202 virtual audio_sample * get_data() {return m_data.get_ptr();}
00203 virtual const audio_sample * get_data() const {return m_data.get_ptr();}
00204 virtual t_size get_data_size() const {return m_data.get_size();}
00205 virtual void set_data_size(t_size new_size) {m_data.set_size(new_size);}
00206
00207 virtual unsigned get_srate() const {return m_srate;}
00208 virtual void set_srate(unsigned val) {m_srate=val;}
00209 virtual unsigned get_channels() const {return m_nch;}
00210 virtual unsigned get_channel_config() const {return m_setup;}
00211 virtual void set_channels(unsigned val,unsigned setup) {m_nch = val;m_setup = setup;}
00212 void set_channels(unsigned val) {set_channels(val,g_guess_channel_config(val));}
00213
00214 virtual t_size get_sample_count() const {return m_samples;}
00215 virtual void set_sample_count(t_size val) {m_samples = val;}
00216
00217 const t_self & operator=(const audio_chunk & p_source) {copy(p_source);return *this;}
00218 const t_self & operator=(const t_self & p_source) {copy(p_source);return *this;}
00219 };
00220
00221 typedef audio_chunk_impl_t<> audio_chunk_impl;
00222 typedef audio_chunk_impl audio_chunk_i;
00223
00225 class audio_chunk_temp_impl : public audio_chunk {
00226 public:
00227 audio_chunk_temp_impl(const audio_sample * p_data,t_size p_samples,t_uint32 p_sample_rate,t_uint32 p_channels,t_uint32 p_channel_config) :
00228 m_data(p_data), m_samples(p_samples), m_sample_rate(p_sample_rate), m_channels(p_channels), m_channel_config(p_channel_config)
00229 {
00230 PFC_ASSERT(is_valid());
00231 }
00232
00233 audio_sample * get_data() {throw pfc::exception_not_implemented();}
00234 const audio_sample * get_data() const {return m_data;}
00235 t_size get_data_size() const {return m_samples * m_channels;}
00236 void set_data_size(t_size p_new_size) {throw pfc::exception_not_implemented();}
00237
00238 unsigned get_srate() const {return m_sample_rate;}
00239 void set_srate(unsigned val) {throw pfc::exception_not_implemented();}
00240 unsigned get_channels() const {return m_channels;}
00241 unsigned get_channel_config() const {return m_channel_config;}
00242 void set_channels(unsigned p_count,unsigned p_config) {throw pfc::exception_not_implemented();}
00243
00244 t_size get_sample_count() const {return m_samples;}
00245
00246 void set_sample_count(t_size val) {throw pfc::exception_not_implemented();}
00247
00248 private:
00249 t_size m_samples;
00250 t_uint32 m_sample_rate,m_channels,m_channel_config;
00251 const audio_sample * m_data;
00252 };
00253
00254 #endif //_AUDIO_CHUNK_H_