libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/graph/node.hpp
Go to the documentation of this file.
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 */