BEAST/BSE - Better Audio System and Sound Engine
0.8.2
|
00001 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __BSE_BLOCK_UTILS_H__ 00003 #define __BSE_BLOCK_UTILS_H__ 00004 #include <wchar.h> /* wmemset */ 00005 #include <bse/bseieee754.hh> 00006 00007 00008 template<class TYPE> inline 00009 void bse_block_fill_0 (size_t n_values, /* 4-byte variant of memset */ 00010 TYPE *values); 00011 /* --- C API --- */ 00012 G_BEGIN_DECLS 00013 const 00014 char* bse_block_impl_name (void); 00015 static inline 00016 void bse_block_fill_uint32 (guint n_values, /* 4-byte variant of memset for ints */ 00017 guint32 *values, 00018 guint32 vuint32); 00019 static inline 00020 void bse_block_fill_float (uint n_values, /* 4-byte variant of memset for floats */ 00021 float *values, 00022 const float value); 00023 static inline 00024 void bse_block_copy_uint32 (guint n_values, /* 4-byte variant of memcpy for ints */ 00025 guint32 *values, 00026 const guint32 *ivalues); 00027 static inline 00028 void bse_block_copy_float (guint n_values, /* 4-byte variant of memcpy for floats */ 00029 gfloat *values, 00030 const gfloat *ivalues); 00031 void bse_block_add_floats (guint n_values, 00032 float *ovalues, 00033 const float *ivalues); 00034 void bse_block_sub_floats (guint n_values, 00035 float *ovalues, 00036 const float *ivalues); 00037 void bse_block_mul_floats (guint n_values, 00038 float *ovalues, 00039 const float *ivalues); 00040 void bse_block_scale_floats (guint n_values, 00041 float *ovalues, 00042 const float *ivalues, 00043 const float level); 00044 void bse_block_interleave2_floats (guint n_ivalues, 00045 float *ovalues, /* length_ovalues = n_ivalues * 2 */ 00046 const float *ivalues, 00047 guint offset); /* 0=left, 1=right */ 00048 void bse_block_interleave2_add_floats (guint n_ivalues, 00049 float *ovalues, /* length_ovalues = n_ivalues * 2 */ 00050 const float *ivalues, 00051 guint offset); /* 0=left, 1=right */ 00052 void bse_block_calc_float_range (guint n_values, 00053 const float *ivalues, 00054 float *min_value, 00055 float *max_value); 00056 float bse_block_calc_float_square_sum (guint n_values, 00057 const float *ivalues); 00058 float bse_block_calc_float_range_and_square_sum (guint n_values, 00059 const float *ivalues, 00060 float *min_value, 00061 float *max_value); 00062 00063 G_END_DECLS 00064 00065 #ifdef __cplusplus 00066 #include <bse/bseresampler.hh> 00067 namespace Bse { 00068 00069 /* --- C++ API --- */ 00070 class Block { 00071 public: 00072 static const char* impl_name () { return singleton->impl_name (); } 00073 static inline void fill (guint n_values, 00074 float *values, 00075 float value); 00076 static inline void fill (guint n_values, 00077 guint32 *values, 00078 guint32 value); 00079 static inline void copy (guint n_values, 00080 float *values, 00081 const float *ivalues); 00082 static inline void copy (guint n_values, 00083 guint32 *values, 00084 const guint32 *ivalues); 00085 static inline void add (guint n_values, 00086 float *ovalues, 00087 const float *ivalues) { singleton->add (n_values, ovalues, ivalues); } 00088 static inline void sub (guint n_values, 00089 float *ovalues, 00090 const float *ivalues) { singleton->sub (n_values, ovalues, ivalues); } 00091 static inline void mul (guint n_values, 00092 float *ovalues, 00093 const float *ivalues) { singleton->mul (n_values, ovalues, ivalues); } 00094 static inline void scale (guint n_values, 00095 float *ovalues, 00096 const float *ivalues, 00097 const float level) { singleton->scale (n_values, ovalues, ivalues, level); } 00098 static inline void interleave2 (guint n_ivalues, 00099 float *ovalues, 00100 const float *ivalues, 00101 guint offset) { singleton->interleave2 (n_ivalues, ovalues, ivalues, offset); } 00102 static inline void interleave2_add (guint n_ivalues, 00103 float *ovalues, 00104 const float *ivalues, 00105 guint offset) { singleton->interleave2_add (n_ivalues, ovalues, ivalues, offset); } 00106 static inline void range (guint n_values, 00107 const float *ivalues, 00108 float& min_value, 00109 float& max_value) { singleton->range (n_values, ivalues, min_value, max_value); } 00110 static inline float square_sum (guint n_values, 00111 const float *ivalues) { return singleton->square_sum (n_values, ivalues); } 00112 static inline float range_and_square_sum (guint n_values, 00113 const float *ivalues, 00114 float& min_value, 00115 float& max_value) { return singleton->range_and_square_sum (n_values, ivalues, min_value, max_value); } 00116 00117 typedef Resampler::Resampler2 Resampler2; 00118 static inline 00119 Resampler2* create_resampler2 (BseResampler2Mode mode, 00120 BseResampler2Precision precision) { return singleton->create_resampler2 (mode, precision); } 00121 static inline 00122 bool test_resampler2 (bool verbose) { return singleton->test_resampler2 (verbose); } 00123 00124 00125 00126 class Impl { 00127 protected: 00128 virtual ~Impl (); 00129 virtual const char* impl_name () = 0; 00130 virtual void add (guint n_values, 00131 float *ovalues, 00132 const float *ivalues) = 0; 00133 virtual void sub (guint n_values, 00134 float *ovalues, 00135 const float *ivalues) = 0; 00136 virtual void mul (guint n_values, 00137 float *ovalues, 00138 const float *ivalues) = 0; 00139 virtual void scale (guint n_values, 00140 float *ovalues, 00141 const float *ivalues, 00142 const float level) = 0; 00143 virtual void interleave2 (guint n_ivalues, 00144 float *ovalues, /* length_ovalues = n_ivalues * 2 */ 00145 const float *ivalues, 00146 guint offset) = 0; /* 0=left, 1=right */ 00147 virtual void interleave2_add (guint n_ivalues, 00148 float *ovalues, /* length_ovalues = n_ivalues * 2 */ 00149 const float *ivalues, 00150 guint offset) = 0; /* 0=left, 1=right */ 00151 virtual void range (guint n_values, 00152 const float *ivalues, 00153 float& min_value, 00154 float& max_value) = 0; 00155 virtual float square_sum (guint n_values, 00156 const float *ivalues) = 0; 00157 virtual float range_and_square_sum (guint n_values, 00158 const float *ivalues, 00159 float& min_value, 00160 float& max_value) = 0; 00161 virtual 00162 Resampler2* create_resampler2 (BseResampler2Mode mode, 00163 BseResampler2Precision precision) = 0; 00164 virtual bool test_resampler2 (bool verbose) = 0; 00165 friend class Block; 00166 static void substitute (Impl *substitute_impl); 00167 }; 00168 static Impl* default_singleton (); 00169 static Impl* current_singleton (); 00170 private: 00171 static Impl *singleton; 00172 }; 00173 00174 /* --- C++ implementation bits --- */ 00175 inline void 00176 Block::fill (guint n_values, 00177 float *values, 00178 float value) 00179 { 00180 RAPICORN_STATIC_ASSERT (sizeof (float) == 4); 00181 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00182 const union { float f; guint32 vuint32; } u = { value }; 00183 wmemset ((wchar_t*) values, u.vuint32, n_values); 00184 } 00185 00186 inline void 00187 Block::fill (guint n_values, 00188 guint32 *values, 00189 guint32 value) 00190 { 00191 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00192 wmemset ((wchar_t*) values, value, n_values); 00193 } 00194 00195 inline void 00196 Block::copy (guint n_values, 00197 guint32 *values, 00198 const guint32 *ivalues) 00199 { 00200 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00201 wmemcpy ((wchar_t*) values, (const wchar_t*) ivalues, n_values); 00202 } 00203 00204 inline void 00205 Block::copy (guint n_values, 00206 gfloat *values, 00207 const gfloat *ivalues) 00208 { 00209 RAPICORN_STATIC_ASSERT (sizeof (float) == 4); 00210 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00211 wmemcpy ((wchar_t*) values, (const wchar_t*) ivalues, n_values); 00212 } 00213 00214 } // Bse 00215 #endif /* __cplusplus */ 00216 00217 /* --- C implementation bits --- */ 00218 G_BEGIN_DECLS 00219 00220 static inline void 00221 bse_block_fill_uint32 (guint n_values, 00222 guint32 *values, 00223 guint32 vuint32) 00224 { 00225 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00226 wmemset ((wchar_t*) values, vuint32, n_values); 00227 } 00228 00229 static inline void 00230 bse_block_fill_float (guint n_values, 00231 float *values, 00232 const float value) 00233 { 00234 RAPICORN_STATIC_ASSERT (sizeof (float) == 4); 00235 const union { float f; guint32 vuint32; } u = { value }; 00236 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00237 wmemset ((wchar_t*) values, u.vuint32, n_values); 00238 } 00239 00240 static inline void 00241 bse_block_copy_uint32 (guint n_values, 00242 guint32 *values, 00243 const guint32 *ivalues) 00244 { 00245 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00246 wmemcpy ((wchar_t*) values, (const wchar_t*) ivalues, n_values); 00247 } 00248 00249 static inline void 00250 bse_block_copy_float (guint n_values, 00251 gfloat *values, 00252 const gfloat *ivalues) 00253 { 00254 RAPICORN_STATIC_ASSERT (sizeof (float) == 4); 00255 RAPICORN_STATIC_ASSERT (sizeof (wchar_t) == 4); 00256 wmemcpy ((wchar_t*) values, (const wchar_t*) ivalues, n_values); 00257 } 00258 G_END_DECLS 00259 00260 // == C++ Implementations == 00261 template<class TYPE> inline void 00262 bse_block_fill_0 (size_t n_values, TYPE *values) 00263 { 00264 size_t n_bytes = n_values * sizeof (TYPE); 00265 char *p = (char*) values; 00266 uint r = size_t (p) & 3; 00267 if (UNLIKELY (r)) 00268 { 00269 r = MIN (r, n_values); // rest for pointer alignment 00270 memset (p, 0, r); 00271 p += r; 00272 n_bytes -= r; 00273 } 00274 const size_t n_aligned = n_bytes / 4; 00275 wmemset ((wchar_t*) p, 0, n_aligned); 00276 n_bytes -= n_aligned * 4; 00277 if (UNLIKELY (n_bytes)) 00278 { 00279 p += n_aligned * 4; 00280 memset (p, 0, n_bytes); 00281 } 00282 } 00283 00284 #endif /* __BSE_BLOCK_UTILS_H__ */