|
libpsynth 0.2.1
|
00001 00019 /* 00020 * Copyright (C) 2011 Juan Pedro BolĂvar Puente 00021 * 00022 * This file is part of Psychosynth. 00023 * 00024 * Psychosynth is free software: you can redistribute it and/or modify 00025 * it under the terms of the GNU General Public License as published by 00026 * the Free Software Foundation, either version 3 of the License, or 00027 * (at your option) any later version. 00028 * 00029 * Psychosynth is distributed in the hope that it will be useful, 00030 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00031 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00032 * GNU General Public License for more details. 00033 * 00034 * You should have received a copy of the GNU General Public License 00035 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00036 * 00037 */ 00038 00039 #ifndef PSYNTH_IO_BUFFERED_OUTPUT_H_ 00040 #define PSYNTH_IO_BUFFERED_OUTPUT_H_ 00041 00042 00043 #include <psynth/base/type_traits.hpp> 00044 #include <psynth/sound/metafunctions.hpp> 00045 #include <psynth/io/output.hpp> 00046 00047 namespace psynth 00048 { 00049 namespace io 00050 { 00051 00052 namespace detail 00053 { 00054 00055 template <class Base, // either output or async_output 00056 class OutputPtr> 00057 class buffered_output_impl : public Base 00058 { 00059 public: 00060 typedef typename Base::range range; 00061 typedef typename Base::const_range const_range; 00062 00063 typedef typename base::pointee<OutputPtr>::type output_type; 00064 typedef typename output_type::range output_range; 00065 typedef typename output_type::const_range output_const_range; 00066 00067 typedef typename sound::buffer_from_range<output_range>::type 00068 buffer_type; 00069 00070 buffered_output_impl (OutputPtr output_ptr = 0) 00071 : _buffer (default_output_buffer_size) 00072 , _output_ptr (output_ptr) 00073 {} 00074 00075 std::size_t put (const const_range& data); 00076 00077 template <class Range2> 00078 std::size_t put (const Range2& data); 00079 00080 output_type& output () 00081 { return *_output_ptr; } 00082 00083 const output_type& output () const 00084 { return *_output_ptr; } 00085 00086 const buffer_type& buffer () const 00087 { return _buffer; } 00088 00089 void set_buffer_size (std::size_t new_size) 00090 { _buffer.recreate (new_size); } 00091 00092 protected: 00093 void set_output (OutputPtr ptr) 00094 { 00095 _output_ptr = ptr; 00096 } 00097 00098 buffer_type _buffer; 00099 OutputPtr _output_ptr; 00100 }; 00101 00102 template <class Base, class OutputPtr> 00103 class buffered_async_output_impl : 00104 public buffered_output_impl<Base, OutputPtr> 00105 { 00106 public: 00107 typedef buffered_output_impl<Base, OutputPtr> base; 00108 typedef typename base::callback_type callback_type; 00109 00110 buffered_async_output_impl (OutputPtr output_ptr = 0) 00111 : base (output_ptr) 00112 {} 00113 00114 void fit_buffer (); 00115 00116 std::size_t buffer_size () const 00117 { return this->_output_ptr->buffer_size (); } 00118 00119 void start () 00120 { this->_output_ptr->start (); } 00121 00122 void stop () 00123 { this->_output_ptr->stop (); } 00124 00125 async_state state () const 00126 { return this->_output_ptr->state (); } 00127 00128 void set_callback (callback_type cb) 00129 { this->_output_ptr->set_callback (cb); } 00130 }; 00131 00132 } /* namespace detail */ 00133 00134 00135 template <class Range, class OutputPtr> 00136 class buffered_output_adapter : 00137 public detail::buffered_output_impl<output<Range>, OutputPtr> 00138 { 00139 public: 00140 typedef detail::buffered_output_impl<output<Range>, OutputPtr> base; 00141 00142 buffered_output_adapter (OutputPtr out = 0) 00143 : base (out) 00144 { } 00145 00146 void set_output (OutputPtr out = 0) 00147 { base::set_output (out); } 00148 }; 00149 00150 00151 template <class Range, class Output> 00152 class buffered_output : 00153 public detail::buffered_output_impl<output<Range>, Output*> 00154 { 00155 public: 00156 typedef detail::buffered_output_impl<output<Range>, Output*> base; 00157 00158 template <typename... Args> 00159 buffered_output (Args... args) 00160 : base (&_output) 00161 , _output (args...) 00162 {} 00163 00164 private: 00165 Output _output; 00166 }; 00167 00168 00169 template <class Range, class OutputPtr> 00170 class buffered_async_output_adapter : 00171 public detail::buffered_async_output_impl<async_output<Range>, OutputPtr> 00172 { 00173 public: 00174 typedef detail::buffered_async_output_impl<async_output<Range>, 00175 OutputPtr> base; 00176 00177 buffered_async_output_adapter (OutputPtr out = 0) 00178 : base (out) 00179 { this->fit_buffer (); } 00180 00181 void set_output (OutputPtr out = 0) 00182 { 00183 this->set_output (out); 00184 this->fit_buffer (); 00185 } 00186 }; 00187 00188 00189 template <class Range, class Output> 00190 class buffered_async_output : 00191 public detail::buffered_async_output_impl<async_output<Range>, Output*> 00192 { 00193 public: 00194 typedef detail::buffered_async_output_impl<async_output<Range>, 00195 Output*> base; 00196 00200 template <typename... Args> 00201 buffered_async_output (Args... args) 00202 : base (&_output) 00203 , _output (args...) 00204 { 00205 this->fit_buffer (); 00206 } 00207 00208 private: 00209 Output _output; 00210 }; 00211 00212 namespace detail 00213 { 00214 00215 template <class OutputPtr> 00216 struct is_async_ptr : public std::is_base_of< 00217 async_base, 00218 typename boost::pointee<OutputPtr>::type> {}; 00219 00220 } /* namespace detail */ 00221 00222 template <class Range, class OutputPtr> 00223 typename std::enable_if< 00224 !detail::is_async_ptr<OutputPtr>::value, 00225 buffered_output_adapter<Range, OutputPtr> 00226 >::type 00227 make_buffered_output (OutputPtr out) 00228 { 00229 return buffered_output_adapter<Range, OutputPtr> (out); 00230 } 00231 00232 template <class Range, class OutputPtr> 00233 typename std::enable_if< 00234 detail::is_async_ptr<OutputPtr>::value, 00235 buffered_async_output_adapter<Range, OutputPtr> 00236 >::type 00237 make_buffered_output (OutputPtr out) 00238 { 00239 return buffered_async_output_adapter<Range, OutputPtr> (out); 00240 } 00241 00242 } /* namespace io */ 00243 } /* namespace psynth */ 00244 00245 #include <psynth/io/buffered_output.tpp> 00246 00247 #endif /* PSYNTH_IO_BUFFERED_OUTPUT_H_ */ 00248
1.7.4