treat VCA assign as a RouteGroup property.
[ardour.git] / libs / ardour / ardour / graph.h
index 80b5a9fe11ff53f30527be3b8efad7c46ea4c93b..239f9ad1abec406c2976e2d1dc48d83cdad47221 100644 (file)
@@ -1,6 +1,6 @@
 /*
-    Copyright (C) 2008 Paul Davis
-    Author: Sakari Bergen
+    Copyright (C) 2010 Paul Davis
+    Author: Torben Hohn
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
+
 #ifndef __ardour_graph_h__
 #define __ardour_graph_h__
 
+#include <list>
+#include <set>
+#include <vector>
+#include <string>
+
 #include <boost/shared_ptr.hpp>
 
-#include <ardour/types.h>
+#include <glib.h>
+
+#include "pbd/semutils.h"
+
+#include "ardour/libardour_visibility.h"
+#include "ardour/types.h"
+#include "ardour/audio_backend.h"
+#include "ardour/session_handle.h"
 
 namespace ARDOUR
 {
 
-/// Takes data in
-template <typename T>
-class GraphSink  {
-  public:
-       GraphSink () : end_of_input (false) {}
-       virtual ~GraphSink () { end_of_input = false; }
-       
-       // writes data and return number of frames written
-       virtual nframes_t write (T * data, nframes_t frames) = 0;
-       
-       // Notifies end of input. All left over data must be written at this stage
-       virtual void set_end_of_input (bool state = true)
-       {
-               end_of_input = state;
-       }
-
-  protected:
-       bool end_of_input;
-};
+class GraphNode;
+class Graph;
 
-/// is a source for data
-template <typename T>
-class GraphSource  {
-  public:
-       GraphSource () {}
-       virtual ~GraphSource () {}
-       
-       virtual nframes_t read (T * data, nframes_t frames) = 0;
-};
+class Route;
+class Session;
+class GraphEdges;
+
+typedef boost::shared_ptr<GraphNode> node_ptr_t;
+
+typedef std::list< node_ptr_t > node_list_t;
+typedef std::set< node_ptr_t > node_set_t;
+
+class LIBARDOUR_API Graph : public SessionHandleRef
+{
+public:
+       Graph (Session & session);
+
+       void prep();
+       void trigger (GraphNode * n);
+       void rechain (boost::shared_ptr<RouteList>, GraphEdges const &);
+
+       void dump (int chain);
+       void process();
+       void dec_ref();
+       void restart_cycle();
+
+       bool run_one();
+       void helper_thread();
+       void main_thread();
+
+       int silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+                                  bool& need_butler);
+
+       int process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
+                           bool& need_butler);
+
+       int routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
+                           bool non_rt_pending, int declick);
 
-/// Takes data in, processes it and passes it on to another sink
-template <typename TIn, typename TOut>
-class GraphSinkVertex : public GraphSink<TIn> {
-  public:
-       GraphSinkVertex () {}
-       virtual ~GraphSinkVertex () {}
-       
-       void pipe_to (boost::shared_ptr<GraphSink<TOut> > dest) {
-               piped_to = dest;
-       }
-       
-       nframes_t write (TIn * data, nframes_t frames)
-       {
-               if (!piped_to) {
-                       return -1;
-               }
-               return process (data, frames);
-       }       
-       
-       virtual void set_end_of_input (bool state = true)
-       {
-               if (!piped_to) {
-                       return;
-               }
-               piped_to->set_end_of_input (state);
-               GraphSink<TIn>::end_of_input = state;
-       }
-       
-  protected:
-       boost::shared_ptr<GraphSink<TOut> > piped_to;
-       
-       /* process must process data,
-          use piped_to->write to write the data
-          and return number of frames written */
-       virtual nframes_t process (TIn * data, nframes_t frames) = 0;
+       void process_one_route (Route * route);
+
+       void clear_other_chain ();
+
+       bool in_process_thread () const;
+
+protected:
+       virtual void session_going_away ();
+
+private:
+       volatile bool        _threads_active;
+
+       void reset_thread_list ();
+       void drop_threads ();
+
+       node_list_t _nodes_rt[2];
+
+       node_list_t _init_trigger_list[2];
+
+       std::vector<GraphNode *> _trigger_queue;
+       pthread_mutex_t          _trigger_mutex;
+
+       PBD::Semaphore _execution_sem;
+
+       /** Signalled to start a run of the graph for a process callback */
+       PBD::Semaphore _callback_start_sem;
+       PBD::Semaphore _callback_done_sem;
+       PBD::Semaphore _cleanup_sem;
+
+       /** The number of processing threads that are asleep */
+       volatile gint _execution_tokens;
+       /** The number of unprocessed nodes that do not feed any other node; updated during processing */
+       volatile gint _finished_refcount;
+       /** The initial number of nodes that do not feed any other node (for each chain) */
+       volatile gint _init_finished_refcount[2];
+
+       bool _graph_empty;
+
+       // chain swapping
+       Glib::Threads::Mutex  _swap_mutex;
+        Glib::Threads::Cond   _cleanup_cond;
+       volatile int _current_chain;
+       volatile int _pending_chain;
+       volatile int _setup_chain;
+
+       // parameter caches.
+       pframes_t  _process_nframes;
+       framepos_t _process_start_frame;
+       framepos_t _process_end_frame;
+       bool       _process_can_record;
+       bool       _process_non_rt_pending;
+       int        _process_declick;
+
+       bool _process_silent;
+       bool _process_noroll;
+       int  _process_retval;
+       bool _process_need_butler;
+
+       // enginer / thread connection
+       PBD::ScopedConnectionList engine_connections;
+       void engine_stopped ();
 };
 
-} // namespace ARDOUR
+} // namespace
 
 #endif /* __ardour_graph_h__ */
-