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