Merge branch 'master' of git.ardour.org:ardour/ardour
[ardour.git] / libs / ardour / ardour / audioengine.h
index 390c0bbda6a3c4671cb27d223e0dd84503e3578d..165ad6744f341db3d809bc56b22ee6f0744a748c 100644 (file)
 #include <exception>
 #include <string>
 
-#include <glibmm/thread.h>
+#include <glibmm/threads.h>
 
 #include "pbd/rcu.h"
 #include "pbd/signals.h"
+#include "pbd/stacktrace.h"
 
-#include "ardour/ardour.h"
+#include <jack/weakjack.h>
 #include <jack/jack.h>
 #include <jack/transport.h>
+#include <jack/thread.h>
+
+#include "ardour/ardour.h"
 
 #include "ardour/data_type.h"
 #include "ardour/session_handle.h"
@@ -59,13 +63,8 @@ class ProcessThread;
 
 class AudioEngine : public SessionHandlePtr
 {
-   public:
-       typedef std::set<Port*> Ports;
-
-        class disconnected_exception : public std::exception {
-          public:
-                virtual const char *what() const throw() { return "AudioEngine is disconnected"; }
-        };
+public:
+       typedef std::map<std::string,boost::shared_ptr<Port> > Ports;
 
        AudioEngine (std::string client_name, std::string session_uuid);
        virtual ~AudioEngine ();
@@ -75,21 +74,18 @@ class AudioEngine : public SessionHandlePtr
 
        bool is_realtime () const;
 
-        ProcessThread* main_thread() const { return _main_thread; }
+       ProcessThread* main_thread() const { return _main_thread; }
 
        std::string client_name() const { return jack_client_name; }
 
        int reconnect_to_jack ();
        int disconnect_from_jack();
 
-       bool will_reconnect_at_halt ();
-       void set_reconnect_at_halt (bool);
-
        int stop (bool forever = false);
        int start ();
        bool running() const { return _running; }
 
-       Glib::Mutex& process_lock() { return _process_lock; }
+       Glib::Threads::Mutex& process_lock() { return _process_lock; }
 
        framecnt_t frame_rate () const;
        pframes_t frames_per_cycle () const;
@@ -107,7 +103,7 @@ class AudioEngine : public SessionHandlePtr
                }
                return jack_frames_since_cycle_start (_priv_jack);
        }
-       
+
        pframes_t frame_time () {
                jack_client_t* _priv_jack = _jack;
                if (!_running || !_priv_jack) {
@@ -134,7 +130,6 @@ class AudioEngine : public SessionHandlePtr
 
        int request_buffer_size (pframes_t);
 
-       framecnt_t set_monitor_check_interval (framecnt_t);
        framecnt_t processed_frames() const { return _processed_frames; }
 
        float get_cpu_load() {
@@ -166,15 +161,18 @@ class AudioEngine : public SessionHandlePtr
                virtual const char *what() const throw() { return "could not connect to engine backend"; }
        };
 
-       Port *register_input_port (DataType, const std::string& portname);
-       Port *register_output_port (DataType, const std::string& portname);
-       int   unregister_port (Port &);
+       boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname);
+       boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname);
+       int unregister_port (boost::shared_ptr<Port>);
+
+       bool port_is_physical (const std::string&) const;
+       void request_jack_monitors_input (const std::string&, bool) const;
 
        void split_cycle (pframes_t offset);
 
        int connect (const std::string& source, const std::string& destination);
        int disconnect (const std::string& source, const std::string& destination);
-       int disconnect (Port &);
+       int disconnect (boost::shared_ptr<Port>);
 
        const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
 
@@ -186,10 +184,8 @@ class AudioEngine : public SessionHandlePtr
        void get_physical_outputs (DataType type, std::vector<std::string>&);
        void get_physical_inputs (DataType type, std::vector<std::string>&);
 
