|
libpsynth 0.2.1
|
00001 00013 /* 00014 * Copyright (C) 2010 Juan Pedro Bolivar Puente 00015 * 00016 * This file is part of Psychosynth. 00017 * 00018 * Psychosynth is free software: you can redistribute it and/or modify 00019 * it under the terms of the GNU General Public License as published by 00020 * the Free Software Foundation, either version 3 of the License, or 00021 * (at your option) any later version. 00022 * 00023 * Psychosynth is distributed in the hope that it will be useful, 00024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00026 * GNU General Public License for more details. 00027 * 00028 * You should have received a copy of the GNU General Public License 00029 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00030 * 00031 */ 00032 00033 /* 00034 * Copyright 2005-2007 Adobe Systems Incorporated 00035 * 00036 * Use, modification and distribution are subject to the Boost 00037 * Software License, Version 1.0. (See accompanying file 00038 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). 00039 */ 00040 00041 #ifndef PSYNTH_SOUND_UTILITIES_H 00042 #define PSYNTH_SOUND_UTILITIES_H 00043 00044 #include <psynth/base/compat.hpp> 00045 00046 #include <functional> 00047 #include <boost/config/no_tr1/cmath.hpp> 00048 #include <cstddef> 00049 #include <algorithm> 00050 #include <utility> 00051 #include <iterator> 00052 00053 #include <boost/static_assert.hpp> 00054 #include <boost/mpl/size.hpp> 00055 #include <boost/mpl/distance.hpp> 00056 #include <boost/mpl/begin.hpp> 00057 #include <boost/mpl/find.hpp> 00058 #include <boost/mpl/range_c.hpp> 00059 #include <boost/iterator/iterator_adaptor.hpp> 00060 #include <boost/iterator/iterator_facade.hpp> 00061 00062 namespace psynth 00063 { 00064 namespace sound 00065 { 00066 00067 inline std::ptrdiff_t iround (float x) 00068 { return static_cast<std::ptrdiff_t>(x + (x < 0.0f ? -0.5f : 0.5f)); } 00069 inline std::ptrdiff_t iround (double x) 00070 { return static_cast<std::ptrdiff_t>(x + (x < 0.0 ? -0.5 : 0.5)); } 00071 inline std::ptrdiff_t ifloor (float x ) 00072 { return static_cast<std::ptrdiff_t> (std::floor(x)); } 00073 inline std::ptrdiff_t ifloor (double x) 00074 { return static_cast<std::ptrdiff_t> (std::floor(x)); } 00075 inline std::ptrdiff_t iceil (float x ) 00076 { return static_cast<std::ptrdiff_t> (std::ceil(x)); } 00077 inline std::ptrdiff_t iceil(double x) 00078 { return static_cast<std::ptrdiff_t> (std::ceil(x)); } 00079 00080 /* 00081 * 00082 * computing size with alignment 00083 * 00084 */ 00085 00086 template <typename T> 00087 inline T align (T val, std::size_t alignment) 00088 { 00089 return val + (alignment - val % alignment) % alignment; 00090 } 00091 00096 template <typename ConstT, typename Value, typename Reference, 00097 typename ConstReference, typename ArgType, typename ResultType, 00098 bool IsMutable> 00099 struct deref_base : public std::unary_function<ArgType, ResultType> 00100 { 00101 typedef ConstT const_type; 00102 typedef Value value_type; 00103 typedef Reference reference; 00104 typedef ConstReference const_reference; 00105 BOOST_STATIC_CONSTANT(bool, is_mutable = IsMutable); 00106 }; 00107 00115 template <typename D1, typename D2> 00116 class deref_compose : public deref_base< 00117 deref_compose<typename D1::const_type, 00118 typename D2::const_type>, 00119 typename D1::value_type, 00120 typename D1::reference, 00121 typename D1::const_reference, 00122 typename D2::argument_type, 00123 typename D1::result_type, 00124 D1::is_mutable && D2::is_mutable> 00125 { 00126 D1 _fn1; 00127 D2 _fn2; 00128 00129 public: 00130 typedef typename D2::argument_type argument_type; 00131 typedef typename D1::result_type result_type; 00132 00133 deref_compose () {} 00134 00135 deref_compose (const D1& x, const D2& y) 00136 : _fn1(x) 00137 , _fn2(y) {} 00138 00139 deref_compose (const deref_compose& dc) 00140 : _fn1(dc._fn1) 00141 , _fn2(dc._fn2) {} 00142 00143 template <typename _D1, typename _D2> 00144 deref_compose (const deref_compose<_D1,_D2>& dc) 00145 : _fn1(dc._fn1) 00146 , _fn2(dc._fn2) {} 00147 00148 result_type operator() (argument_type x) const { return _fn1(_fn2 (x)); } 00149 result_type operator() (argument_type x) { return _fn1(_fn2 (x)); } 00150 }; 00151 00152 /* reinterpret_cast is implementation-defined. Static cast is not. */ 00153 template <typename OutPtr, typename In> PSYNTH_FORCEINLINE 00154 OutPtr psynth_reinterpret_cast (In* p) 00155 { 00156 return static_cast<OutPtr> (static_cast<void*> (p)); 00157 } 00158 00159 template <typename OutPtr, typename In> PSYNTH_FORCEINLINE 00160 const OutPtr psynth_reinterpret_cast_c(const In* p) 00161 { 00162 return static_cast<const OutPtr>(static_cast<const void*>(p)); 00163 } 00164 00165 namespace detail 00166 { 00167 00171 template <class InputIter, class Size, class OutputIter> 00172 std::pair<InputIter, OutputIter> do_copy_n (InputIter first, Size count, 00173 OutputIter result, 00174 std::input_iterator_tag) 00175 { 00176 for ( ; count > 0; --count) { 00177 *result = *first; 00178 ++first; 00179 ++result; 00180 } 00181 return std::pair<InputIter, OutputIter>(first, result); 00182 } 00183 00184 template <class RAIter, class Size, class OutputIter> 00185 inline std::pair<RAIter, OutputIter> 00186 do_copy_n (RAIter first, Size count, OutputIter result, 00187 std::random_access_iterator_tag) 00188 { 00189 RAIter last = first + count; 00190 return std::pair<RAIter, OutputIter>(last, std::copy(first, last, result)); 00191 } 00192 00193 template <class InputIter, class Size, class OutputIter> 00194 inline std::pair<InputIter, OutputIter> 00195 do_copy_n (InputIter first, Size count, OutputIter result) 00196 { 00197 return do_copy_n ( 00198 first, count, result, 00199 typename std::iterator_traits<InputIter>::iterator_category()); 00200 } 00201 00202 template <class InputIter, class Size, class OutputIter> 00203 inline std::pair<InputIter, OutputIter> 00204 copy_n (InputIter first, Size count, OutputIter result) 00205 { 00206 return detail::do_copy_n (first, count, result); 00207 } 00208 00210 template <typename T> 00211 struct identity : public std::unary_function<T,T> { 00212 const T& operator()(const T& val) const { return val; } 00213 }; 00214 00215 00218 template <typename T1, typename T2> 00219 struct plus_asymmetric : public std::binary_function<T1,T2,T1> { 00220 T1 operator()(T1 f1, T2 f2) const { 00221 return f1+f2; 00222 } 00223 }; 00224 00226 template <typename T> 00227 struct inc : public std::unary_function<T,T> 00228 { 00229 T operator () (T x) const { return ++x; } 00230 }; 00231 00233 template <typename T> 00234 struct dec : public std::unary_function<T,T> 00235 { 00236 T operator () (T x) const { return --x; } 00237 }; 00238 00244 template <typename Types, typename T> 00245 struct type_to_index 00246 : public boost::mpl::distance< 00247 typename boost::mpl::begin<Types>::type, 00248 typename boost::mpl::find<Types,T>::type>::type {}; 00249 00250 } /* namespace detail */ 00251 00252 00257 template <typename ChannelSpace, 00258 typename SampleMapping = boost::mpl::range_c< 00259 int, 0, boost::mpl::size<ChannelSpace>::value> > 00260 struct layout 00261 { 00262 typedef ChannelSpace channel_space; 00263 typedef SampleMapping sample_mapping; 00264 }; 00265 00270 template <typename Value, typename T1, typename T2> 00271 // where value_type<T1> == value_type<T2> == Value 00272 void swap_proxy (T1& left, T2& right) 00273 { 00274 Value tmp = left; 00275 left = right; 00276 right = tmp; 00277 } 00278 00283 inline bool little_endian () 00284 { 00285 short tester = 0x0001; 00286 return *(char*)&tester!=0; 00287 } 00288 00293 inline bool big_endian() 00294 { 00295 return !little_endian(); 00296 } 00297 00298 } /* namespace sound */ 00299 } /* namespace psynth */ 00300 00301 #endif /* PSYNTH_SOUND_UTIL */
1.7.4