#ifndef SPROUT_COMPOST_EFFECTS_PSEUDO_STEREO_HPP #define SPROUT_COMPOST_EFFECTS_PSEUDO_STEREO_HPP #include #include #include #include #include #include #include #include namespace sprout { namespace compost { // // pseudo_stereo_outdirected_value // template struct pseudo_stereo_outdirected_value { public: typedef Value value_type; typedef IntType int_type; private: value_type delay_; int_type samples_per_sec_; int_type d_; private: template SPROUT_CONSTEXPR typename std::enable_if< Left, typename std::iterator_traits::value_type >::type calc(Outdirected const& x) const { return x.index() + d_ >= 0 ? *x + x[d_] : 0 ; } template SPROUT_CONSTEXPR typename std::enable_if< !Left, typename std::iterator_traits::value_type >::type calc(Outdirected const& x) const { return x.index() + d_ >= 0 ? *x - x[d_] : 0 ; } public: explicit SPROUT_CONSTEXPR pseudo_stereo_outdirected_value( value_type const& delay, int_type samples_per_sec = 44100 ) : delay_(delay), samples_per_sec_(samples_per_sec), d_(static_cast(-delay * samples_per_sec_)) {} template SPROUT_CONSTEXPR typename std::iterator_traits::value_type operator()(Outdirected const& x) const { return calc(x); } }; namespace effects { // // pseudo_stereo_holder // template class pseudo_stereo_holder { public: typedef T value_type; typedef IntType int_type; private: value_type delay_; int_type samples_per_sec_; public: pseudo_stereo_holder() = default; pseudo_stereo_holder(pseudo_stereo_holder const&) = default; explicit SPROUT_CONSTEXPR pseudo_stereo_holder( value_type const& delay, int_type samples_per_sec = 44100 ) : delay_(delay), samples_per_sec_(samples_per_sec) {} SPROUT_CONSTEXPR value_type const& delay() const { return delay_; } SPROUT_CONSTEXPR int_type const& samples_per_sec() const { return samples_per_sec_; } }; // // pseudo_stereo_forwarder // class pseudo_stereo_forwarder { public: template SPROUT_CONSTEXPR sprout::compost::effects::pseudo_stereo_holder operator()(T const& delay, IntType samples_per_sec) { return sprout::compost::effects::pseudo_stereo_holder(delay, samples_per_sec); } template SPROUT_CONSTEXPR sprout::compost::effects::pseudo_stereo_holder operator()(T const& delay) { return sprout::compost::effects::pseudo_stereo_holder(delay); } }; // // pseudo_stereo // namespace { SPROUT_STATIC_CONSTEXPR sprout::compost::effects::pseudo_stereo_forwarder pseudo_stereo = {}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::compost::effects::pseudo_stereo_holder const& rhs) -> decltype( sprout::lvalue_forward(lhs) | sprout::adaptors::indexed | sprout::adaptors::outdirected | sprout::adaptors::transformed( sprout::compost::pseudo_stereo_outdirected_value(rhs.delay(), rhs.samples_per_sec()) ) | sprout::compost::formats::stereo( sprout::lvalue_forward(lhs) | sprout::adaptors::indexed | sprout::adaptors::outdirected | sprout::adaptors::transformed( sprout::compost::pseudo_stereo_outdirected_value(rhs.delay(), rhs.samples_per_sec()) ) ) ) { return sprout::lvalue_forward(lhs) | sprout::adaptors::indexed | sprout::adaptors::outdirected | sprout::adaptors::transformed( sprout::compost::pseudo_stereo_outdirected_value(rhs.delay(), rhs.samples_per_sec()) ) | sprout::compost::formats::stereo( sprout::lvalue_forward(lhs) | sprout::adaptors::indexed | sprout::adaptors::outdirected | sprout::adaptors::transformed( sprout::compost::pseudo_stereo_outdirected_value(rhs.delay(), rhs.samples_per_sec()) ) ) ; } } // namespace effects using sprout::compost::effects::pseudo_stereo; } // namespace compost } // namespace sprout #endif // #ifndef SPROUT_COMPOST_EFFECTS_PSEUDO_STEREO_HPP