libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/packed_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_PACKED_FRAME_H
00040 #define PSYNTH_SOUND_PACKED_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/frame.hpp>
00049 
00050 namespace psynth
00051 {
00052 namespace sound
00053 {
00054 
00096 template <typename BitField,
00097           // A type that holds the bits of the frame. Typically an
00098           // integral type, like boost::uint16_t
00099           typename SampleRefVec,
00100           // An MPL vector whose elements are packed samples. They
00101           // must be constructible from BitField. GIL uses
00102           // packed_sample_reference
00103           typename Layout
00104           // Layout defining the channel space and ordering of the
00105           // samples. Example value: rgb_layout
00106           >
00107 struct packed_frame
00108 {
00109     BitField _bitfield;
00110 
00111     typedef Layout                layout;
00112     typedef packed_frame          value_type;
00113     typedef value_type&           reference;
00114     typedef const value_type&     const_reference;
00115 
00116     BOOST_STATIC_CONSTANT(bool, is_mutable = sample_traits<
00117                               typename boost::mpl::front<SampleRefVec>::type
00118                               >::is_mutable);
00119 
00120     packed_frame () {}
00121     
00122     explicit packed_frame (const BitField& bitfield)
00123         : _bitfield (bitfield) {}
00124 
00125     // Construct from another compatible frame type
00126     packed_frame (const packed_frame& p)
00127         : _bitfield (p._bitfield) {}
00128     
00129     template <typename P>
00130     packed_frame (const P& p,
00131                   typename boost::enable_if_c<is_frame<P>::value>::type* d=0)
00132     {
00133         check_compatible<P> ();
00134         static_copy (p, *this);
00135     }
00136     
00137     packed_frame (int chan0, int chan1)
00138         : _bitfield(0)
00139     { 
00140         BOOST_STATIC_ASSERT((num_samples<packed_frame>::value == 2)); 
00141         sound::at_c<0>(*this) = chan0;
00142         sound::at_c<1>(*this) = chan1; 
00143     }
00144     
00145     packed_frame (int chan0, int chan1, int chan2)
00146         : _bitfield(0)
00147     { 
00148         BOOST_STATIC_ASSERT((num_samples<packed_frame>::value == 3)); 
00149         sound::at_c<0>(*this) = chan0;
00150         sound::at_c<1>(*this) = chan1;
00151         sound::at_c<2>(*this) = chan2; 
00152     }
00153     
00154     packed_frame(int chan0, int chan1, int chan2, int chan3)
00155         : _bitfield (0)
00156     { 
00157         BOOST_STATIC_ASSERT((num_samples<packed_frame>::value==4)); 
00158         sound::at_c<0>(*this) = chan0;
00159         sound::at_c<1>(*this) = chan1;
00160         sound::at_c<2>(*this) = chan2;
00161         sound::at_c<3>(*this) = chan3; 
00162     }
00163     
00164     packed_frame(int chan0, int chan1, int chan2, int chan3, int chan4)
00165         : _bitfield(0)
00166     { 
00167         BOOST_STATIC_ASSERT((num_samples<packed_frame>::value == 5)); 
00168         sound::at_c<0>(*this) = chan0;
00169         sound::at_c<1>(*this) = chan1;
00170         sound::at_c<2>(*this) = chan2;
00171         sound::at_c<3>(*this) = chan3;
00172         sound::at_c<4>(*this) = chan4;
00173     } 
00174 
00175     packed_frame& operator= (const packed_frame& p)
00176     {
00177         _bitfield = p._bitfield;
00178         return *this;
00179     }
00180 
00181     template <typename P>
00182     packed_frame& operator= (const P& p)
00183     {
00184         assign (p, boost::mpl::bool_<is_frame<P>::value>());
00185         return *this;
00186     }
00187     
00188     template <typename P>
00189     bool operator== (const P& p) const
00190     {
00191         return equal (p, boost::mpl::bool_<is_frame<P>::value>());
00192     } 
00193 
00194     template <typename P>
00195     bool operator!= (const P& p) const
00196     {
00197         return !(*this==p);
00198     }
00199 
00200     packed_frame& operator= (int chan)
00201     {
00202         check_mono ();
00203         sound::at_c<0>(*this) = chan;
00204         return *this;
00205     }
00206     
00207     bool operator== (int chan) const
00208     {
00209         check_mono ();
00210         return sound::at_c<0>(*this) == chan;
00211     }
00212     
00213 private:    
00214     template <typename Frame>
00215     static void check_compatible()
00216     {
00217         base::psynth_function_requires<
00218             FramesCompatibleConcept<Frame, packed_frame> >();
00219     }
00220     
00221     template <typename Frame>
00222     void assign(const Frame& p, boost::mpl::true_)
00223     {
00224         check_compatible<Frame>();
00225         static_copy (p,*this);
00226     }
00227     
00228     template <typename Frame>
00229     bool  equal (const Frame& p, boost::mpl::true_) const
00230     {
00231         check_compatible<Frame>();
00232         return static_equal(*this,p);
00233     } 
00234 
00235     // Support for assignment/equality comparison of a sample with a
00236     // monoscale frame
00237     static void check_mono ()
00238     {
00239         BOOST_STATIC_ASSERT((boost::is_same<typename Layout::channel_space,
00240                              mono_space>::value));
00241     }
00242     
00243     template <typename Sample>
00244     void assign (const Sample& chan, boost::mpl::false_)
00245     {
00246         check_mono ();
00247         sound::at_c<0>(*this) = chan;
00248     }
00249     
00250     template <typename Sample>
00251     bool equal (const Sample& chan, boost::mpl::false_) const
00252     {
00253         check_mono ();
00254         return sound::at_c<0>(*this) == chan;
00255     }
00256 };
00257 
00258 
00259 /*
00260  *
00261  *   ChannelBasedConcept
00262  *
00263  */
00264 
00265 template <typename BitField, typename SampleRefVec, typename Layout, int K>  
00266 struct kth_element_type<packed_frame<BitField,SampleRefVec,Layout>,K> :
00267         public boost::mpl::at_c<SampleRefVec, K> {};
00268 
00269 template <typename BitField, typename SampleRefVec, typename Layout, int K>  
00270 struct kth_element_reference_type<packed_frame<BitField,SampleRefVec,Layout>,K> :
00271         public boost::mpl::at_c<SampleRefVec, K> {};
00272 
00273 template <typename BitField, typename SampleRefVec, typename Layout, int K>  
00274 struct kth_element_const_reference_type<
00275     packed_frame<BitField, SampleRefVec, Layout>, K>
00276 {
00277     typedef typename sample_traits<
00278         typename boost::mpl::at_c<SampleRefVec, K>::type>::const_reference type;
00279 };
00280 
00281 template <int K, typename P, typename C, typename L> inline
00282 typename kth_element_reference_type<packed_frame<P,C,L>, K>::type 
00283 at_c (packed_frame<P,C,L>& p)
00284 {
00285     return typename kth_element_reference_type<
00286         packed_frame<P,C,L>, K>::type (&p._bitfield); 
00287 }
00288 
00289 template <int K, typename P, typename C, typename L> inline
00290 typename kth_element_const_reference_type<packed_frame<P,C,L>, K>::type 
00291 at_c (const packed_frame<P,C,L>& p)
00292 { 
00293     return typename kth_element_const_reference_type<
00294         packed_frame<P,C,L>, K>::type (&p._bitfield);
00295 }
00296 
00297 
00298 /*
00299  *
00300  *    FrameConcept
00301  *
00302  */
00303 
00304 /* Metafunction predicate that flags packed_frame as a model of
00305  * FrameConcept. Required by FrameConcept */
00306 template <typename BitField, typename SampleRefVec, typename Layout>  
00307 struct is_frame<packed_frame<BitField, SampleRefVec, Layout> > :
00308     public boost::mpl::true_ {};
00309 
00310 
00311 /*
00312  *
00313  *    FrameBasedConcept
00314  *
00315  */
00316 
00317 template <typename P, typename C, typename Layout>
00318 struct channel_space_type<packed_frame<P,C,Layout> > {
00319     typedef typename Layout::channel_space type;
00320 }; 
00321 
00322 template <typename P, typename C, typename Layout>
00323 struct sample_mapping_type<packed_frame<P,C,Layout> > {
00324     typedef typename Layout::sample_mapping type;
00325 }; 
00326 
00327 template <typename P, typename C, typename Layout>
00328 struct is_planar<packed_frame<P,C,Layout> > : boost::mpl::false_ {}; 
00329 
00330 
00331 /*
00332  *
00333  *    Support for interleaved iterators over packed frame
00334  *
00335  */
00336 
00348 template <typename P, typename C, typename L>  
00349 struct iterator_is_mutable<packed_frame<P,C,L>*> :
00350     public boost::mpl::bool_<packed_frame<P,C,L>::is_mutable> {};
00351 
00352 template <typename P, typename C, typename L>  
00353 struct iterator_is_mutable<const packed_frame<P,C,L>*> :
00354     public boost::mpl::false_ {};
00355 
00356 } /* namespace sound */
00357 } /* namespace psynth */
00358 
00359 namespace boost
00360 {
00361 
00362 template <typename P, typename C, typename L>
00363 struct has_trivial_constructor<psynth::sound::packed_frame<P,C,L> > :
00364         public has_trivial_constructor<P> {};
00365 
00366 } /* namespace boost */
00367 
00368 #endif /* PSYNTH_PACKED_FRAME_H_ */