|
libpsynth 0.2.1
|
00001 00011 /* 00012 * Copyright (C) 2010 Juan Pedro Bolivar Puente 00013 * 00014 * This file is part of Psychosynth. 00015 * 00016 * Psychosynth is free software: you can redistribute it and/or modify 00017 * it under the terms of the GNU General Public License as published by 00018 * the Free Software Foundation, either version 3 of the License, or 00019 * (at your option) any later version. 00020 * 00021 * Psychosynth is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU General Public License 00027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00028 * 00029 */ 00030 00031 /* 00032 * Copyright 2005-2007 Adobe Systems Incorporated 00033 * 00034 * Use, modification and distribution are subject to the Boost 00035 * Software License, Version 1.0. (See accompanying file 00036 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). 00037 */ 00038 00039 #ifndef PSYNTH_SAMPLE_ALGORITHM_HPP 00040 #define PSYNTH_SAMPLE_ALGORITHM_HPP 00041 00042 #include <psynth/base/compat.hpp> 00043 #include <psynth/sound/sample.hpp> 00044 00045 #include <boost/mpl/less.hpp> 00046 #include <boost/mpl/integral_c.hpp> 00047 #include <boost/mpl/greater.hpp> 00048 #include <boost/type_traits.hpp> 00049 00050 namespace psynth 00051 { 00052 namespace sound 00053 { 00054 00055 //#ifdef _MSC_VER 00056 //#pragma warning(push) 00057 //#pragma warning(disable: 4309) 00058 // disable truncation of constant value warning (using -1 to get the 00059 // max value of an integral) 00060 //#endif 00061 00062 namespace detail 00063 { 00064 00065 /* some forward declarations */ 00066 template <typename SrcSampleV, typename DstSampleV, 00067 bool SrcIsIntegral, bool DstIsIntegral> 00068 struct sample_converter_unsigned_impl; 00069 template <typename SrcSampleV, typename DstSampleV, 00070 bool SrcIsGreater> 00071 struct sample_converter_unsigned_integral; 00072 template <typename SrcSampleV, typename DstSampleV, 00073 bool SrcLessThanDst, bool SrcDivisible> 00074 struct sample_converter_unsigned_integral_impl; 00075 template <typename SrcSampleV, typename DstSampleV, 00076 bool SrcLessThanDst, bool CannotFitInInteger> 00077 struct sample_converter_unsigned_integral_nondivisible; 00078 00084 template <typename UnsignedIntegralSample> 00085 struct unsigned_integral_max_value : 00086 public boost::mpl::integral_c<UnsignedIntegralSample, -1> {}; 00087 00088 template <> 00089 struct unsigned_integral_max_value<uint8_t> : 00090 public boost::mpl::integral_c<uint32_t, 0xFF> {}; 00091 template <> 00092 struct unsigned_integral_max_value<uint16_t> : 00093 public boost::mpl::integral_c<uint32_t, 0xFFFF> {}; 00094 template <> 00095 struct unsigned_integral_max_value<uint32_t> : 00096 public boost::mpl::integral_c<uintmax_t, 0xFFFFFFFF> {}; 00097 00098 template <int K> 00099 struct unsigned_integral_max_value<packed_sample_value<K> > 00100 : public boost::mpl::integral_c< 00101 typename packed_sample_value<K>::integer_t, (1 << K) - 1> {}; 00102 00108 template <typename UnsignedIntegralSample> 00109 struct unsigned_integral_num_bits : 00110 public boost::mpl::int_<sizeof(UnsignedIntegralSample)*8> {}; 00111 00112 template <int K> 00113 struct unsigned_integral_num_bits<packed_sample_value<K> > 00114 : public boost::mpl::int_<K> {}; 00115 00116 } /* namespace detail */ 00117 00162 template <typename SrcSampleV, typename DstSampleV> 00163 // Model SampleValueConcept 00164 struct sample_converter_unsigned 00165 : public detail::sample_converter_unsigned_impl< 00166 SrcSampleV, DstSampleV, 00167 boost::is_integral<SrcSampleV>::value, 00168 boost::is_integral<DstSampleV>::value> 00169 {}; 00170 00172 template <typename T> struct sample_converter_unsigned<T,T> : 00173 public detail::identity<T> {}; 00174 00175 00176 namespace detail 00177 { 00178 00187 template <typename SrcSampleV, typename DstSampleV, 00188 bool SrcIsIntegral, bool DstIsIntegral> 00189 struct sample_converter_unsigned_impl : 00190 public std::unary_function <DstSampleV, SrcSampleV> 00191 { 00192 DstSampleV operator () (SrcSampleV src) const 00193 { 00194 return DstSampleV ( 00195 sample_traits<DstSampleV>::min_value() + 00196 (src - sample_traits<SrcSampleV>::min_value()) / 00197 sample_range<SrcSampleV>() * sample_range<DstSampleV> ()); 00198 } 00199 00200 private: 00201 template <typename C> 00202 static double sample_range () 00203 { 00204 return double (sample_traits<C>::max_value ()) - 00205 double (sample_traits<C>::min_value ()); 00206 } 00207 }; 00208 00209 // When both the source and the destination are integral samples, 00210 // perform a faster conversion 00211 template <typename SrcSampleV, typename DstSampleV> 00212 struct sample_converter_unsigned_impl<SrcSampleV, DstSampleV, true, true> 00213 : public sample_converter_unsigned_integral<SrcSampleV, DstSampleV, 00214 boost::mpl::less<unsigned_integral_max_value<SrcSampleV>, 00215 unsigned_integral_max_value<DstSampleV> >::value > {}; 00216 00217 00222 template <typename SrcSampleV, typename DstSampleV> 00223 struct sample_converter_unsigned_integral<SrcSampleV, DstSampleV, true> 00224 : public sample_converter_unsigned_integral_impl< 00225 SrcSampleV, DstSampleV, true, 00226 !(unsigned_integral_max_value<DstSampleV>::value % 00227 unsigned_integral_max_value<SrcSampleV>::value)> {}; 00228 00229 template <typename SrcSampleV, typename DstSampleV> 00230 struct sample_converter_unsigned_integral<SrcSampleV,DstSampleV, false> 00231 : public sample_converter_unsigned_integral_impl< 00232 SrcSampleV, DstSampleV, false, 00233 !(unsigned_integral_max_value<SrcSampleV>::value % 00234 unsigned_integral_max_value<DstSampleV>::value) > {}; 00235 00236 00241 /* 00242 Both source and destination are unsigned integral samples, the src 00243 max value is less than the dst max value, and the dst max value is 00244 divisible by the src max value 00245 */ 00246 template <typename SrcSampleV, typename DstSampleV> 00247 struct sample_converter_unsigned_integral_impl<SrcSampleV, DstSampleV, true, true> 00248 { 00249 DstSampleV operator () (SrcSampleV src) const 00250 { 00251 typedef typename unsigned_integral_max_value<DstSampleV>::value_type 00252 integer_t; 00253 static const integer_t mul = 00254 unsigned_integral_max_value<DstSampleV>::value / 00255 unsigned_integral_max_value<SrcSampleV>::value; 00256 return DstSampleV (src * mul); 00257 } 00258 }; 00259 00260 /* 00261 Both source and destination are unsigned integral samples, the dst 00262 max value is less than (or equal to) the src max value, and the src 00263 max value is divisible by the dst max value 00264 */ 00265 template <typename SrcSampleV, typename DstSampleV> 00266 struct sample_converter_unsigned_integral_impl<SrcSampleV,DstSampleV, false, true> 00267 { 00268 DstSampleV operator () (SrcSampleV src) const 00269 { 00270 typedef typename unsigned_integral_max_value<SrcSampleV>::value_type 00271 integer_t; 00272 static const integer_t div = 00273 unsigned_integral_max_value<SrcSampleV>::value / 00274 unsigned_integral_max_value<DstSampleV>::value; 00275 static const integer_t div2 = div / 2; 00276 return DstSampleV ((src + div2) / div); 00277 } 00278 }; 00279 00280 /* Prevent overflow for the largest integral type */ 00281 template <typename DstSampleV> 00282 struct sample_converter_unsigned_integral_impl<uintmax_t, DstSampleV, false, true> 00283 { 00284 DstSampleV operator () (uintmax_t src) const 00285 { 00286 static const uintmax_t div = 00287 unsigned_integral_max_value<bits32>::value / 00288 unsigned_integral_max_value<DstSampleV>::value; 00289 static const uintmax_t div2 = div/2; 00290 if (src > unsigned_integral_max_value<uintmax_t>::value - div2) 00291 return unsigned_integral_max_value<DstSampleV>::value; 00292 return DstSampleV ((src + div2) / div); 00293 } 00294 }; 00295 00296 /* 00297 Both source and destination are unsigned integral samples, and the 00298 dst max value is not divisible by the src max value See if you can 00299 represent the expression (src * dst_max) / src_max in integral form 00300 */ 00301 template <typename SrcSampleV, typename DstSampleV, bool SrcLessThanDst> 00302 struct sample_converter_unsigned_integral_impl<SrcSampleV, DstSampleV, 00303 SrcLessThanDst, false> 00304 : public sample_converter_unsigned_integral_nondivisible< 00305 SrcSampleV, DstSampleV, 00306 SrcLessThanDst, 00307 boost::mpl::greater< 00308 boost::mpl::plus<unsigned_integral_num_bits<SrcSampleV>, 00309 unsigned_integral_num_bits<DstSampleV> >, 00310 unsigned_integral_num_bits<uintmax_t> >::value> 00311 {}; 00312 00313 00314 /* 00315 Both source and destination are unsigned integral samples, the src 00316 max value is less than the dst max value, and the dst max value is 00317 not divisible by the src max value The expression (src * dst_max) / 00318 src_max fits in an integer 00319 */ 00320 template <typename SrcSampleV, typename DstSampleV> 00321 struct sample_converter_unsigned_integral_nondivisible< 00322 SrcSampleV, DstSampleV, true, false> 00323 { 00324 DstSampleV operator () (SrcSampleV src) const 00325 { 00326 typedef typename detail::min_fast_uint< 00327 unsigned_integral_num_bits<SrcSampleV>::value + 00328 unsigned_integral_num_bits<DstSampleV>::value>::type integer_t; 00329 00330 return DstSampleV ( 00331 integer_t (src * unsigned_integral_max_value<DstSampleV>::value) / 00332 unsigned_integral_max_value<SrcSampleV>::value); 00333 } 00334 }; 00335 00336 /* 00337 Both source and destination are unsigned integral samples, the src 00338 max value is less than the dst max value, and the dst max value is 00339 not divisible by the src max value The expression (src * dst_max) / 00340 src_max cannot fit in an integer (overflows). Use a double 00341 */ 00342 template <typename SrcSampleV, typename DstSampleV> 00343 struct sample_converter_unsigned_integral_nondivisible < 00344 SrcSampleV, DstSampleV, true, true> 00345 { 00346 DstSampleV operator () (SrcSampleV src) const 00347 { 00348 static const double mul = 00349 unsigned_integral_max_value<DstSampleV>::value / 00350 double (unsigned_integral_max_value<SrcSampleV>::value); 00351 return DstSampleV (src * mul); 00352 } 00353 }; 00354 00355 /* 00356 Both source and destination are unsigned integral samples, the dst 00357 max value is less than (or equal to) the src max value, and the src 00358 max value is not divisible by the dst max value 00359 */ 00360 template <typename SrcSampleV, typename DstSampleV, bool CannotFit> 00361 struct sample_converter_unsigned_integral_nondivisible< 00362 SrcSampleV, DstSampleV, false, CannotFit> 00363 { 00364 DstSampleV operator () (SrcSampleV src) const 00365 { 00366 typedef typename unsigned_integral_max_value<SrcSampleV>::value_type 00367 integer_t; 00368 static const double div = 00369 unsigned_integral_max_value<SrcSampleV>::value / 00370 double (unsigned_integral_max_value<DstSampleV>::value); 00371 static const integer_t div2 = integer_t (div/2); 00372 return DstSampleV ((src + div2) / div); 00373 } 00374 }; 00375 00376 } /* namespace detail */ 00377 00378 00384 template <typename DstSampleV> 00385 struct sample_converter_unsigned<bits32f,DstSampleV> : 00386 public std::unary_function<bits32f,DstSampleV> 00387 { 00388 DstSampleV operator () (bits32f x) const 00389 { 00390 return DstSampleV (x * sample_traits<DstSampleV>::max_value () + 0.5f); 00391 } 00392 }; 00393 00394 template <typename SrcSampleV> 00395 struct sample_converter_unsigned<SrcSampleV, bits32f> : 00396 public std::unary_function<SrcSampleV, bits32f> 00397 { 00398 bits32f operator () (SrcSampleV x) const 00399 { 00400 return bits32f (x / float (sample_traits<SrcSampleV>::max_value ())); 00401 } 00402 }; 00403 00404 template <> 00405 struct sample_converter_unsigned<bits32f, bits32f> : 00406 public std::unary_function<bits32f, bits32f> 00407 { 00408 bits32f operator() (bits32f x) const { return x; } 00409 }; 00410 00411 00413 template <> 00414 struct sample_converter_unsigned<bits32, bits32f> : 00415 public std::unary_function<bits32, bits32f> 00416 { 00417 bits32f operator () (bits32 x) const 00418 { 00419 // unfortunately without an explicit check it is possible to 00420 // get a round-off error. We must ensure that max_value of 00421 // bits32 matches max_value of bits32f 00422 if (x >= sample_traits<bits32>::max_value ()) 00423 return sample_traits<bits32f>::max_value (); 00424 return float (x) / float (sample_traits<bits32>::max_value ()); 00425 } 00426 }; 00427 00429 template <> struct sample_converter_unsigned<bits32f, bits32> : 00430 public std::unary_function<bits32f, bits32> 00431 { 00432 bits32 operator () (bits32f x) const 00433 { 00434 // unfortunately without an explicit check it is possible to 00435 // get a round-off error. We must ensure that max_value of 00436 // bits32 matches max_value of bits32f 00437 if (x >= sample_traits<bits32f>::max_value ()) 00438 return sample_traits<bits32>::max_value(); 00439 return bits32 (x * sample_traits<bits32>::max_value () + 0.5f); 00440 } 00441 }; 00442 00445 namespace detail 00446 { 00447 00448 /* 00449 Converting from signed to unsigned integral sample. 00450 It is both a unary function, and a metafunction (thus requires the 00451 'type' nested typedef, which equals result_type) 00452 */ 00453 template <typename SampleValue> // Model SampleValueConcept 00454 struct sample_convert_to_unsigned : public detail::identity<SampleValue> 00455 { 00456 typedef SampleValue type; 00457 }; 00458 00459 template <> 00460 struct sample_convert_to_unsigned<bits8s> : 00461 public std::unary_function<bits8s, bits8> 00462 { 00463 typedef bits8 type; 00464 type operator () (bits8s val) const { return val + 128; } 00465 }; 00466 00467 template <> 00468 struct sample_convert_to_unsigned <bits16s> : 00469 public std::unary_function<bits16s, bits16> 00470 { 00471 typedef bits16 type; 00472 type operator () (bits16s val) const { return val + 32768; } 00473 }; 00474 00475 template <> struct sample_convert_to_unsigned<bits32s> : 00476 public std::unary_function<bits32s, bits32> 00477 { 00478 typedef bits32 type; 00479 type operator () (bits32s x) const 00480 { return static_cast<bits32>(x + (1 << 31)); } 00481 }; 00482 00483 template <> struct sample_convert_to_unsigned<bits32sf> : 00484 public std::unary_function<bits32sf, bits32f> 00485 { 00486 typedef bits32f type; 00487 type operator () (bits32sf x) const 00488 { return static_cast<float>((x + 1.0f) * .5f); } 00489 }; 00490 00491 /* 00492 Converting from unsigned to signed integral sample 00493 It is both a unary function, and a metafunction (thus requires the 00494 'type' nested typedef, which equals result_type) 00495 */ 00496 template <typename SampleValue> // Model SampleValueConcept 00497 struct sample_convert_from_unsigned : public detail::identity<SampleValue> 00498 { 00499 typedef SampleValue type; 00500 }; 00501 00502 template <> 00503 struct sample_convert_from_unsigned<bits8s> : 00504 public std::unary_function<bits8, bits8s> 00505 { 00506 typedef bits8s type; 00507 type operator () (bits8 val) const 00508 { return val-128; } 00509 }; 00510 00511 template <> 00512 struct sample_convert_from_unsigned<bits16s> : 00513 public std::unary_function<bits16,bits16s> 00514 { 00515 typedef bits16s type; 00516 type operator () (bits16 val) const 00517 { return val-32768; } 00518 }; 00519 00520 template <> 00521 struct sample_convert_from_unsigned<bits32s> : 00522 public std::unary_function<bits32, bits32s> 00523 { 00524 typedef bits32s type; 00525 type operator () (bits32 x) const 00526 { return static_cast<bits32s>(x-(1<<31)); } 00527 }; 00528 00529 template <> 00530 struct sample_convert_from_unsigned<bits32sf> : 00531 public std::unary_function<bits32f, bits32sf> 00532 { 00533 typedef bits32sf type; 00534 type operator () (bits32f x) const { 00535 return static_cast<float>(x * 2.0f - 1.0f); 00536 } 00537 }; 00538 00539 template <typename SrcSampleV, typename DstSampleV, bool DstIsUnsigned> 00540 struct sample_converter_impl 00541 { 00542 PSYNTH_FORCEINLINE 00543 DstSampleV operator () (const SrcSampleV& src) const 00544 { 00545 typedef detail::sample_convert_to_unsigned<SrcSampleV> to_unsigned; 00546 typedef sample_converter_unsigned<typename to_unsigned::result_type, 00547 DstSampleV> converter_unsigned; 00548 return converter_unsigned () (to_unsigned () (src)); 00549 } 00550 }; 00551 00552 template <typename SrcSampleV, typename DstSampleV> 00553 struct sample_converter_impl<SrcSampleV, DstSampleV, false> 00554 { 00555 PSYNTH_FORCEINLINE 00556 DstSampleV operator () (const SrcSampleV& src) const 00557 { 00558 typedef detail::sample_convert_to_unsigned<SrcSampleV> to_unsigned; 00559 typedef detail::sample_convert_from_unsigned<DstSampleV> from_unsigned; 00560 typedef sample_converter_unsigned<typename to_unsigned::result_type, 00561 typename from_unsigned::argument_type> 00562 converter_unsigned; 00563 return from_unsigned () (converter_unsigned () (to_unsigned () (src))); 00564 } 00565 }; 00566 00567 } /* namespace detail */ 00568 00573 template <typename SrcSampleV, typename DstSampleV> // Model SampleValueConcept 00574 struct sample_converter : public std::unary_function<SrcSampleV, DstSampleV> 00575 { 00576 typedef detail::sample_convert_from_unsigned<DstSampleV> from_unsigned; 00577 typedef detail::sample_converter_impl< 00578 SrcSampleV, DstSampleV, 00579 std::is_same<typename from_unsigned::argument_type, 00580 DstSampleV>::value> converter_impl; 00581 00582 PSYNTH_FORCEINLINE 00583 DstSampleV operator () (const SrcSampleV& src) const 00584 { 00585 return converter_impl () (src); 00586 } 00587 }; 00588 00589 00594 template <typename DstSample, typename SrcSample> 00595 // Model SampleConcept (could be sample references) 00596 inline typename sample_traits<DstSample>::value_type 00597 sample_convert (const SrcSample& src) 00598 { 00599 return sample_converter< 00600 typename sample_traits<SrcSample>::value_type, 00601 typename sample_traits<DstSample>::value_type>() (src); 00602 } 00603 00613 struct default_sample_converter 00614 { 00615 template <typename Ch1, typename Ch2> 00616 void operator () (const Ch1& src, Ch2& dst) const 00617 { 00618 dst = sample_convert<Ch2> (src); 00619 } 00620 }; 00621 00622 namespace detail 00623 { 00624 00625 /* fast integer division by 255 */ 00626 inline uint32_t div255 (uint32_t in) 00627 { 00628 uint32_t tmp = in + 128; 00629 return (tmp + (tmp >> 8)) >> 8; 00630 } 00631 00632 /* fast integer divison by 32768 */ 00633 inline uint32_t div32768 (uint32_t in) 00634 { 00635 return (in + 16384) >> 15; 00636 } 00637 00638 } /* namespace detail */ 00639 00661 template <typename SampleValue> 00662 struct sample_multiplier_unsigned : 00663 public std::binary_function<SampleValue,SampleValue,SampleValue> 00664 { 00665 SampleValue operator () (SampleValue a, SampleValue b) const 00666 { 00667 return SampleValue ( 00668 a / double (sample_traits<SampleValue>::max_value()) * b); 00669 } 00670 }; 00671 00675 template<> 00676 struct sample_multiplier_unsigned<bits8> : 00677 public std::binary_function<bits8, bits8, bits8> 00678 { 00679 bits8 operator () (bits8 a, bits8 b) const 00680 { 00681 return bits8 (detail::div255 (uint32_t (a) * uint32_t (b))); 00682 } 00683 }; 00684 00689 template<> 00690 struct sample_multiplier_unsigned<bits16> : 00691 public std::binary_function<bits16,bits16,bits16> 00692 { 00693 bits16 operator () (bits16 a, bits16 b) const 00694 { 00695 return bits16 ((uint32_t (a) * uint32_t (b)) / 65535); 00696 } 00697 }; 00698 00702 template<> 00703 struct sample_multiplier_unsigned<bits32f> : 00704 public std::binary_function<bits32f, bits32f, bits32f> 00705 { 00706 bits32f operator () (bits32f a, bits32f b) const { return a * b; } 00707 }; 00708 00713 template <typename SampleValue> 00714 struct sample_multiplier : 00715 public std::binary_function<SampleValue, SampleValue, SampleValue> 00716 { 00717 SampleValue operator () (SampleValue a, SampleValue b) const 00718 { 00719 typedef detail::sample_convert_to_unsigned<SampleValue> to_unsigned; 00720 typedef detail::sample_convert_from_unsigned<SampleValue> from_unsigned; 00721 typedef sample_multiplier_unsigned<typename to_unsigned::result_type> 00722 multiplier_unsigned; 00723 return from_unsigned () (multiplier_unsigned () ( 00724 to_unsigned () (a), to_unsigned () (b))); 00725 } 00726 }; 00727 00729 template <> 00730 struct sample_multiplier<bits32f> : 00731 public std::binary_function<bits32f, bits32f, bits32f> 00732 { 00733 bits32f operator () (bits32f a, bits32f b) const 00734 { return a * b; } 00735 }; 00736 00741 template <typename Sample> // Models SampleConcept (could be a sample reference) 00742 inline typename sample_traits<Sample>::value_type 00743 sample_multiply (Sample a, Sample b) 00744 { 00745 return sample_multiplier< 00746 typename sample_traits<Sample>::value_type> () (a, b); 00747 } 00748 00770 template <typename Sample> // Models SampleConcept (could be a sample reference) 00771 inline typename sample_traits<Sample>::value_type sample_invert (Sample x) 00772 { 00773 return 00774 sample_traits<Sample>::max_value() - x + 00775 sample_traits<Sample>::min_value(); 00776 } 00777 00778 //#ifdef _MSC_VER 00779 //#pragma warning(pop) 00780 //#endif 00781 00782 } /* namespace sound */ 00783 } /* namespace psynth */ 00784 00785 #endif
1.7.4