|
libpsynth 0.2.1
|
00001 00017 /* 00018 * Copyright (C) 2008, 2009 Juan Pedro BolĂvar Puente 00019 * 00020 * This file is part of Psychosynth. 00021 * 00022 * Psychosynth is free software: you can redistribute it and/or modify 00023 * it under the terms of the GNU General Public License as published by 00024 * the Free Software Foundation, either version 3 of the License, or 00025 * (at your option) any later version. 00026 * 00027 * Psychosynth is distributed in the hope that it will be useful, 00028 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00029 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00030 * GNU General Public License for more details. 00031 * 00032 * You should have received a copy of the GNU General Public License 00033 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00034 * 00035 */ 00036 00037 #ifndef PSYNTH_SYNTH_MULTI_POINT_ENVELOPE_H 00038 #define PSYNTH_SYNTH_MULTI_POINT_ENVELOPE_H 00039 00040 #include <vector> 00041 #include <psynth/sound/forwards.hpp> 00042 #include <psynth/sound/algorithm.hpp> 00043 #include <psynth/synth/envelope.hpp> 00044 00045 namespace psynth 00046 { 00047 namespace synth 00048 { 00049 00050 template <class Sample> 00051 struct envelope_point 00052 { 00053 float dt; 00054 Sample val; 00055 }; 00056 00063 template <class Sample> 00064 class envelope_values 00065 { 00066 template <class R, class Vp> 00067 friend class multi_point_envelope; 00068 00069 public: 00070 typedef envelope_point<Sample> point; 00071 00072 envelope_values () 00073 : _sustain (1) 00074 , _factor (1.0f) 00075 {} 00076 00077 void set_asr (point a, point s, point r); 00078 void set_adsr (point a, point d, point s, point r); 00079 00080 void set_factor (float factor) 00081 { _factor = factor; } 00082 00083 float factor () const 00084 { return _factor; } 00085 00086 void set_sustain (std::size_t sustain) 00087 { _sustain = sustain; } 00088 00089 void set (const std::vector<point>& p, std::size_t sustain) 00090 { 00091 _points = p; 00092 _sustain = sustain; 00093 } 00094 00095 point& get (std::size_t index) 00096 { return _points [index]; } 00097 00098 const point& get (std::size_t index) const 00099 { return _points [index]; } 00100 00101 point& operator [] (int index) 00102 { return _points [index]; } 00103 00104 const point& operator[] (int index) const 00105 { return _points [index]; } 00106 00107 std::size_t size () const 00108 { return _points.size (); } 00109 00110 void resize (std::size_t size) 00111 { _points.resize (size); } 00112 00113 private: 00114 std::vector<point> _points; 00115 std::size_t _sustain; 00116 float _factor; 00117 }; 00118 00119 template <class Range, 00120 typename ValuesPtr = 00121 envelope_values<typename sound::sample_type<Range>::type>* > 00122 class multi_point_envelope : public envelope<Range> 00123 { 00124 public: 00125 typedef Range range; 00126 typedef typename Range::value_type value_type; 00127 typedef ValuesPtr values_ptr; 00128 00129 multi_point_envelope (values_ptr val) 00130 : _val (val) 00131 , _cur_point (0) 00132 , _time (0.0f) 00133 , _pressed (false) 00134 {} 00135 00136 void set_values (values_ptr vals) 00137 { _val = vals; } 00138 00139 values_ptr get_values () 00140 { return _val; } 00141 00142 float time () const 00143 { return _time; } 00144 00145 void set_time (float time) 00146 { _time = time; } 00147 00148 void restart () 00149 { 00150 _time = 0; 00151 _cur_point = 0; 00152 } 00153 00154 void press () 00155 { 00156 if (multi_point_envelope::finished ()) 00157 multi_point_envelope::restart (); 00158 _pressed = true; 00159 } 00160 00161 void release () 00162 { _pressed = false; } 00163 00164 PSYNTH_FORCEINLINE value_type update () 00165 { return multi_point_envelope::update (1); } 00166 00167 value_type update (std::size_t sample); 00168 00169 void update (const range& samples) 00170 { 00171 generate_frames (samples, [&] () -> value_type { 00172 return this->multi_point_envelope::update (); 00173 }); 00174 } 00175 00176 bool finished () 00177 { return _cur_point >= _val->size() - 1; } 00178 00179 private: 00180 values_ptr _val; 00181 std::size_t _cur_point; 00182 float _time; 00183 bool _pressed; 00184 }; 00185 00186 } /* namespace synth */ 00187 } /* namespace psynth */ 00188 00189 #include <psynth/synth/multi_point_envelope.tpp> 00190 00191 #endif /* PSYNTH_SYNTH_MULTI_POINT_ENVELOPE_H */
1.7.4