|
libpsynth 0.2.1
|
00001 /*************************************************************************** 00002 * * 00003 * PSYCHOSYNTH * 00004 * =========== * 00005 * * 00006 * Copyright (C) Juan Pedro Bolivar Puente 2007 * 00007 * * 00008 * This program is free software: you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation, either version 3 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00020 * * 00021 ***************************************************************************/ 00022 00023 #ifndef PSYNTH_NODE_H 00024 #define PSYNTH_NODE_H 00025 00026 #include <list> 00027 #include <vector> 00028 #include <cmath> 00029 #include <set> 00030 #include <iostream> 00031 #include <algorithm> 00032 #include <thread> 00033 00034 #include <psynth/base/vector_2d.hpp> 00035 #include <psynth/base/pointer.hpp> 00036 #include <psynth/synth/simple_envelope.hpp> 00037 #include <psynth/synth/audio_info.hpp> 00038 00039 #include <psynth/graph/buffers.hpp> 00040 #include <psynth/graph/node_param.hpp> 00041 #include <psynth/graph/watch.hpp> 00042 00043 namespace psynth 00044 { 00045 namespace graph 00046 { 00047 00048 class node 00049 { 00050 public: 00051 static const int NULL_ID = -1; 00052 00053 enum link_type { 00054 LINK_NONE = -1, 00055 LINK_AUDIO, 00056 LINK_CONTROL, 00057 LINK_TYPES 00058 }; 00059 00060 enum commom_params { 00061 PARAM_POSITION = 0, 00062 PARAM_RADIOUS, 00063 PARAM_MUTE, 00064 N_COMMON_PARAMS 00065 }; 00066 00067 typedef synth::simple_envelope<sample_range> link_envelope; 00068 00069 class out_socket { 00070 friend class node; 00071 00072 int m_type; 00073 std::list<std::pair<node*, int> > m_ref; /* Objetos y puertos destino */ 00074 00075 protected: 00076 out_socket (int type) 00077 : m_type(type) 00078 {} 00079 00080 bool is_empty () { 00081 return m_ref.empty(); 00082 } 00083 00084 void add_reference (node* obj, int port) { 00085 m_ref.push_back(std::pair<node*, int>(obj, port)); 00086 } 00087 00088 void remove_reference (node* obj, int port) { 00089 m_ref.remove(std::pair<node*, int>(obj, port)); 00090 } 00091 00092 void clear_references () { 00093 std::list<std::pair<node*, int> >::iterator i, r; 00094 for (i = m_ref.begin(); i != m_ref.end(); ) { 00095 r = i++; 00096 r->first->connect_in (m_type, r->second, NULL, 0); 00097 } 00098 } 00099 00100 public: 00101 const std::list<std::pair<node*, int> >& get_references () const { 00102 return m_ref; 00103 } 00104 }; 00105 00106 class in_socket 00107 { 00108 friend class node; 00109 00110 void attach_watch (watch* watch) { 00111 m_watchs.push_back(watch); 00112 } 00113 00114 void detach_watch (watch* watch) { 00115 m_watchs.remove(watch); 00116 }; 00117 00118 protected: 00119 int m_type; 00120 node* m_srcobj; 00121 int m_srcport; 00122 std::list<watch*> m_watchs; 00123 00124 in_socket (int type) : 00125 m_type(type), m_srcobj(NULL), m_srcport(0) {} 00126 00127 bool is_empty () { 00128 return m_srcobj == NULL; 00129 } 00130 00131 void set(node* srcobj, int port) { 00132 m_srcobj = srcobj; 00133 m_srcport = port; 00134 } 00135 00136 void update_input (const node* caller, int caller_port_type, int caller_port); 00137 00138 template <typename SocketDataType> 00139 const SocketDataType* get_data (int type) const { 00140 if (m_srcobj) 00141 return m_srcobj->get_output <SocketDataType> (type, m_srcport); 00142 else 00143 return NULL; 00144 } 00145 00146 public: 00147 virtual ~in_socket() { 00148 for_each (m_watchs.begin(), m_watchs.end(), base::deleter<watch*>()); 00149 } 00150 00151 virtual node* get_source_node () const { 00152 return m_srcobj; 00153 } 00154 00155 virtual int get_source_socket () const { 00156 return m_srcport; 00157 } 00158 }; 00159 00160 class in_socket_manual : public in_socket 00161 { 00162 friend class node; 00163 00164 bool must_update; 00165 node* src_obj; 00166 int src_sock; 00167 00168 public: 00169 in_socket_manual(int type) : 00170 in_socket(type), 00171 must_update(false), 00172 src_obj(NULL), 00173 src_sock(-1) {} 00174 00175 virtual node* get_source_node () const { 00176 return src_obj; 00177 } 00178 00179 virtual int get_source_socket () const { 00180 return src_sock; 00181 } 00182 }; 00183 00184 private: 00185 audio_info m_audioinfo; 00186 00187 std::vector<audio_buffer> m_outdata_audio; 00188 std::vector<sample_buffer> m_outdata_control; 00189 00190 std::vector<out_socket> m_out_sockets[LINK_TYPES]; 00191 std::vector<sample> m_out_stable_value[LINK_TYPES]; 00192 std::vector<in_socket_manual> m_in_sockets[LINK_TYPES]; 00193 std::vector<link_envelope> m_in_envelope[LINK_TYPES]; 00194 link_envelope m_out_envelope; 00195 00196 std::vector<node_param*> m_params; 00197 node_param m_null_param; 00198 int m_nparam; 00199 00200 int m_id; 00201 int m_type; 00202 std::string m_name; 00203 00204 base::vector_2f m_param_position; 00205 float m_param_radious; 00206 int m_param_mute; 00207 00208 /* For !m_single_update, contains the nodes that has 00209 * been updated (<obj_id, port_id>) */ 00210 std::set<std::pair<int,int> > m_updated_links[LINK_TYPES]; 00211 bool m_updated; 00212 bool m_single_update; 00213 00214 std::mutex m_paramlock; 00215 00216 void blend_buffer (sample* buf, 00217 int n_elem, 00218 sample stable_value, 00219 link_envelope env); 00220 00221 void update_params_out (); 00222 void update_inputs (); 00223 void update_in_sockets (); 00224 void set_envelopes_deltas (); 00225 void update_envelopes (); 00226 bool can_update (const node* caller, int caller_port_type, 00227 int caller_port); 00228 00229 protected: 00230 template <typename SocketDataType> 00231 SocketDataType* get_output (int type, int socket) { 00232 if (m_param_mute && m_out_envelope.finished()) 00233 return NULL; 00234 00235 /* TODO: Find a way to do type checking */ 00236 switch(type) { 00237 case LINK_AUDIO: 00238 return reinterpret_cast<SocketDataType*>(&(m_outdata_audio[socket])); 00239 break; 00240 case LINK_CONTROL: 00241 return reinterpret_cast<SocketDataType*>(&(m_outdata_control[socket])); 00242 break; 00243 default: 00244 break; 00245 } 00246 00247 return NULL; 00248 } 00249 00250 void set_output_stable_value (int sock_type, int sock_num, sample value) { 00251 m_out_stable_value[sock_type][sock_num] = value; 00252 } 00253 00254 virtual void do_update (const node* caller, int caller_port_type, int caller_port) = 0; 00255 virtual void do_advance () = 0; 00256 virtual void on_info_change () = 0; 00257 00258 void del_param (int index); 00259 void add_param (const std::string&, int type, void* val); 00260 void add_param (const std::string&, int type, void* val, node_param::event ev); 00261 00262 link_envelope get_in_envelope (int type, int sock) 00263 { return m_in_envelope[type][sock]; } 00264 00265 public: 00266 node (const audio_info& prop, int type, 00267 const std::string& name, 00268 int inaudiosocks, int incontrolsocks, 00269 int outaudiosocks, int outcontrolsocks, 00270 bool single_update = true); 00271 00272 virtual ~node(); 00273 00274 int get_type () const { 00275 return m_type; 00276 }; 00277 00278 const std::string& get_name () const { 00279 return m_name; 00280 } 00281 00282 void update_params_in (); 00283 void update (const node* caller, int caller_port_type, int caller_port); 00284 00285 void advance () { 00286 m_updated = false; 00287 if (!m_single_update) { 00288 m_updated_links[LINK_AUDIO].clear(); 00289 m_updated_links[LINK_CONTROL].clear(); 00290 } 00291 00292 do_advance(); 00293 } 00294 00295 const audio_info& get_info () const { 00296 return m_audioinfo; 00297 } 00298 00299 void set_info(const audio_info& info); 00300 00301 void attach_watch (int type, int in_socket, watch* watch) { 00302 watch->set_info (m_audioinfo); 00303 m_in_sockets[type][in_socket].attach_watch(watch); 00304 } 00305 00306 void detach_watch (int type, int in_socket, watch* watch) { 00307 m_in_sockets[type][in_socket].detach_watch(watch); 00308 } 00309 00310 void connect_in (int type, int in_socket, node* src, int out_socket); 00311 00312 void force_connect_in (int type, int in_socket, node* src, int out_socket); 00313 00314 void clear_connections (); 00315 00316 bool has_connections (); 00317 00318 node_param& param (int id) { 00319 return *m_params[id]; 00320 } 00321 00322 const node_param& param (int id) const { 00323 return *m_params[id]; 00324 } 00325 00326 node_param& get_param (const std::string& name); 00327 00328 const node_param& get_param (const std::string& name) const; 00329 00330 template <typename SocketDataType> 00331 const SocketDataType* get_output (int type, int socket) const { 00332 return get_output <SocketDataType> (type, socket); 00333 } 00334 00335 template <typename SocketDataType> 00336 const SocketDataType* get_input(int type, int socket) const { 00337 return m_in_sockets[type][socket].get_data<SocketDataType>(type); 00338 } 00339 00340 const out_socket& get_out_socket(int type, int socket) const { 00341 return m_out_sockets[type][socket]; 00342 } 00343 00344 const in_socket& get_in_socket(int type, int socket) const { 00345 return m_in_sockets[type][socket]; 00346 } 00347 00348 int get_num_output (int type) const { 00349 return m_out_sockets[type].size(); 00350 } 00351 00352 int get_num_input (int type) const { 00353 return m_in_sockets[type].size(); 00354 } 00355 00356 int get_id () const { 00357 return m_id; 00358 } 00359 00360 void set_id (int id) { 00361 m_id = id; 00362 } 00363 00364 float distance_to (const node &obj) const { 00365 return m_param_position.distance(obj.m_param_position); 00366 } 00367 00368 float sqr_distance_to (const node &obj) const { 00369 return m_param_position.sqr_distance (obj.m_param_position); 00370 } 00371 00372 float distance_to_center () const { 00373 return m_param_position.length(); 00374 } 00375 00376 float sqr_distance_to_center () const { 00377 return m_param_position.sqr_length(); 00378 } 00379 00380 float distance_to (const base::vector_2f& obj) const { 00381 return m_param_position.distance(obj); 00382 } 00383 00384 float sqr_distance_to (const base::vector_2f &obj) const { 00385 return m_param_position.sqr_distance(obj); 00386 } 00387 }; 00388 00389 } /* namespace graph */ 00390 } /* namespace psynth */ 00391 00392 #endif /* PSYNTH_NODE_H */
1.7.4