libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/io/buffered_input.hpp
Go to the documentation of this file.
00001 
00011 /*
00012  *  Copyright (C) 2011 Juan Pedro BolĂ­var 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_IO_BUFFERED_INPUT_H_
00032 #define PSYNTH_IO_BUFFERED_INPUT_H_
00033 
00034 #include <psynth/base/type_traits.hpp>
00035 #include <psynth/io/input.hpp>
00036 
00037 namespace psynth
00038 {
00039 namespace io
00040 {
00041 
00042 namespace detail
00043 {
00044 
00045 template <class Range, class InputPtr> 
00046 class buffered_input_impl : public input<Range>
00047 {
00048 public:
00049     typedef Range range;
00050     
00051     typedef typename base::pointee<InputPtr>::type input_type;
00052     typedef typename input_type::range                   input_range;
00053 
00054     typedef typename sound::buffer_from_range<input_range>::type
00055     buffer_type;
00056 
00057     buffered_input_impl (InputPtr input_ptr = 0)
00058         : _buffer (default_input_buffer_size)
00059         , _input_ptr (input_ptr)
00060     {}
00061     
00062     std::size_t take (const range& data);
00063     
00064     template <class Range2>
00065     std::size_t take (const Range2& data);
00066 
00067     input_type& input ()
00068     { return *_input_ptr; }
00069 
00070     const input_type& input () const
00071     { return *_input_ptr; }
00072 
00073     const buffer_type& buffer () const
00074     { return _buffer; }
00075     
00076     void set_buffer_size (std::size_t new_size)
00077     { _buffer.recreate (new_size); }
00078 
00079 protected:
00080     void set_input (InputPtr ptr)
00081     {
00082         _input_ptr = ptr;
00083         this->fit_buffer ();
00084     }
00085 
00086     buffer_type _buffer;
00087     InputPtr   _input_ptr;
00088 };
00089 
00090 
00091 template <class Range, class InputPtr> 
00092 class buffered_async_input_impl :
00093         public buffered_input_impl<Range, InputPtr>
00094 {
00095 public:
00096     typedef  buffered_input_impl<Range, InputPtr> base;
00097     
00098     buffered_async_input_impl (InputPtr input_ptr = 0)
00099         : base (input_ptr)
00100     {}
00101 
00102     void fit_buffer ();
00103 };
00104 
00105 } /* namespace detail */
00106 
00107 
00108 template <class Range, class InputPtr>
00109 class buffered_input_adapter :
00110     public detail::buffered_input_impl<Range, InputPtr>
00111 {
00112 public:
00113     typedef detail::buffered_input_impl<Range, InputPtr> base;
00114     
00115     buffered_input_adapter (InputPtr in = 0)
00116         : base (in)
00117     { }
00118     
00119     void set_input (InputPtr in = 0)
00120     { base::set_input (in); }
00121 };
00122 
00123 template <class Range, class InputPtr>
00124 class buffered_async_input_adapter :
00125     public detail::buffered_input_impl<Range, InputPtr>
00126 {
00127 public:
00128     typedef detail::buffered_input_impl<Range, InputPtr> base;
00129     
00130     buffered_async_input_adapter (InputPtr in = 0)
00131         : base (in)
00132     { this->fit_buffer (); }
00133     
00134     void set_input (InputPtr in = 0)
00135     {
00136         this->set_input (in);
00137         this->fit_buffer ();
00138     }
00139 };
00140 
00141 
00142 template <class Range, class Input>
00143 class buffered_async_input :
00144     public detail::buffered_async_input_impl<Range, Input*>
00145 {
00146 public:   
00147     typedef detail::buffered_async_input_impl<Range, Input*> base;
00148 
00152     template <typename... Args>
00153     buffered_async_input (Args... args)
00154         : base (&_input)
00155         , _input (args...)
00156     {}
00157 
00158 private:
00159     Input _input;
00160 };
00161 
00162 
00163 template <class Range, class Input>
00164 class buffered_input :
00165     public detail::buffered_input_impl<Range, Input*>
00166 {   
00167 public:
00168     typedef detail::buffered_input_impl<Range, Input*> base;
00169  
00170     template <typename... Args>
00171     buffered_input (Args... args)
00172         : base (&_input)
00173         , _input (args...)
00174     {}
00175 
00176 private:
00177     Input _input;
00178 };
00179 
00180 namespace detail
00181 {
00182 
00183 template <class InputPtr>
00184 struct is_async_ptr : public std::is_base_of<
00185     async_base,
00186     typename boost::pointee<InputPtr>::type> {};
00187 
00188 } /* namespace detail */
00189 
00190 template <class Range, class InputPtr>
00191 typename std::enable_if<
00192     !detail::is_async_ptr<InputPtr>::value,
00193     buffered_input_adapter<Range, InputPtr>
00194     >::type
00195 make_buffered_input (InputPtr in)
00196 {
00197     return buffered_input_adapter<Range, InputPtr> (in);
00198 }
00199 
00200 template <class Range, class InputPtr>
00201 typename std::enable_if<
00202     detail::is_async_ptr<InputPtr>::value,
00203     buffered_async_input_adapter<Range, InputPtr>
00204     >::type
00205 make_buffered_input (InputPtr in)
00206 {
00207     return buffered_async_input_adapter<Range, InputPtr> (in);
00208 }
00209 
00210 } /* namespace io */
00211 } /* namespace psynth */
00212 
00213 #include <psynth/io/buffered_input.tpp>
00214 
00215 #endif /* PSYNTH_IO_BUFFERED_INPUT_H_ */
00216