libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/frame.hpp
Go to the documentation of this file.
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_FRAME_H_
00040 #define PSYNTH_SOUND_FRAME_H_
00041 
00042 #include <functional>
00043 #include <boost/utility/enable_if.hpp>
00044 #include <boost/mpl/bool.hpp>
00045 #include <boost/mpl/front.hpp>
00046 
00047 #include <psynth/base/compat.hpp>
00048 #include <psynth/sound/channel_base.hpp>
00049 #include <psynth/sound/concept.hpp>
00050 #include <psynth/sound/sample.hpp>
00051 #include <psynth/sound/metafunctions.hpp>
00052 #include <psynth/sound/util.hpp>
00053 #include <psynth/sound/channel_base_algorithm.hpp>
00054 
00055 namespace psynth
00056 {
00057 namespace sound
00058 {
00059 
00060 /* Forward-declare mono_t */
00061 struct mono_channel;
00062 typedef boost::mpl::vector1<mono_channel> mono_space;
00063 
00064 template <typename FrameBased> struct channel_space_type;
00065 template <typename FrameBased> struct sample_mapping_type;
00066 template <typename FrameBased> struct sample_type;
00067 template <typename FrameBased> struct is_planar;
00068 
00069 template <typename FrameBased> struct channel_space_type<const FrameBased> :
00070         public channel_space_type<FrameBased> {};
00071 template <typename FrameBased>
00072 struct sample_mapping_type<const FrameBased> :
00073         public sample_mapping_type<FrameBased> {};
00074 template <typename FrameBased> struct sample_type<const FrameBased> :
00075         public sample_type<FrameBased> {};
00076 template <typename FrameBased> struct is_planar<const FrameBased> :
00077         public is_planar<FrameBased> {};
00078 
00079 
00080 template <typename T> struct is_frame : public boost::mpl::false_{};
00081 template <typename T> struct is_frame<const T> : public is_frame<T> {};
00082 
00088 template <typename FrameBased>
00089 struct num_samples :
00090         public boost::mpl::size<typename channel_space_type<FrameBased>::type> {}; 
00091 
00148 template <typename SampleValue, typename Layout>
00149 // = boost::mpl::range_c<int, 0, ChannelSpace::size> >
00150 struct frame : public detail::homogeneous_channel_base<
00151     SampleValue, Layout, boost::mpl::size<typename Layout::channel_space>::value>
00152 {
00153 private:
00154     typedef SampleValue sample_t;
00155     typedef detail::homogeneous_channel_base<
00156         SampleValue, Layout,
00157         boost::mpl::size<typename Layout::channel_space>::value>
00158     parent_t;
00159 
00160 public:
00161     typedef frame                value_type;
00162     typedef value_type&          reference;
00163     typedef const value_type&    const_reference;
00164     BOOST_STATIC_CONSTANT(
00165         bool, is_mutable = sample_traits<sample_t>::is_mutable);
00166 
00167     frame () {}
00168 
00169     explicit frame (sample_t v)
00170         : parent_t (v)
00171     {}  // sets all samples to v
00172 
00173     frame (sample_t v0, sample_t v1)
00174         : parent_t(v0,v1) {}
00175     frame(sample_t v0, sample_t v1, sample_t v2)
00176         : parent_t(v0,v1,v2) {}
00177     frame(sample_t v0, sample_t v1, sample_t v2, sample_t v3)
00178         : parent_t(v0,v1,v2,v3) {}
00179     frame(sample_t v0, sample_t v1, sample_t v2, sample_t v3, sample_t v4)
00180         : parent_t(v0,v1,v2,v3,v4) {}
00181     frame(sample_t v0, sample_t v1, sample_t v2, sample_t v3, sample_t v4,
00182           sample_t v5)
00183         : parent_t(v0,v1,v2,v3,v4,v5) {}
00184 
00185     frame (const frame& p)
00186         : parent_t (p) {}
00187 
00188     frame& operator= (const frame& p)
00189     {
00190         static_copy(p,*this);
00191         return *this;
00192     }
00193 
00194     /* Construct from another compatible frame type */
00195     template <typename Frame>
00196     frame (const Frame& p,
00197            typename boost::enable_if_c<is_frame<Frame>::value>::type* dummy = 0)
00198         : parent_t (p)
00199     { 
00200         check_compatible<Frame>();
00201     }
00202 
00203     template <typename P>
00204     frame& operator= (const P& p)
00205     {
00206         assign (p, boost::mpl::bool_<is_frame<P>::value>());
00207         return *this;
00208     }
00209     
00210     template <typename P>
00211     bool operator == (const P& p) const
00212     {
00213         return equal (p, boost::mpl::bool_<is_frame<P>::value>());
00214     } 
00215 
00216     template <typename P>
00217     bool operator != (const P& p) const
00218     {
00219         return !(*this == p);
00220     }
00221 
00222     /* homogeneous frames have operator[] */
00223     typename sample_traits<sample_t>::reference
00224     operator[] (std::size_t i)
00225     {
00226         return dynamic_at_c (*this, i);
00227     }
00228     
00229     typename sample_traits<sample_t>::const_reference
00230     operator[](std::size_t i) const
00231     {
00232         return dynamic_at_c (*this, i);
00233     }
00234 
00235     /* Monoscale support */
00236     frame&  operator= (sample_t chan)
00237     {
00238         check_mono();
00239         sound::at_c<0>(*this) = chan;
00240         return *this;
00241     }
00242     
00243     bool operator== (sample_t chan) const
00244     {
00245         check_mono ();
00246         return sound::at_c<0>(*this) == chan;
00247     }
00248     
00249 private:
00250     template <typename Frame>
00251     void assign (const Frame& p, boost::mpl::true_)
00252     {
00253         check_compatible<Frame>();
00254         static_copy (p, *this);
00255     }
00256     
00257     template <typename Frame>
00258     bool equal (const Frame& p, boost::mpl::true_) const
00259     {
00260         check_compatible<Frame>();
00261         return static_equal(*this, p);
00262     } 
00263 
00264     template <typename Frame>
00265     void check_compatible() const
00266     {
00267         base::psynth_function_requires<FramesCompatibleConcept<Frame, frame> >();
00268     }
00269 
00270     /* Support for assignment/equality comparison of a sample with a
00271      * monoscale frame */
00272 
00273     static void check_mono()
00274     {
00275         BOOST_STATIC_ASSERT(
00276             (boost::is_same<typename Layout::channel_space, mono_space>::value));
00277     }
00278     
00279     template <typename Sample>
00280     void assign (const Sample& chan, boost::mpl::false_)
00281     {
00282         check_mono ();
00283         sound::at_c<0> (*this) = chan;
00284     }
00285     
00286     template <typename Sample>
00287     bool equal (const Sample& chan, boost::mpl::false_) const
00288     {
00289         check_mono ();
00290         return sound::at_c<0>(*this)==chan;
00291     }
00292 };
00293 
00294 /*
00295  *
00296  *   ChannelBasedConcept
00297  *
00298  */
00299 
00300 template <typename SampleValue, typename Layout, int K>  
00301 struct kth_element_type<frame<SampleValue,Layout>, K>
00302 {
00303     typedef SampleValue type;
00304 };
00305 
00306 template <typename SampleValue, typename Layout, int K>  
00307 struct kth_element_reference_type<frame<SampleValue,Layout>, K>
00308 {
00309     typedef typename sample_traits<SampleValue>::reference type;
00310 };
00311 
00312 template <typename SampleValue, typename Layout, int K>  
00313 struct kth_element_reference_type<const frame<SampleValue,Layout>, K>
00314 {
00315     typedef typename sample_traits<SampleValue>::const_reference type;
00316 };
00317 
00318 template <typename SampleValue, typename Layout, int K>  
00319 struct kth_element_const_reference_type<frame<SampleValue,Layout>, K>
00320 {
00321     typedef typename sample_traits<SampleValue>::const_reference type;
00322 };
00323 
00324 /*
00325  *
00326  *   FrameConcept
00327  *
00328  */
00329 
00330 template <typename SampleValue, typename Layout> 
00331 struct is_frame<frame<SampleValue,Layout> > : public boost::mpl::true_{};
00332 
00333 /*
00334  *
00335  *   HomogeneousFrameBasedConcept
00336  *
00337  */
00338 
00339 template <typename SampleValue, typename Layout>
00340 struct channel_space_type<frame<SampleValue,Layout> >
00341 {
00342     typedef typename Layout::channel_space type;
00343 }; 
00344 
00345 template <typename SampleValue, typename Layout>
00346 struct sample_mapping_type<frame<SampleValue,Layout> >
00347 {
00348     typedef typename Layout::sample_mapping type;
00349 }; 
00350 
00351 template <typename SampleValue, typename Layout>
00352 struct is_planar<frame<SampleValue,Layout> > :
00353     public boost::mpl::false_ {};
00354 
00355 template <typename SampleValue, typename Layout>
00356 struct sample_type<frame<SampleValue,Layout> >
00357 {
00358     typedef SampleValue type;
00359 }; 
00360 
00361 } /* namespace sound */
00362 } /* namespace psynth */
00363 
00364 namespace boost
00365 {
00366     template <typename SampleValue, typename Layout> 
00367     struct has_trivial_constructor<psynth::sound::frame<SampleValue,Layout> > :
00368         public has_trivial_constructor<SampleValue> {};
00369 }
00370 
00371 #endif /* PSYNTH_SOUND_FRAME_H_ */