|
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_SAMPLE_HPP_ 00040 #define PSYNTH_SAMPLE_HPP_ 00041 00042 #include <limits> 00043 #include <cassert> 00044 #include <boost/cstdint.hpp> 00045 00046 #include <psynth/base/compat.hpp> 00047 #include <psynth/sound/util.hpp> 00048 00049 namespace psynth 00050 { 00051 namespace sound 00052 { 00053 00069 namespace detail 00070 { 00071 template <typename T, bool is_class> struct sample_traits_impl; 00072 00073 /* sample traits for custom class */ 00074 template <typename T> 00075 struct sample_traits_impl<T, true> 00076 { 00077 typedef typename T::value_type value_type; 00078 typedef typename T::reference reference; 00079 typedef typename T::pointer pointer; 00080 typedef typename T::const_reference const_reference; 00081 typedef typename T::const_pointer const_pointer; 00082 BOOST_STATIC_CONSTANT(bool, is_mutable = T::is_mutable); 00083 static value_type min_value () { return T::min_value(); } 00084 static value_type max_value () { return T::max_value(); } 00085 static value_type zero_value () { return T::zero_value(); } 00086 }; 00087 00088 /* sample traits implementation for built-in integral or floating 00089 point sample type */ 00090 template <typename T> 00091 struct sample_traits_impl<T, false> 00092 { 00093 typedef T value_type; 00094 typedef T& reference; 00095 typedef T* pointer; 00096 typedef const T& const_reference; 00097 typedef T const* const_pointer; 00098 BOOST_STATIC_CONSTANT(bool, is_mutable=true); 00099 static value_type min_value () { return (std::numeric_limits<T>::min) (); } 00100 static value_type max_value () { return (std::numeric_limits<T>::max) (); } 00101 static value_type zero_value () { return T(0); } 00102 }; 00103 00104 /* sample traits implementation for constant built-in scalar or 00105 floating point type */ 00106 template <typename T> 00107 struct sample_traits_impl<const T, false> : 00108 public sample_traits_impl<T, false> 00109 { 00110 typedef const T& reference; 00111 typedef const T* pointer; 00112 BOOST_STATIC_CONSTANT(bool, is_mutable = false); 00113 }; 00114 00115 } /* namespace detail */ 00116 00137 template <typename T> 00138 struct sample_traits : 00139 public detail::sample_traits_impl<T, boost::is_class<T>::value> {}; 00140 00141 // Sample traits for C++ reference type - remove the reference 00142 template <typename T> 00143 struct sample_traits<T&> : public sample_traits<T> {}; 00144 00145 // Sample traits for constant C++ reference type 00146 template <typename T> struct sample_traits<const T&> : public sample_traits<T> 00147 { 00148 typedef typename sample_traits<T>::const_reference reference; 00149 typedef typename sample_traits<T>::const_pointer pointer; 00150 BOOST_STATIC_CONSTANT(bool, is_mutable = false); 00151 }; 00152 00153 00154 /* 00155 * 00156 * scoped_sample_value 00157 * 00158 */ 00159 00186 template <typename BaseSampleValue, 00187 // base sample (models SampleValueConcept) 00188 typename MinVal, 00189 typename MaxVal, 00190 typename ZeroVal 00191 // classes with a static apply() function returning the 00192 // minimum/maximum sample values 00193 > 00194 struct scoped_sample_value 00195 { 00196 typedef scoped_sample_value value_type; 00197 typedef value_type& reference; 00198 typedef value_type* pointer; 00199 typedef const value_type& const_reference; 00200 typedef const value_type* const_pointer; 00201 00202 BOOST_STATIC_CONSTANT(bool, is_mutable = 00203 sample_traits<BaseSampleValue>::is_mutable); 00204 00205 typedef BaseSampleValue base_sample; 00206 00207 static value_type min_value () { return MinVal::apply (); } 00208 static value_type max_value () { return MaxVal::apply (); } 00209 static value_type zero_value () { return ZeroVal::apply (); } 00210 00211 scoped_sample_value () {} 00212 scoped_sample_value (const scoped_sample_value& c) : _value(c._value) {} 00213 scoped_sample_value (BaseSampleValue val) : _value(val) {} 00214 00215 scoped_sample_value& operator++ () { ++_value; return *this; } 00216 scoped_sample_value& operator-- () { --_value; return *this; } 00217 00218 scoped_sample_value operator ++ (int) 00219 { 00220 scoped_sample_value tmp = *this; 00221 this->operator++ (); 00222 return tmp; 00223 } 00224 00225 scoped_sample_value operator--(int) 00226 { 00227 scoped_sample_value tmp = *this; 00228 this->operator-- (); 00229 return tmp; 00230 } 00231 00232 template <typename Scalar2> 00233 scoped_sample_value& operator+=(Scalar2 v) { _value+=v; return *this; } 00234 template <typename Scalar2> 00235 scoped_sample_value& operator-=(Scalar2 v) { _value-=v; return *this; } 00236 template <typename Scalar2> 00237 scoped_sample_value& operator*=(Scalar2 v) { _value*=v; return *this; } 00238 template <typename Scalar2> 00239 scoped_sample_value& operator/=(Scalar2 v) { _value/=v; return *this; } 00240 00241 scoped_sample_value& operator= (BaseSampleValue v) 00242 { _value=v; return *this; } 00243 00244 operator BaseSampleValue () const { return _value; } 00245 00246 private: 00247 BaseSampleValue _value; 00248 }; 00249 00250 struct float_zero { static float apply () { return 0.0f; } }; 00251 struct float_one { static float apply () { return 1.0f; } }; 00252 struct float_minus_one { static float apply () { return -1.0f; } }; 00253 struct float_half { static float apply () { return 0.5f; } }; 00254 00255 00256 00257 /* 00258 * 00259 * Support for sub-byte samples. These are integral samples whose 00260 * value is contained in a range of bits inside an integral type 00261 * 00262 */ 00263 00264 /* 00265 It is necessary for packed samples to have their own value 00266 type. They cannot simply use an integral large enough to store the 00267 data. Here is why: 00268 00269 - Any operation that requires returning the result by value will 00270 otherwise return the built-in integral type, which will have 00271 incorrect range That means that after getting the value of the 00272 sample we cannot properly do sample_convert, sample_invert, etc. 00273 00274 - Two samples are declared compatible if they have the same value 00275 type. That means that a packed sample is incorrectly declared 00276 compatible with an integral type 00277 */ 00278 namespace detail 00279 { 00280 /* returns the smallest fast unsigned integral type that has at 00281 least NumBits bits */ 00282 template <int NumBits> 00283 struct min_fast_uint : 00284 public boost::mpl::if_c< 00285 (NumBits<=8), 00286 uint_least8_t, 00287 typename boost::mpl::if_c< 00288 (NumBits<=16), 00289 uint_least16_t, 00290 typename boost::mpl::if_c< 00291 (NumBits<=32), 00292 uint_least32_t, 00293 uintmax_t 00294 >::type 00295 >::type 00296 > {}; 00297 } 00298 00321 template <int NumBits> 00322 class packed_sample_value 00323 { 00324 static const std::size_t num_values = 1 << NumBits; 00325 00326 public: 00327 typedef typename detail::min_fast_uint<NumBits>::type integer_t; 00328 00329 typedef packed_sample_value value_type; 00330 typedef value_type& reference; 00331 typedef const value_type& const_reference; 00332 typedef value_type* pointer; 00333 typedef const value_type* const_pointer; 00334 00335 static value_type min_value () { return value_type (0); } 00336 static value_type zero_value () { return min_value () / 2 + max_value () / 2; } 00337 static value_type max_value () { return value_type (num_values - 1); } 00338 BOOST_STATIC_CONSTANT(bool, is_mutable = true); 00339 00340 packed_sample_value () {} 00341 packed_sample_value (integer_t v) : _value(v % num_values) {} 00342 packed_sample_value (const packed_sample_value& v) : _value (v._value) {} 00343 template <typename Scalar> 00344 packed_sample_value (Scalar v) : _value (integer_t (v) % num_values) {} 00345 // suppress GCC implicit conversion warnings in sample regression file 00346 00347 operator integer_t () const { return _value; } 00348 00349 private: 00350 integer_t _value; 00351 }; 00352 00353 namespace detail 00354 { 00355 00356 template <std::size_t K> 00357 struct static_copy_bytes 00358 { 00359 void operator () (const unsigned char* from, unsigned char* to) const 00360 { 00361 *to = *from; 00362 static_copy_bytes<K-1> () (++from, ++to); 00363 } 00364 }; 00365 00366 template <> 00367 struct static_copy_bytes<0> 00368 { 00369 void operator () (const unsigned char* , unsigned char*) const {} 00370 }; 00371 00372 template <typename Derived, typename BitField, int NumBits, bool Mutable> 00373 class packed_sample_reference_base 00374 { 00375 protected: 00376 typedef typename boost::mpl::if_c<Mutable, void*, const void*>::type data_ptr_t; 00377 00378 public: 00379 typedef packed_sample_value<NumBits> value_type; 00380 typedef const Derived reference; 00381 typedef value_type* pointer; 00382 typedef const value_type* const_pointer; 00383 BOOST_STATIC_CONSTANT(int, num_bits = NumBits); 00384 BOOST_STATIC_CONSTANT(bool, is_mutable = Mutable); 00385 00386 static value_type min_value () 00387 { 00388 return sample_traits<value_type>::min_value(); 00389 } 00390 00391 static value_type max_value () 00392 { 00393 return sample_traits<value_type>::max_value(); 00394 } 00395 00396 static value_type zero_value () 00397 { 00398 return sample_traits<value_type>::zero_value(); 00399 } 00400 00401 typedef BitField bitfield_t; 00402 typedef typename value_type::integer_t integer_t; 00403 00404 packed_sample_reference_base (data_ptr_t data_ptr) 00405 : _data_ptr(data_ptr) {} 00406 packed_sample_reference_base (const packed_sample_reference_base& ref) 00407 : _data_ptr(ref._data_ptr) {} 00408 00409 const Derived& operator= (integer_t v) const { set (v); return derived (); } 00410 const Derived& operator++ () const { set(get()+1); return derived (); } 00411 const Derived& operator-- () const { set(get()-1); return derived (); } 00412 00413 Derived operator++(int) const 00414 { 00415 Derived tmp=derived(); 00416 this->operator++(); 00417 return tmp; 00418 } 00419 00420 Derived operator--(int) const 00421 { 00422 Derived tmp=derived(); 00423 this->operator--(); 00424 return tmp; 00425 } 00426 00427 template <typename Scalar2> 00428 const Derived& operator+= (Scalar2 v) const { set(get()+v); return derived(); } 00429 template <typename Scalar2> 00430 const Derived& operator-= (Scalar2 v) const { set(get()-v); return derived(); } 00431 template <typename Scalar2> 00432 const Derived& operator*= (Scalar2 v) const { set(get()*v); return derived(); } 00433 template <typename Scalar2> 00434 const Derived& operator/= (Scalar2 v) const { set(get()/v); return derived(); } 00435 00436 operator integer_t () const { return get (); } 00437 data_ptr_t operator & () const {return _data_ptr;} 00438 00439 protected: 00440 data_ptr_t _data_ptr; 00441 // void* pointer to the first byte of the bit range 00442 static const integer_t max_val = (1 << NumBits) - 1; 00443 00444 #ifdef PSYNTH_NONWORD_POINTER_ALIGNMENT_SUPPORTED 00445 const bitfield_t& get_data () const 00446 { 00447 return *static_cast<const bitfield_t*> (_data_ptr); 00448 } 00449 00450 void set_data(const bitfield_t& val) const 00451 { 00452 *static_cast<bitfield_t*> (_data_ptr) = val; 00453 } 00454 #else 00455 bitfield_t get_data() const 00456 { 00457 bitfield_t ret; 00458 static_copy_bytes<sizeof(bitfield_t)> ()( 00459 psynth_reinterpret_cast_c<const unsigned char*>(_data_ptr), 00460 psynth_reinterpret_cast<unsigned char*>(&ret)); 00461 return ret; 00462 } 00463 00464 void set_data(const bitfield_t& val) const 00465 { 00466 static_copy_bytes<sizeof(bitfield_t)> ()( 00467 psynth_reinterpret_cast_c<const unsigned char*>(&val), 00468 psynth_reinterpret_cast<unsigned char*>(_data_ptr)); 00469 } 00470 #endif 00471 00472 private: 00473 void set(integer_t value) const 00474 { 00475 // TODO: can this be done faster?? 00476 const integer_t num_values = max_val+1; 00477 this->derived ().set_unsafe ( 00478 ((value % num_values) + num_values) % num_values); 00479 } 00480 00481 integer_t get () const { return derived ().get (); } 00482 00483 const Derived& derived() const 00484 { 00485 return static_cast<const Derived&>(*this); 00486 } 00487 }; 00488 00489 } /* namespace detail */ 00490 00510 template <typename BitField, 00511 // A type that holds the bits of the pixel from which the 00512 // sample is referenced. Typically an integral type, like 00513 // boost::uint16_t 00514 int FirstBit, int NumBits, 00515 // Defines the sequence of bits in the data value that 00516 // contain the sample 00517 bool Mutable 00518 // true if the reference is mutable 00519 > 00520 class packed_sample_reference; 00521 00522 template <typename BitField, 00523 // A type that holds the bits of the pixel from which the 00524 // sample is referenced. Typically an integral type, like 00525 // boost::uint16_t 00526 int NumBits, 00527 // Defines the sequence of bits in the data value that 00528 // contain the sample 00529 bool Mutable 00530 // true if the reference is mutable 00531 > 00532 class packed_dynamic_sample_reference; 00533 00539 template <typename BitField, int FirstBit, int NumBits> 00540 class packed_sample_reference<BitField, FirstBit, NumBits, false> : 00541 public detail::packed_sample_reference_base< 00542 packed_sample_reference<BitField, FirstBit, NumBits, false>, 00543 BitField, NumBits, false> 00544 { 00545 typedef detail::packed_sample_reference_base< 00546 packed_sample_reference<BitField, FirstBit, NumBits, false>, 00547 BitField,NumBits,false> parent_t; 00548 friend class packed_sample_reference<BitField, FirstBit, NumBits, true>; 00549 00550 static const BitField sample_mask = 00551 static_cast<BitField>(parent_t::max_val) << FirstBit; 00552 00553 void operator= (const packed_sample_reference&); 00554 00555 public: 00556 typedef const packed_sample_reference<BitField,FirstBit,NumBits,false> 00557 const_reference; 00558 typedef const packed_sample_reference<BitField,FirstBit,NumBits,true> 00559 mutable_reference; 00560 typedef typename parent_t::integer_t integer_t; 00561 00562 explicit packed_sample_reference (const void* data_ptr) 00563 : parent_t (data_ptr) {} 00564 packed_sample_reference(const packed_sample_reference& ref) 00565 : parent_t (ref._data_ptr) {} 00566 packed_sample_reference(const mutable_reference& ref) 00567 : parent_t (ref._data_ptr) {} 00568 00569 unsigned first_bit () const { return FirstBit; } 00570 00571 integer_t get () const 00572 { 00573 return integer_t ((this->get_data () & sample_mask) >> FirstBit); 00574 } 00575 }; 00576 00582 template <typename BitField, int FirstBit, int NumBits> 00583 class packed_sample_reference<BitField, FirstBit, NumBits, true> 00584 : public detail::packed_sample_reference_base< 00585 packed_sample_reference<BitField, FirstBit, NumBits, true>, 00586 BitField, NumBits, true> 00587 { 00588 typedef detail::packed_sample_reference_base< 00589 packed_sample_reference<BitField, FirstBit, NumBits, true>, 00590 BitField, NumBits, true> parent_t; 00591 friend class packed_sample_reference<BitField, FirstBit, NumBits, false>; 00592 00593 static const BitField sample_mask = 00594 static_cast<BitField> (parent_t::max_val) << FirstBit; 00595 00596 public: 00597 typedef const packed_sample_reference<BitField,FirstBit,NumBits,false> 00598 const_reference; 00599 typedef const packed_sample_reference<BitField,FirstBit,NumBits,true> 00600 mutable_reference; 00601 typedef typename parent_t::integer_t integer_t; 00602 00603 explicit packed_sample_reference (void* data_ptr) 00604 : parent_t (data_ptr) {} 00605 00606 packed_sample_reference (const packed_sample_reference& ref) 00607 : parent_t (ref._data_ptr) {} 00608 00609 const packed_sample_reference& operator= (integer_t value) const 00610 { 00611 assert (value<=parent_t::max_val); 00612 set_unsafe (value); 00613 return *this; 00614 } 00615 00616 const packed_sample_reference& operator= (const mutable_reference& ref) const 00617 { 00618 set_from_reference (ref.get_data ()); 00619 return *this; 00620 } 00621 00622 const packed_sample_reference& operator= (const const_reference& ref) const 00623 { 00624 set_from_reference (ref.get_data ()); 00625 return *this; 00626 } 00627 00628 template <bool Mutable1> 00629 const packed_sample_reference& operator= ( 00630 const packed_dynamic_sample_reference<BitField,NumBits,Mutable1>& ref) 00631 const 00632 { 00633 set_unsafe (ref.get ()); 00634 return *this; 00635 } 00636 00637 unsigned first_bit () const { return FirstBit; } 00638 00639 integer_t get () const 00640 { 00641 return integer_t((this->get_data()&sample_mask) >> FirstBit); 00642 } 00643 00644 void set_unsafe (integer_t value) const 00645 { 00646 this->set_data ((this->get_data() & ~sample_mask) | 00647 (( static_cast< BitField >( value )<<FirstBit))); 00648 } 00649 00650 private: 00651 00652 void set_from_reference (const BitField& other_bits) const 00653 { 00654 this->set_data((this->get_data() & ~sample_mask) | 00655 (other_bits & sample_mask)); 00656 } 00657 }; 00658 00659 } /* namespace sound */ 00660 } /* namespace psynth */ 00661 00662 namespace std 00663 { 00664 00665 /* 00666 We are forced to define swap inside std namespace because on some 00667 platforms (Visual Studio 8) STL calls swap qualified. 00668 00669 swap with 'left bias': 00670 - swap between proxy and anything 00671 - swap between value type and proxy 00672 - swap between proxy and proxy 00673 */ 00674 00679 template <typename BF, int FB, int NB, bool M, typename R> inline 00680 void swap(const psynth::sound::packed_sample_reference<BF,FB,NB,M> x, R& y) 00681 { 00682 psynth::sound::swap_proxy< 00683 typename psynth::sound::packed_sample_reference<BF,FB,NB,M>::value_type>( 00684 x, y); 00685 } 00686 00687 00692 template <typename BF, int FB, int NB, bool M> inline 00693 void swap( 00694 typename psynth::sound::packed_sample_reference<BF,FB,NB,M>::value_type& x, 00695 const psynth::sound::packed_sample_reference<BF,FB,NB,M> y) 00696 { 00697 psynth::sound::swap_proxy< 00698 typename psynth::sound::packed_sample_reference<BF,FB,NB,M>::value_type>( 00699 x, y); 00700 } 00701 00702 00707 template <typename BF, int FB, int NB, bool M> inline 00708 void swap ( 00709 const psynth::sound::packed_sample_reference<BF,FB,NB,M> x, 00710 const psynth::sound::packed_sample_reference<BF,FB,NB,M> y) 00711 { 00712 psynth::sound::swap_proxy< 00713 typename psynth::sound::packed_sample_reference<BF,FB,NB,M>::value_type>( 00714 x, y); 00715 } 00716 00717 } /* namespace std */ 00718 00719 namespace psynth 00720 { 00721 namespace sound 00722 { 00723 00758 template <typename BitField, int NumBits> 00759 class packed_dynamic_sample_reference<BitField,NumBits,false> 00760 : public detail::packed_sample_reference_base< 00761 packed_dynamic_sample_reference<BitField, NumBits, false>, 00762 BitField, NumBits, false> 00763 { 00764 typedef detail::packed_sample_reference_base< 00765 packed_dynamic_sample_reference<BitField, NumBits, false>, 00766 BitField,NumBits,false> parent_t; 00767 friend class packed_dynamic_sample_reference<BitField, NumBits, true>; 00768 00769 unsigned _first_bit; // 0..7 00770 00771 void operator= (const packed_dynamic_sample_reference&); 00772 00773 public: 00774 typedef const packed_dynamic_sample_reference<BitField, NumBits, false> 00775 const_reference; 00776 typedef const packed_dynamic_sample_reference<BitField,NumBits,true> 00777 mutable_reference; 00778 typedef typename parent_t::integer_t 00779 integer_t; 00780 00781 packed_dynamic_sample_reference (const void* data_ptr, unsigned first_bit) 00782 : parent_t(data_ptr) 00783 , _first_bit(first_bit) {} 00784 00785 packed_dynamic_sample_reference (const const_reference& ref) 00786 : parent_t (ref._data_ptr) 00787 , _first_bit(ref._first_bit) {} 00788 00789 packed_dynamic_sample_reference (const mutable_reference& ref) 00790 : parent_t (ref._data_ptr) 00791 , _first_bit (ref._first_bit) {} 00792 00793 unsigned first_bit () const { return _first_bit; } 00794 00795 integer_t get () const 00796 { 00797 const BitField sample_mask = parent_t::max_val << _first_bit; 00798 return (static_cast<integer_t>(this->get_data () & sample_mask ) >> 00799 _first_bit); 00800 } 00801 }; 00802 00812 template <typename BitField, int NumBits> 00813 class packed_dynamic_sample_reference<BitField, NumBits, true> 00814 : public detail::packed_sample_reference_base< 00815 packed_dynamic_sample_reference<BitField, NumBits, true>, 00816 BitField, NumBits, true> 00817 { 00818 typedef detail::packed_sample_reference_base< 00819 packed_dynamic_sample_reference<BitField, NumBits, true>, 00820 BitField, NumBits, true> parent_t; 00821 00822 friend class packed_dynamic_sample_reference<BitField, NumBits, false>; 00823 00824 unsigned _first_bit; 00825 00826 public: 00827 typedef const packed_dynamic_sample_reference<BitField,NumBits, false> 00828 const_reference; 00829 00830 typedef const packed_dynamic_sample_reference<BitField,NumBits, true> 00831 mutable_reference; 00832 00833 typedef typename parent_t::integer_t integer_t; 00834 00835 packed_dynamic_sample_reference (void* data_ptr, unsigned first_bit) 00836 : parent_t (data_ptr) 00837 , _first_bit (first_bit) {} 00838 00839 packed_dynamic_sample_reference (const packed_dynamic_sample_reference& ref) 00840 : parent_t(ref._data_ptr) 00841 , _first_bit (ref._first_bit) {} 00842 00843 const packed_dynamic_sample_reference& 00844 operator= (integer_t value) const 00845 { 00846 assert (value <= parent_t::max_val); 00847 set_unsafe (value); 00848 return *this; 00849 } 00850 00851 const packed_dynamic_sample_reference& 00852 operator= (const mutable_reference& ref) const 00853 { 00854 set_unsafe (ref.get()); 00855 return *this; 00856 } 00857 00858 const packed_dynamic_sample_reference& 00859 operator= (const const_reference& ref) const 00860 { 00861 set_unsafe (ref.get ()); 00862 return *this; 00863 } 00864 00865 template <typename BitField1, int FirstBit1, bool Mutable1> 00866 const packed_dynamic_sample_reference& operator= ( 00867 const packed_sample_reference<BitField1, FirstBit1, 00868 NumBits, Mutable1>& ref) const 00869 { 00870 set_unsafe (ref.get()); 00871 return *this; 00872 } 00873 00874 unsigned first_bit () const { return _first_bit; } 00875 00876 integer_t get() const 00877 { 00878 const BitField sample_mask = parent_t::max_val<<_first_bit; 00879 return (static_cast<integer_t>(this->get_data() & sample_mask ) >> 00880 _first_bit); 00881 } 00882 00883 void set_unsafe(integer_t value) const 00884 { 00885 const BitField sample_mask = parent_t::max_val << _first_bit; 00886 this->set_data ((this->get_data() & ~sample_mask) | value << _first_bit); 00887 } 00888 }; 00889 00890 } /* namespace sound */ 00891 } /* namespace psynth */ 00892 00893 namespace std 00894 { 00895 00896 /* 00897 We are forced to define swap inside std namespace because on some 00898 platforms (Visual Studio 8) STL calls swap qualified. 00899 00900 swap with 'left bias': 00901 - swap between proxy and anything 00902 - swap between value type and proxy 00903 - swap between proxy and proxy 00904 */ 00905 00910 template <typename BF, int NB, bool M, typename R> inline 00911 void swap(const psynth::sound::packed_dynamic_sample_reference<BF,NB,M> x, R& y) 00912 { 00913 psynth::sound::swap_proxy< 00914 typename psynth::sound::packed_dynamic_sample_reference< 00915 BF,NB,M>::value_type> (x, y); 00916 } 00917 00918 00923 template <typename BF, int NB, bool M> inline 00924 void swap (typename psynth::sound::packed_dynamic_sample_reference<BF,NB,M>::value_type& x, 00925 const psynth::sound::packed_dynamic_sample_reference<BF,NB,M> y) 00926 { 00927 psynth::sound::swap_proxy< 00928 typename psynth::sound::packed_dynamic_sample_reference< 00929 BF, NB, M>::value_type> (x,y); 00930 } 00931 00936 template <typename BF, int NB, bool M> inline 00937 void swap(const psynth::sound::packed_dynamic_sample_reference<BF,NB,M> x, 00938 const psynth::sound::packed_dynamic_sample_reference<BF,NB,M> y) 00939 { 00940 psynth::sound::swap_proxy< 00941 typename psynth::sound::packed_dynamic_sample_reference<BF,NB,M>::value_type> (x,y); 00942 } 00943 00944 } /* namespace std */ 00945 00946 00947 namespace psynth 00948 { 00949 namespace sound 00950 { 00951 00952 /* 00953 * 00954 * Built-in sample models 00955 * 00956 */ 00957 00965 typedef boost::uint8_t bits8; 00966 00974 typedef boost::uint16_t bits16; 00975 00983 typedef boost::uint32_t bits32; 00984 00992 typedef boost::int8_t bits8s; 00993 01001 typedef boost::int16_t bits16s; 01002 01010 typedef boost::int32_t bits32s; 01011 01019 typedef scoped_sample_value<float, float_zero, float_one, float_half> bits32f; 01020 01028 typedef scoped_sample_value<float, float_minus_one, float_one, float_zero> 01029 bits32sf; 01030 01031 } /* namespace sound */ 01032 } /* namespace psynth */ 01033 01034 namespace boost 01035 { 01036 01041 template <int NumBits> 01042 struct is_integral<psynth::sound::packed_sample_value<NumBits> > : 01043 public boost::mpl::true_ {}; 01044 01045 template <typename BitField, int FirstBit, int NumBits, bool IsMutable> 01046 struct is_integral<psynth::sound::packed_sample_reference< 01047 BitField, FirstBit, NumBits, IsMutable> > : 01048 public boost::mpl::true_ {}; 01049 01050 template <typename BitField, int NumBits, bool IsMutable> 01051 struct is_integral<psynth::sound::packed_dynamic_sample_reference< 01052 BitField, NumBits, IsMutable> > : 01053 public boost::mpl::true_ {}; 01054 01055 template <typename BaseSampleValue, 01056 typename MinVal, typename MaxVal, typename ZeroVal> 01057 struct is_integral<psynth::sound::scoped_sample_value< 01058 BaseSampleValue, MinVal, MaxVal, ZeroVal> > : 01059 public is_integral<BaseSampleValue> {}; 01060 01061 } /* namespace boost */ 01062 01063 #endif /* PSYNTH_SAMPLE_HPP_ */
1.7.4