|
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_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_ */
1.7.4