|
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 #ifndef PSYNTH_SOUND_RING_BUFFER_H_ 00032 #define PSYNTH_SOUND_RING_BUFFER_H_ 00033 00034 #include <psynth/sound/buffer.hpp> 00035 #include <psynth/sound/ring_buffer_range.hpp> 00036 00037 namespace psynth 00038 { 00039 namespace sound 00040 { 00041 00045 template <class Buffer, template <class> class BRange> 00046 class ring_buffer_base 00047 { 00048 public: 00049 typedef BRange<typename Buffer::range> range_base; 00050 typedef BRange<typename Buffer::const_range> const_range_base; 00051 00052 typedef typename range_base::difference_type difference_type; 00053 typedef typename range_base::size_type size_type; 00054 typedef typename range_base::unsafe_position unsafe_position; 00055 typedef typename range_base::position position; 00056 00057 /* Create with size and optional initial value and 00058 * alignment */ 00059 00060 explicit ring_buffer_base (size_type size = 0, 00061 std::size_t alignment = 0) 00062 : _buffer (size, alignment) 00063 , _range (range_base (range (_buffer))) 00064 {} 00065 00066 template <typename Allocator> 00067 explicit ring_buffer_base (size_type size, 00068 std::size_t alignment, 00069 Allocator alloc_in) 00070 : _buffer (size, alignment, alloc_in) 00071 , _range (range_base (range (_buffer))) 00072 {} 00073 00074 explicit ring_buffer_base (const Buffer& buf) 00075 : _buffer (buf) 00076 , _range (range_base (range (_buffer))) 00077 { 00078 _range.advance (size ()); 00079 } 00080 00081 template <typename F2, bool IP2, typename Alloc2> 00082 explicit ring_buffer_base (const buffer<F2, IP2, Alloc2>& buf) 00083 : _buffer (buf) 00084 , _range (range_base (range (_buffer))) 00085 { 00086 _range.advance (size ()); 00087 } 00088 00089 ring_buffer_base& operator= (const ring_buffer_base& buf) 00090 { 00091 _buffer = buf._buffer; 00092 _range = range_base (range (_buffer)); 00093 _range.advance (buf._range.count ()); 00094 return *this; 00095 } 00096 00097 template <class Buffer2, template<class>class BRange2> 00098 ring_buffer_base& operator= (const ring_buffer_base<Buffer2, BRange2>& buf) 00099 { 00100 _buffer = buf._buffer; 00101 _range = range_base (range (_buffer)); 00102 _range.advance (buf._range.count ()); 00103 return *this; 00104 } 00105 00106 size_type size () const 00107 { return _range.size (); } 00108 00109 void swap (ring_buffer_base& buf) 00110 { 00111 // required by MutableContainerConcept 00112 using std::swap; 00113 swap (_buffer, buf._buffer); 00114 swap (_range, buf._range); 00115 } 00116 00117 void recreate (size_type size, 00118 std::size_t alignment = 0) 00119 { 00120 _buffer.recreate (size, alignment); 00121 _range = range_base (range (_buffer)); 00122 } 00123 00124 template <typename Allocator> 00125 void recreate (size_type size, 00126 std::size_t alignment, 00127 const Allocator alloc_in) 00128 { 00129 _buffer.recreate (size, alignment, alloc_in); 00130 _range = range_base (range (_buffer)); 00131 } 00132 00133 00134 #ifdef PSYNTH_BUFFER_MODEL_RANGE 00135 00136 position begin_pos () const 00137 { return _range.begin_pos (); } 00138 00139 position end_pos () const 00140 { return _range.end_pos (); } 00141 00142 safe_position safe_begin_pos () const 00143 { return _range.safe_begin_pos (); } 00144 00145 safe_position safe_end_pos () const 00146 { return _range.safe_end_pos (); } 00147 00149 size_type available (const safe_position& r) const 00150 { return _range.available (r); } 00151 00153 size_type available () const 00154 { return _range.available (); } 00155 00157 ring_buffer_error check_position (const safe_position& r) const 00158 { return _range.check_position (r); } 00159 00161 template<class Position, class Range> 00162 size_type read (Position& r, Range& buf) const 00163 { return _range.read (r, buf, buf.size ()); }; 00164 00166 template<class Position, class Range> 00167 size_type read (Position& r, Range& buf, size_type samples) const 00168 { return _range.read (r, buf, samples); } 00169 00171 template<class Position, class Range, class CC = default_channel_converter> 00172 size_type read_and_convert (Position& r, const Range& buf, CC cc = CC ()) const 00173 { return _range.read_and_convert (r, buf, buf.size (), cc); }; 00174 00176 template<class Position, class Range, class CC = default_channel_converter> 00177 size_type read_and_convert (Position& r, const Range& buf, 00178 size_type samples, CC cc = CC ()) const 00179 { return _range.read_and_convert (r, buf, samples, cc); } 00180 00182 template<class Position, class Range, class CC = default_channel_converter> 00183 size_type read_and_convert (Position& r, Range& buf, CC cc = CC ()) const 00184 { return _range.read_and_convert (r, buf, buf.size (), cc); }; 00185 00187 template<class Position, class Range, class CC = default_channel_converter> 00188 size_type read_and_convert (Position& r, Range& buf, 00189 size_type samples, CC cc = CC ()) const 00190 { return _range.read_and_convert (r, buf, samples, cc); } 00191 00193 template <class Range> 00194 void write (const Range& buf) 00195 { return _range.write (buf, buf.size ()); } 00196 00198 template <class Range> 00199 void write (const Range& buf, size_type samples) 00200 { _range.write (buf, samples); } 00201 00203 template <class Range, class CC = default_channel_converter> 00204 void write_and_convert (const Range& buf, CC cc = CC ()) 00205 { _range.write_and_convert (buf, buf.size (), cc); } 00206 00208 template <class Range, class CC = default_channel_converter> 00209 void write_and_convert (const Range& buf, size_type samples, CC cc = CC ()) 00210 { _range.write_and_convert (buf, samples, cc); } 00211 00213 void zero () 00214 { _range.zero (); } 00215 00217 bool is_backwards () const 00218 { return _range.is_backwards (); } 00219 00221 void set_backwards () 00222 { return _range.set_backwards (); } 00223 00224 template <typename Position> // Models PositionConcept 00225 void advance (Position& r, difference_type n) const 00226 { return _range.advance (r, n); } 00227 00228 template <typename Position> 00229 void increment (Position& r) const 00230 { return _range.increment (r); } 00231 00232 template <typename Position> 00233 void decrement (Position& r) const 00234 { return _range.decrement (r); } 00235 00236 void advance (size_type n) 00237 { return _range.advance (n); } 00238 00239 difference_type count () const 00240 { return _range.count (); } 00241 00242 safe_position sync (const safe_position& r) const 00243 { return _range.sync (); } 00244 00245 #endif /* PSYNTH_BUFFER_MODEL_RANGE */ 00246 00247 protected: 00248 Buffer _buffer; 00249 range_base _range; 00250 }; 00251 00252 00253 template <class Buffer> 00254 class ring_buffer : public ring_buffer_base<Buffer, ring_buffer_range> 00255 { 00256 typedef ring_buffer_base<Buffer, ring_buffer_range> parent_type; 00257 00258 public: 00259 typedef typename Buffer::allocator_type allocator_type; 00260 00261 typedef typename parent_type::range_base range; 00262 typedef typename parent_type::const_range_base const_range; 00263 00264 typedef typename range::value_type value_type; 00265 typedef typename range::reference reference; 00266 00267 typedef typename range::unsafe_iterator unsafe_iterator; 00268 typedef typename const_range::unsafe_iterator const_unsafe_iterator; 00269 typedef typename range::iterator iterator; 00270 typedef typename const_range::iterator const_iterator; 00271 00277 explicit ring_buffer (typename parent_type::size_type size = 0, 00278 std::size_t alignment = 0, 00279 const typename Buffer::allocator_type 00280 alloc_in = typename Buffer::allocator_type ()) 00281 : parent_type (size, alignment, alloc_in) 00282 {} 00283 00284 explicit ring_buffer (const Buffer& buf) 00285 : parent_type (buf) 00286 {} 00287 00288 template <typename F2, bool IP2, typename Alloc2> 00289 explicit ring_buffer (const buffer<F2, IP2, Alloc2>& buf) 00290 : parent_type (buf) 00291 { 00292 } 00293 00294 ring_buffer& operator= (const ring_buffer& buf) 00295 { 00296 parent_type::operator= (buf); 00297 return *this; 00298 } 00299 00300 template <class Buffer2> 00301 ring_buffer& operator= (const ring_buffer<Buffer2>& buf) 00302 { 00303 parent_type::operator= (buf); 00304 return *this; 00305 } 00306 00307 using parent_type::recreate; 00308 00309 void recreate (typename parent_type::size_type size, 00310 typename Buffer::range::value_type val, 00311 std::size_t alignment = 0) 00312 { 00313 this->_buffer.recreate (size, val, alignment); 00314 this->_range = range (sound::range (this->_buffer)); 00315 } 00316 00317 #ifdef PSYNTH_BUFFER_MODELS_RANGE 00318 00319 iterator begin () 00320 { return this->_range.begin (); } 00321 00322 iterator end () 00323 { return this->_range.end (); } 00324 00325 safe_iterator safe_begin () 00326 { return this->_range.safe_begin (); } 00327 00328 safe_iterator safe_end () 00329 { return this->_range.safe_end (); } 00330 00331 const_iterator begin () const 00332 { return this->_range.begin (); } 00333 00334 const_iterator end () const 00335 { return this->_range.end (); } 00336 00337 const_safe_iterator safe_begin () const 00338 { return this->_range.safe_begin (); } 00339 00340 const_safe_iterator safe_end () const 00341 { return this->_range.safe_end (); } 00342 00343 #endif /* PSYNTH_BUFFER_MODEL_RANGE */ 00344 00345 allocator_type& allocator () 00346 { return this->_buffer.allocator (); } 00347 00348 allocator_type const& allocator () const 00349 { return this->_buffer.allocator (); } 00350 00351 private: 00352 template <typename B> friend 00353 typename ring_buffer<B>::range& 00354 range (ring_buffer<B>& buf); 00355 00356 template <typename B> friend 00357 const typename ring_buffer<B>::const_range 00358 const_range (const ring_buffer<B>& buf); 00359 }; 00360 00361 /* 00362 * 00363 * @todo BufferConcept 00364 * 00365 */ 00366 00372 template <typename B> 00373 typename ring_buffer<B>::range& 00374 range (ring_buffer<B>& buf) 00375 { 00376 return buf._range; 00377 } 00378 00379 template <typename B> 00380 const typename ring_buffer<B>::const_range 00381 const_range (const ring_buffer<B>& buf) 00382 { 00383 return buf._range; 00384 } 00385 00386 /* 00387 * 00388 * FrameBasedConcept 00389 * 00390 */ 00391 00392 template <typename Buffer> 00393 struct sample_type<ring_buffer<Buffer> > : 00394 public sample_type<Buffer> {}; 00395 00396 template <typename Buffer> 00397 struct channel_space_type<ring_buffer<Buffer> > : 00398 public channel_space_type<Buffer> {}; 00399 00400 template <typename Buffer> 00401 struct sample_mapping_type<ring_buffer<Buffer> > : 00402 public sample_mapping_type<Buffer> {}; 00403 00404 template <typename Buffer> 00405 struct is_planar<ring_buffer<Buffer> > : 00406 public is_planar<Buffer> {}; 00407 00408 00409 /* 00410 * 00411 * @todo DynamicStepTypeConcept 00412 * 00413 */ 00414 00415 } /* namespace sound */ 00416 } /* namespace psynth */ 00417 00418 #endif /* PSYNTH_SOUND_RING_BUFFER_H_ */ 00419
1.7.4