|
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_SOUND_REDUCE_HPP 00040 #define PSYNTH_SOUND_REDUCE_HPP 00041 00042 #include <boost/mpl/insert_range.hpp> 00043 #include <boost/mpl/range_c.hpp> 00044 #include <boost/mpl/vector_c.hpp> 00045 #include <boost/mpl/back.hpp> 00046 #include <boost/mpl/vector.hpp> 00047 #include <boost/mpl/set.hpp> 00048 #include <boost/mpl/long.hpp> 00049 #include <boost/mpl/logical.hpp> 00050 #include <boost/mpl/transform.hpp> 00051 #include <boost/mpl/insert.hpp> 00052 #include <boost/mpl/transform.hpp> 00053 #include <boost/mpl/order.hpp> 00054 00055 #include <psynth/sound/metafunctions.hpp> 00056 #include <psynth/sound/typedefs.hpp> 00057 #include <psynth/sound/dynamic_at_c.hpp> 00058 00059 00060 #ifdef PSYNTH_REDUCE_CODE_BLOAT 00061 00062 00063 // Max number of cases in the cross-expension of binary operation for 00064 // it to be reduced as unary 00065 #define PSYNTH_BINARY_REDUCE_LIMIT 226 00066 00067 namespace boost 00068 { 00069 namespace mpl 00070 { 00071 00072 namespace detail { 00073 00074 template <typename VecOfVecs, std::size_t N, std::size_t B_SIZE> 00075 struct _select_subvector { 00076 private: 00077 typedef typename front<VecOfVecs>::type cur_vec; 00078 static const std::size_t cur_base = size<cur_vec>::value; 00079 typedef typename pop_front<VecOfVecs>::type next_vec_of_vecs; 00080 typedef typename _select_subvector<next_vec_of_vecs, N/cur_base, B_SIZE-1>::type 00081 next_subvector; 00082 public: 00083 typedef typename push_front< 00084 next_subvector, 00085 typename at_c<cur_vec, N%cur_base>::type >::type type; 00086 }; 00087 00088 template <typename VecOfVecs, std::size_t N> 00089 struct _select_subvector<VecOfVecs, N, 0> { 00090 typedef vector<>::type type; 00091 }; 00092 00093 template <typename VecOfVecs, std::size_t N> 00094 struct select_subvector_c { 00095 typedef typename _select_subvector< 00096 VecOfVecs, N, size<VecOfVecs>::value>::type type; 00097 }; 00098 00099 } /* namespace detail */ 00100 00130 template <typename VecOfVecs, typename TypeGen> 00131 struct cross_vector {}; 00132 00137 template <typename VecOfVecs, typename TypeGen, std::size_t K> 00138 struct cross_iterator 00139 { 00140 typedef boost::mpl::random_access_iterator_tag category; 00141 }; 00142 00143 /* 00144 * 00145 * Implementation of the iterator functions of cross vector 00146 * 00147 */ 00148 00159 template <typename VecOfVecs, typename TypeGen, std::size_t K> 00160 struct deref<cross_iterator<VecOfVecs,TypeGen,K> > 00161 { 00162 private: 00163 typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes; 00164 public: 00165 typedef typename TypeGen::template apply<DerefTypes>::type type; 00166 }; 00167 00172 template <typename VecOfVecs, typename TypeGen, std::size_t K> 00173 struct next<cross_iterator<VecOfVecs,TypeGen,K> > { 00174 typedef cross_iterator<VecOfVecs,TypeGen,K+1> type; 00175 }; 00176 00181 template <typename VecOfVecs, typename TypeGen, std::size_t K> 00182 struct prior<cross_iterator<VecOfVecs,TypeGen,K> > { 00183 typedef cross_iterator<VecOfVecs,TypeGen,K-1> type; 00184 }; 00185 00190 template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance> 00191 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > { 00192 typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type; 00193 }; 00194 00201 template <typename VecOfVecs, typename TypeGen, 00202 std::size_t K1, std::size_t K2> 00203 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, 00204 cross_iterator<VecOfVecs,TypeGen,K2> > 00205 { 00206 typedef size_t<K2-K1> type; 00207 }; 00208 00209 00210 /* 00211 * 00212 * Implementation of cross vector 00213 * 00214 */ 00215 00221 template <typename VecOfVecs, typename TypeGen> 00222 struct size<cross_vector<VecOfVecs,TypeGen> > 00223 { 00224 typedef typename fold<VecOfVecs, size_t<1>, 00225 times<_1, size<_2> > >::type type; 00226 static const std::size_t value = type::value; 00227 }; 00228 00233 template <typename VecOfVecs, typename TypeGen> 00234 struct empty<cross_vector<VecOfVecs,TypeGen> > { 00235 typedef typename empty<VecOfVecs>::type type; 00236 }; 00237 00242 template <typename VecOfVecs, typename TypeGen, typename K> 00243 struct at<cross_vector<VecOfVecs,TypeGen>, K> 00244 { 00245 private: 00246 typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator; 00247 public: 00248 typedef typename deref<KthIterator>::type type; 00249 }; 00250 00255 template <typename VecOfVecs, typename TypeGen> 00256 struct begin<cross_vector<VecOfVecs,TypeGen> > { 00257 typedef cross_iterator<VecOfVecs,TypeGen,0> type; 00258 }; 00259 00264 template <typename VecOfVecs, typename TypeGen> 00265 struct end<cross_vector<VecOfVecs,TypeGen> > 00266 { 00267 private: 00268 typedef cross_vector<VecOfVecs,TypeGen> this_t; 00269 public: 00270 typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type; 00271 }; 00272 00277 template <typename VecOfVecs, typename TypeGen> 00278 struct front<cross_vector<VecOfVecs,TypeGen> > 00279 { 00280 private: 00281 typedef cross_vector<VecOfVecs,TypeGen> this_t; 00282 public: 00283 typedef typename deref<typename begin<this_t>::type>::type type; 00284 }; 00285 00290 template <typename VecOfVecs, typename TypeGen> 00291 struct back<cross_vector<VecOfVecs,TypeGen> > { 00292 private: 00293 typedef cross_vector<VecOfVecs,TypeGen> this_t; 00294 typedef typename size<this_t>::type size; 00295 typedef typename minus<size, size_t<1> >::type last_index; 00296 public: 00297 typedef typename at<this_t, last_index>::type type; 00298 }; 00299 00304 template <typename VecOfVecs, typename TypeGen, typename OPP> 00305 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > { 00306 typedef typename lambda<OPP>::type Op; 00307 struct adapter { 00308 template <typename Elements> 00309 struct apply { 00310 typedef typename TypeGen::template apply<Elements>::type orig_t; 00311 typedef typename Op::template apply<orig_t>::type type; 00312 }; 00313 }; 00314 typedef cross_vector<VecOfVecs, adapter > type; 00315 }; 00316 00317 } /* namespace mpl */ 00318 } /* namespace boost */ 00319 00320 namespace boost 00321 { 00322 namespace mpl 00323 { 00324 00335 template <typename SrcTypes, typename DstTypes> 00336 struct mapping_vector {}; 00337 00338 template <typename SrcTypes, typename DstTypes, long K> 00339 struct at_c<mapping_vector<SrcTypes,DstTypes>, K> 00340 { 00341 static const std::size_t value = 00342 size<DstTypes>::value - 00343 mpl::order<DstTypes, typename at_c<SrcTypes,K>::type>::type::value + 1; 00344 typedef size_t<value> type; 00345 }; 00346 00347 template <typename SrcTypes, typename DstTypes> 00348 struct size<mapping_vector<SrcTypes,DstTypes> > 00349 { 00350 typedef typename size<SrcTypes>::type type; 00351 static const std::size_t value = type::value; 00352 }; 00353 00354 00365 namespace detail 00366 { 00367 00368 template <typename SFirst, std::size_t NLeft> 00369 struct copy_to_vector_impl 00370 { 00371 private: 00372 typedef typename deref<SFirst>::type T; 00373 typedef typename next<SFirst>::type next; 00374 typedef typename copy_to_vector_impl<next, NLeft-1>::type rest; 00375 public: 00376 typedef typename push_front<rest, T>::type type; 00377 }; 00378 00379 template <typename SFirst> 00380 struct copy_to_vector_impl<SFirst,1> 00381 { 00382 typedef vector<typename deref<SFirst>::type> type; 00383 }; 00384 00385 } /* namespace detail */ 00386 00387 template <typename Src> 00388 struct copy_to_vector 00389 { 00390 typedef typename detail::copy_to_vector_impl< 00391 typename begin<Src>::type, size<Src>::value>::type type; 00392 }; 00393 00394 template <> 00395 struct copy_to_vector<mpl::set<> > 00396 { 00397 typedef mpl::vector0<> type; 00398 }; 00399 00400 } /* namespace mpl */ 00401 } /* namespace boost */ 00402 00403 00404 namespace psynth 00405 { 00406 namespace sound 00407 { 00408 00427 template <typename Types, typename Op> 00428 struct unary_reduce_impl 00429 { 00430 typedef typename boost::mpl::transform< 00431 Types, detail::reduce<Op, boost::mpl::_1> >::type reduced_t; 00432 typedef typename boost::mpl::copy< 00433 reduced_t, boost::mpl::inserter< 00434 boost::mpl::set<>, 00435 boost::mpl::insert<boost::mpl::_1, 00436 boost::mpl::_2> > >::type unique_t; 00437 static const bool is_single = boost::mpl::size<unique_t>::value == 1; 00438 }; 00439 00440 template <typename Types, typename Op, 00441 bool IsSingle = unary_reduce_impl<Types,Op>::is_single> 00442 struct unary_reduce : public unary_reduce_impl<Types,Op> 00443 { 00444 typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t; 00445 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t; 00446 00447 static unsigned short inline map_index (std::size_t index) 00448 { 00449 typedef typename boost::mpl::mapping_vector<reduced_t, unique_t> indices_t; 00450 return gil::at_c<indices_t, unsigned short>(index); 00451 } 00452 00453 template <typename Bits> PSYNTH_FORCEINLINE 00454 static typename Op::result_type applyc ( 00455 const Bits& bits, std::size_t index, Op op) 00456 { 00457 return apply_operation_basec<unique_t>(bits, map_index (index), op); 00458 } 00459 00460 template <typename Bits> PSYNTH_FORCEINLINE 00461 static typename Op::result_type apply (Bits& bits, std::size_t index, Op op) 00462 { 00463 return apply_operation_base<unique_t>(bits, map_index(index), op); 00464 } 00465 }; 00466 00467 template <typename Types, typename Op> 00468 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> 00469 { 00470 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t; 00471 00472 static unsigned short inline map_index (std::size_t index) 00473 { 00474 return 0; 00475 } 00476 00477 template <typename Bits> PSYNTH_FORCEINLINE 00478 static typename Op::result_type applyc ( 00479 const Bits& bits, std::size_t index, Op op) 00480 { 00481 return op (*psynth_reinterpret_cast_c< 00482 const typename boost::mpl::front<unique_t>::type*>(&bits)); 00483 } 00484 00485 template <typename Bits> PSYNTH_FORCEINLINE 00486 static typename Op::result_type apply (Bits& bits, std::size_t index, Op op) 00487 { 00488 return op (*psynth_reinterpret_cast< 00489 typename boost::mpl::front<unique_t>::type*>(&bits)); 00490 } 00491 }; 00492 00493 00510 namespace detail 00511 { 00512 00513 struct pair_generator 00514 { 00515 template <typename Vec2> 00516 struct apply 00517 { 00518 typedef std::pair< 00519 const typename boost::mpl::at_c<Vec2,0>::type*, 00520 const typename boost::mpl::at_c<Vec2,1>::type*> type; 00521 }; 00522 }; 00523 00524 // When the types are not too large, applies reduce on their cross 00525 // product 00526 template <typename Unary1, typename Unary2, typename Op, 00527 bool IsComplex> 00528 struct binary_reduce_impl 00529 { 00530 // TODO: private: 00531 typedef typename boost::mpl::copy_to_vector< 00532 typename Unary1::unique_t>::type vec1_types; 00533 typedef typename boost::mpl::copy_to_vector< 00534 typename Unary2::unique_t>::type vec2_types; 00535 00536 typedef boost::mpl::cross_vector< 00537 boost::mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES; 00538 00539 typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t; 00540 00541 static unsigned short inline map_index (std::size_t index1, 00542 std::size_t index2) 00543 { 00544 unsigned short r1=Unary1::map_index(index1); 00545 unsigned short r2=Unary2::map_index(index2); 00546 return bin_reduced_t::map_index ( 00547 r2 * boost::mpl::size<vec1_types>::value + r1); 00548 } 00549 00550 public: 00551 typedef typename bin_reduced_t::unique_t unique_t; 00552 00553 template <typename Bits1, typename Bits2> 00554 static typename Op::result_type inline apply ( 00555 const Bits1& bits1, std::size_t index1, 00556 const Bits2& bits2, std::size_t index2, Op op) 00557 { 00558 std::pair<const void*,const void*> pr (&bits1, &bits2); 00559 return apply_operation_basec<unique_t> ( 00560 pr, map_index (index1, index2), op); 00561 } 00562 }; 00563 00564 // When the types are large performs a double-dispatch. Binary 00565 // reduction is not done. 00566 template <typename Unary1, typename Unary2, typename Op> 00567 struct binary_reduce_impl<Unary1, Unary2,Op, true> 00568 { 00569 template <typename Bits1, typename Bits2> 00570 static typename Op::result_type inline apply ( 00571 const Bits1& bits1, std::size_t index1, 00572 const Bits2& bits2, std::size_t index2, Op op) 00573 { 00574 return apply_operation_base<Unary1::unique_t, Unary2::unique_t>( 00575 bits1, index1, bits2, index2, op); 00576 } 00577 }; 00578 00579 } /* namespace detail */ 00580 00581 00582 template <typename Types1, typename Types2, typename Op> 00583 struct binary_reduce 00584 { 00585 // TODO private: 00586 typedef unary_reduce<Types1,Op> unary1_t; 00587 typedef unary_reduce<Types2,Op> unary2_t; 00588 00589 static const std::size_t CROSS_SIZE = 00590 boost::mpl::size<typename unary1_t::unique_t>::value * 00591 boost::mpl::size<typename unary2_t::unique_t>::value; 00592 00593 typedef detail::binary_reduce_impl< 00594 unary1_t, unary2_t, Op, (CROSS_SIZE > PSYNTH_BINARY_REDUCE_LIMIT)> impl; 00595 00596 public: 00597 template <typename Bits1, typename Bits2> 00598 static typename Op::result_type inline apply ( 00599 const Bits1& bits1, std::size_t index1, 00600 const Bits2& bits2, std::size_t index2, Op op) 00601 { 00602 return impl::apply (bits1, index1, bits2, index2, op); 00603 } 00604 }; 00605 00606 template <typename Types, typename UnaryOp> PSYNTH_FORCEINLINE 00607 typename UnaryOp::result_type apply_operation (variant<Types>& arg, UnaryOp op) 00608 { 00609 return unary_reduce<Types,UnaryOp>::template apply ( 00610 arg._bits, arg._index, op); 00611 } 00612 00613 template <typename Types, typename UnaryOp> PSYNTH_FORCEINLINE 00614 typename UnaryOp::result_type apply_operation (const variant<Types>& arg, 00615 UnaryOp op) 00616 { 00617 return unary_reduce<Types,UnaryOp>::template applyc ( 00618 arg._bits, arg._index, op); 00619 } 00620 00621 template <typename Types1, typename Types2, typename BinaryOp> PSYNTH_FORCEINLINE 00622 typename BinaryOp::result_type apply_operation (const variant<Types1>& arg1, 00623 const variant<Types2>& arg2, 00624 BinaryOp op) 00625 { 00626 return binary_reduce<Types1, Types2, BinaryOp>::template apply ( 00627 arg1._bits, arg1._index, 00628 arg2._bits, arg2._index, op); 00629 } 00630 00631 #undef PSYNTH_BINARY_REDUCE_LIMIT 00632 00633 } /* namespace sound */ 00634 } /* namespace psynth */ 00635 00636 00637 namespace psynth 00638 { 00639 namespace sound 00640 { 00641 00642 template <typename Types, typename T> struct type_to_index; 00643 template <typename V> struct range_is_basic; 00644 00645 #if 0 // HACK? 00646 00647 struct stereo_space; 00648 struct mono_space; 00649 struct quad_space; 00650 struct surround_space; 00651 struct error_type; 00652 00653 #endif 00654 00655 namespace detail 00656 { 00657 00658 /* 00659 * 00660 * Generic reduce operation 00661 * 00662 */ 00663 template <typename Op, typename T> 00664 struct reduce 00665 { 00666 typedef T type; 00667 }; 00668 00675 template <typename Op, typename Range, bool IsBasic> 00676 struct reduce_range_basic 00677 { 00678 typedef Range type; 00679 }; 00680 00681 template <typename Op, typename Loc> 00682 struct reduce<Op, buffer_range<Loc> > 00683 : public reduce_range_basic<Op, buffer_range<Loc>, 00684 range_is_basic<buffer_range<Loc> >::value> {}; 00685 00693 template <typename Op, typename Buf, bool IsBasic> 00694 struct reduce_buffer_basic 00695 { 00696 typedef Buf type; 00697 }; 00698 00699 template <typename Op, typename F, bool P, typename A> 00700 struct reduce<Op, buffer<F, P, A>> : 00701 public reduce_buffer_basic<Op, 00702 buffer<F, P, A>, 00703 buffer_is_basic<buffer<F, P, A>>::value > {}; 00704 00712 template <typename Op, typename V1, typename V2, bool AreBasic> 00713 struct reduce_ranges_basic 00714 { 00715 typedef std::pair<const V1*, const V2*> type; 00716 }; 00717 00718 template <typename Op, typename L1, typename L2> 00719 struct reduce<Op, std::pair<const buffer_range<L1>*, const buffer_range<L2>*> > 00720 : public reduce_ranges_basic<Op, 00721 buffer_range<L1>, 00722 buffer_range<L2>, 00723 boost::mpl::and_< 00724 range_is_basic<buffer_range<L1> >, 00725 range_is_basic<buffer_range<L2> > >::value > 00726 {}; 00727 00728 00736 template <typename Cs> 00737 struct reduce_channel_space { 00738 typedef Cs type; 00739 }; 00740 00741 /* 00742 TODO: 00743 template <> struct reduce_channel_space<lab_t> { typedef rgb_t type; }; 00744 template <> struct reduce_channel_space<hsb_t> { typedef rgb_t type; }; 00745 template <> struct reduce_channel_space<cmyk_t> { typedef rgba_t type; }; 00746 */ 00747 00872 // TODO: Use the old code for reduce_color_spaces above to do 00873 // color layout reduction 00874 00875 template <typename SrcLayout, typename DstLayout> 00876 struct reduce_channel_layouts 00877 { 00878 typedef SrcLayout first_t; 00879 typedef DstLayout second_t; 00880 }; 00881 00882 00883 /* 00884 * 00885 * Reduce for copy_frames 00886 * 00887 */ 00888 00889 struct copy_frames_fn; 00890 00891 /* 00892 00893 // 1D reduce for copy_frames reduces the sample to mutable and the 00894 // channel space to its base with same dimensions 00895 00896 template <typename Range> 00897 struct reduce_range_basic<copy_frames_fn,Range,true> { 00898 private: 00899 typedef typename reduce_channel_space< 00900 typename Range::channel_space_t>::type Cs; 00901 // reduce the channel space 00902 typedef layout<Cs, typename Range::sample_mapping_t> layout_t; 00903 public: 00904 typedef typename derived_range_type< 00905 Range, use_default, layout_t, use_default, 00906 use_default, boost::mpl::true_>::type type; 00907 }; 00908 */ 00909 00910 // Incompatible ranges cannot be used in copy_frames - will throw 00911 // std::bad_cast 00912 template <typename V1, typename V2, bool Compatible> 00913 struct reduce_copy_pixop_compat 00914 { 00915 typedef error_type type; 00916 }; 00917 00918 // For compatible basic ranges, reduce their channel spaces based on 00919 // their sample mapping. Make the source immutable and the 00920 // destination mutable (they should already be that way) 00921 template <typename V1, typename V2> 00922 struct reduce_copy_pixop_compat<V1, V2, true> 00923 { 00924 typedef layout<typename V1::channel_space, 00925 typename V1::sample_mapping> layout1; 00926 typedef layout<typename V2::channel_space, 00927 typename V2::sample_mapping> layout2; 00928 00929 typedef typename reduce_channel_layouts<layout1,layout2>::first_t L1; 00930 typedef typename reduce_channel_layouts<layout1,layout2>::second_t L2; 00931 00932 typedef typename derived_range_type< 00933 V1, boost::use_default, L1, 00934 boost::use_default, 00935 boost::use_default, boost::mpl::false_>::type DV1; 00936 00937 typedef typename derived_range_type< 00938 V2, boost::use_default, L2, 00939 boost::use_default, 00940 boost::use_default, boost::mpl::true_ >::type DV2; 00941 00942 typedef std::pair<const DV1*, const DV2*> type; 00943 }; 00944 00945 // The general 2D version branches into compatible and incompatible 00946 // ranges 00947 template <typename V1, typename V2> 00948 struct reduce_ranges_basic<copy_frames_fn, V1, V2, true> 00949 : public reduce_copy_pixop_compat< 00950 V1, V2, boost::mpl::and_<ranges_are_compatible<V1,V2>, 00951 range_is_mutable<V2> >::value > 00952 { 00953 }; 00954 00955 00962 struct destructor_op; 00963 template <typename Range> 00964 struct reduce_range_basic<destructor_op,Range,true> 00965 { 00966 typedef mono8_range type; 00967 }; 00968 00969 00978 struct dynamic_type_get_dimensions; 00979 template <typename Range> 00980 struct reduce_range_basic<dynamic_type_get_dimensions, Range, true> 00981 { 00982 typedef mono8_range type; 00983 }; 00984 00985 template <typename Img> 00986 struct reduce_buffer_basic<dynamic_type_get_dimensions, Img, true> 00987 { 00988 typedef mono8_buffer type; 00989 }; 00990 00991 /* 00992 * 00993 * Reduce for get_num_samples (only channel space matters) 00994 * 00995 */ 00996 00997 struct dynamic_type_get_num_samples; 00998 template <typename Range> 00999 struct reduce_range_basic<dynamic_type_get_num_samples,Range,true> 01000 { 01001 typedef typename Range::channel_space::base Cs; 01002 01003 typedef typename range_type< 01004 bits8, typename reduce_channel_space<Cs>::type>::type type; 01005 }; 01006 01007 template <typename Img> 01008 struct reduce_buffer_basic<dynamic_type_get_num_samples, Img, true> 01009 { 01010 typedef typename Img::channel_space_t::base Cs; 01011 typedef typename buffer_type< 01012 bits8, typename reduce_channel_space<Cs>::type>::type type; 01013 }; 01014 01015 /* 01016 * 01017 * Reduce for resample_frames (same as copy_frames) 01018 * 01019 */ 01020 template <typename Sampler, typename MapFn> struct resample_frames_fn; 01021 01022 template <typename S, typename M, typename V, bool IsBasic> 01023 struct reduce_range_basic<resample_frames_fn<S,M>, V, IsBasic> : 01024 public reduce_range_basic<copy_frames_fn, V, IsBasic> {}; 01025 01026 template <typename S, typename M, typename V1, typename V2, bool IsBasic> 01027 struct reduce_ranges_basic<resample_frames_fn<S,M>, V1, V2, IsBasic> 01028 : public reduce_ranges_basic<copy_frames_fn, V1, V2, IsBasic> {}; 01029 01030 /* 01031 * 01032 * Reduce for copy_and_convert_frames 01033 * 01034 * (the only reduction could be made when ranges are compatible 01035 * and have the same mapping, planarity and stepness) 01036 * 01037 */ 01038 01039 template <typename CC> class copy_and_convert_frames_fn; 01040 01041 // the only thing for 1D reduce is making them all mutable... 01042 template <typename CC, typename Range, bool IsBasic> 01043 struct reduce_range_basic<copy_and_convert_frames_fn<CC>, Range, IsBasic> 01044 : public derived_range_type<Range, boost::use_default, boost::use_default, 01045 boost::use_default, boost::use_default, boost::mpl::true_> 01046 { 01047 }; 01048 01049 // For 2D reduce, if they have the same samples and channel spaces 01050 // (i.e. the same frames) then copy_and_convert is just copy. In this 01051 // case, reduce their common channel space. In general make the first 01052 // immutable and the second mutable 01053 template <typename CC, typename V1, typename V2, bool AreBasic> 01054 struct reduce_ranges_basic<copy_and_convert_frames_fn<CC>, V1, V2, AreBasic> 01055 { 01056 typedef boost::is_same<typename V1::frame_type, typename V2::frame_type> Same; 01057 01058 typedef reduce_channel_space<typename V1::channel_space::base> CsR; 01059 typedef typename boost::mpl::if_< 01060 Same, typename CsR::type, typename V1::channel_space>::type Cs1; 01061 typedef typename boost::mpl::if_< 01062 Same, typename CsR::type, typename V2::channel_space>::type Cs2; 01063 01064 typedef typename derived_range_type< 01065 V1, boost::use_default, layout<Cs1, typename V1::sample_mapping>, 01066 boost::use_default, boost::use_default, boost::mpl::false_>::type DV1; 01067 01068 typedef typename derived_range_type< 01069 V2, boost::use_default, layout<Cs2, typename V2::sample_mapping_t>, 01070 boost::use_default, boost::use_default, boost::mpl::true_ >::type DV2; 01071 01072 typedef std::pair<const DV1*, const DV2*> type; 01073 }; 01074 01075 /* 01076 TODO: What the hell is this? 01077 */ 01078 01079 //integral_buffer_generator 01080 //resize_clobber_buffer_fnobj 01081 //buffer_default_construct_fnobj 01082 //fill_converted_frames_fn 01083 //bind(gil::detail::copy_frames_fn(), _1, dst) 01084 //bind(gil::detail::copy_frames_fn(), src,_1) 01085 01086 //bind(detail::copy_and_convert_frames_fn(), _1, dst) 01087 //bind(detail::copy_and_convert_frames_fn(), src, _1) 01088 //gil::detail::fill_frames_fn<Value>(val) 01089 01090 //detail::copy_construct_in_place_fn<base_t> 01091 //detail::equal_to_fn<typename variant<Types>::base_t> 01092 01093 //detail::dynamic_buffer_get_range<typename dynamic_buffer<Types>::range_t> 01094 //detail::dynamic_buffer_get_const_range<typename dynamic_buffer<Types>::range_t> 01095 //detail::flipped_up_down_range_fn<dynamic_buffer_range<RangeTypes> > 01096 //detail::flipped_left_right_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01097 //detail::tranposed_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01098 //detail::rotated90cw_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01099 //detail::rotated90ccw_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01100 //detail::rotated180_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01101 //detail::subbuffer_range_fn<dynamic_buffer_range<RangeTypes> > 01102 //detail::sub_sampled_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t> 01103 //detail::nth_sample_range_fn<typename nth_sample_range_type<dynamic_buffer_range<RangeTypes> > 01104 //detail::channel_converted_range_fn<DstP,typename channel_convert_range_type<dynamic_buffer_range<RangeTypes>, DstP>::type > 01105 01106 } /* namespace detail */ 01107 01108 } /* namespace sound */ 01109 } /* namespace psynth */ 01110 01111 #endif // PSYNTH_REDUCE_CODE_BLOAT 01112 01113 #endif /* PSYNTH_SOUND_REDUCE */
1.7.4