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