-       void update_total_latencies ();
-       void update_total_latency (const Port&);
-
-       Port *get_port_by_name (const std::string &);
+       boost::shared_ptr<Port> get_port_by_name (const std::string &);
+       void port_renamed (const std::string&, const std::string&);
 
        enum TransportState {
                TransportStopped = JackTransportStopped,
@@ -205,6 +201,8 @@ class AudioEngine : public SessionHandlePtr
 
        int  reset_timebase ();
 
+        void update_latencies ();
+
        /* start/stop freewheeling */
 
        int freewheel (bool onoff);
@@ -247,26 +245,32 @@ _    the regular process() call to session->process() is not made.
 
        /** Emitted if a JACK port is connected or disconnected.
         *  The Port parameters are the ports being connected / disconnected, or 0 if they are not known to Ardour.
+        *  The std::string parameters are the (long) port names.
         *  The bool parameter is true if ports were connected, or false for disconnected.
         */
-       PBD::Signal3<void, Port *, Port *, bool> PortConnectedOrDisconnected;
+       PBD::Signal5<void, boost::weak_ptr<Port>, std::string, boost::weak_ptr<Port>, std::string, bool> PortConnectedOrDisconnected;
 
-       std::string make_port_name_relative (std::string);
-       std::string make_port_name_non_relative (std::string);
+       std::string make_port_name_relative (std::string) const;
+       std::string make_port_name_non_relative (std::string) const;
+       bool port_is_mine (const std::string&) const;
 
        static AudioEngine* instance() { return _instance; }
+       static void destroy();
        void died ();
 
-        int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
+       int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
 
-  private:
+private:
        static AudioEngine*       _instance;
 
        jack_client_t* volatile   _jack; /* could be reset to null by SIGPIPE or another thread */
        std::string                jack_client_name;
-       Glib::Mutex               _process_lock;
-       Glib::Cond                 session_removed;
+       Glib::Threads::Mutex      _process_lock;
+        Glib::Threads::Cond        session_removed;
        bool                       session_remove_pending;
+        frameoffset_t              session_removal_countdown;
+        gain_t                     session_removal_gain;
+        gain_t                     session_removal_gain_step;
        bool                      _running;
        bool                      _has_run;
        mutable framecnt_t        _buffer_size;
@@ -279,18 +283,18 @@ _    the regular process() call to session->process() is not made.
        /// the number of frames processed since start() was called
        framecnt_t                _processed_frames;
        bool                      _freewheeling;
-       bool                      _freewheel_pending;
-       boost::function<int(framecnt_t)>  freewheel_action;
-       bool                       reconnect_on_halt;
+       bool                      _pre_freewheel_mmc_enabled;
        int                       _usecs_per_cycle;
+       bool                       port_remove_in_progress;
+        Glib::Threads::Thread*     m_meter_thread;
+       ProcessThread*            _main_thread;
 
        SerializedRCUManager<Ports> ports;
 
-       Port *register_port (DataType type, const std::string& portname, bool input);
+       boost::shared_ptr<Port> register_port (DataType type, const std::string& portname, bool input);
 
        int    process_callback (pframes_t nframes);
        void*  process_thread ();
-        void   finish_process_cycle (int status);
        void   remove_all_ports ();
 
        ChanCount n_physical (unsigned long) const;
@@ -303,7 +307,6 @@ _      the regular process() call to session->process() is not made.
        static void _session_callback (jack_session_event_t *event, void *arg);
 #endif
        static int  _graph_order_callback (void *arg);
-       static int  _process_callback (pframes_t nframes, void *arg);
        static void* _process_thread (void *arg);
        static int  _sample_rate_callback (pframes_t nframes, void *arg);
        static int  _bufsize_callback (pframes_t nframes, void *arg);
@@ -317,6 +320,13 @@ _     the regular process() call to session->process() is not made.
        int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
        int  jack_bufsize_callback (pframes_t);
        int  jack_sample_rate_callback (pframes_t);
+       void freewheel_callback (int);
+        void connect_callback (jack_port_id_t, jack_port_id_t, int);
+
+       void set_jack_callbacks ();
+
+       static void _latency_callback (jack_latency_callback_mode_t, void*);
+       void jack_latency_callback (jack_latency_callback_mode_t);
 
        int connect_to_jack (std::string client_name, std::string session_uuid);
 
@@ -327,21 +337,20 @@ _    the regular process() call to session->process() is not made.
        void start_metering_thread ();
        void stop_metering_thread ();
 
-       Glib::Thread*    m_meter_thread;
        static gint      m_meter_exit;
 
-        ProcessThread* _main_thread;
-
-        struct ThreadData {
-            AudioEngine* engine;
-            boost::function<void()> f;
-            size_t stacksize;
-            
-            ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz) 
-            : engine (ae) , f (fp) , stacksize (stacksz) {}
-        };
-        
-        static void* _start_process_thread (void*);
+       struct ThreadData {
+               AudioEngine* engine;
+               boost::function<void()> f;
+               size_t stacksize;
+
+               ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz)
+               : engine (ae) , f (fp) , stacksize (stacksz) {}
+       };
+
+       static void* _start_process_thread (void*);
+        void parameter_changed (const std::string&);
+        PBD::ScopedConnection config_connection;
 };
 
 } // namespace ARDOUR