jack_audiobackend.cc finally compiles
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 30 Jul 2013 21:48:57 +0000 (17:48 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 30 Jul 2013 21:48:57 +0000 (17:48 -0400)
15 files changed:
gtk2_ardour/ardour_ui.cc
libs/ardour/ardour/audio_backend.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/jack_audiobackend.h
libs/ardour/ardour/jack_portengine.h
libs/ardour/ardour/port_manager.h
libs/ardour/ardour/session.h
libs/ardour/audioengine.cc
libs/ardour/jack_audiobackend.cc
libs/ardour/jack_connection.cc
libs/ardour/jack_portengine.cc
libs/ardour/lv2_plugin.cc
libs/ardour/port_manager.cc
libs/ardour/session_time.cc
libs/ardour/wscript

index aa71040f462547ce304e476f3d62d8cbf541a7f6..155826492b7e0d7fad832f30983c9dd68c54a789 100644 (file)
@@ -396,7 +396,7 @@ ARDOUR_UI::create_engine ()
        loading_message (_("Starting audio engine"));
 
        try {
-               engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::backend_client_name, ARDOUR_COMMAND_LINE::backend_session_uuid);
+               engine = ARDOUR::AudioEngine::create (ARDOUR_COMMAND_LINE::backend_client_name, ARDOUR_COMMAND_LINE::backend_session_uuid);
 
        } catch (...) {
 
@@ -487,7 +487,7 @@ ARDOUR_UI::post_engine ()
 
        update_disk_space ();
        update_cpu_load ();
-       update_sample_rate (engine->frame_rate());
+       update_sample_rate (engine->sample_rate());
        update_timecode_format ();
 
        Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
@@ -923,7 +923,7 @@ If you still wish to quit, please use the\n\n\
                _session = 0;
        }
 
-       engine->stop (true);
+       engine->stop ();
        quit ();
 }
 
index e8511d0c57b4b85823bcb55fa66c732a7d238a5d..4d6d6a6dd8d40d4acc4bd48c3bd6cee08dad6268 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <boost/function.hpp>
 
+#include "ardour/types.h"
+
 namespace ARDOUR {
 
 class AudioEngine;
@@ -45,6 +47,8 @@ class AudioBackend {
      */
     virtual std::string name() const = 0;
 
+    virtual void* private_handle() const = 0;
+
     /** return true if the underlying mechanism/API is still available
      * for us to utilize. return false if some or all of the AudioBackend
      * API can no longer be effectively used.
@@ -98,13 +102,6 @@ class AudioBackend {
      */
     virtual uint32_t available_output_channel_count (const std::string& device) const = 0;
 
-    enum SampleFormat {
-           Signed16bitInteger,
-           Signed24bitInteger,
-           Signed32bitInteger,
-           FloatingPoint
-    };
-
     /* Set the hardware parameters.
      * 
      * If called when the current state is stopped or paused,
@@ -163,15 +160,15 @@ class AudioBackend {
      */
     virtual int set_systemic_output_latency (uint32_t) = 0;
 
-    virtual std::string  get_device_name () const = 0;
-    virtual float        get_sample_rate () const = 0;
-    virtual uint32_t     get_buffer_size () const = 0;
-    virtual SampleFormat get_sample_format () const = 0;
-    virtual bool         get_interleaved () const = 0;
-    virtual uint32_t     get_input_channels () const = 0;
-    virtual uint32_t     get_output_channels () const = 0;
-    virtual uint32_t     get_systemic_input_latency () const = 0;
-    virtual uint32_t     get_systemic_output_latency () const = 0;
+    virtual std::string  device_name () const = 0;
+    virtual float        sample_rate () const = 0;
+    virtual uint32_t     buffer_size () const = 0;
+    virtual SampleFormat sample_format () const = 0;
+    virtual bool         interleaved () const = 0;
+    virtual uint32_t     input_channels () const = 0;
+    virtual uint32_t     output_channels () const = 0;
+    virtual uint32_t     systemic_input_latency () const = 0;
+    virtual uint32_t     systemic_output_latency () const = 0;
 
     /* Basic state control */
 
@@ -246,7 +243,7 @@ class AudioBackend {
      * Implementations can feel free to smooth the values returned over
      * time (e.g. high pass filtering, or its equivalent).
      */
-    virtual float get_cpu_load() const  = 0;
+    virtual float cpu_load() const  = 0;
 
     /* Transport Control (JACK is the only audio API that currently offers
        the concept of shared transport control)
@@ -260,14 +257,14 @@ class AudioBackend {
     virtual void transport_stop () {}
     /** return the current transport state
      */
-    virtual TransportState transport_state () { return TransportStopped; }
+    virtual TransportState transport_state () const { return TransportStopped; }
     /** Attempt to locate the transport to @param pos
      */
     virtual void transport_locate (framepos_t /*pos*/) {}
     /** Return the current transport location, in samples measured
      * from the origin (defined by the transport time master)
      */
-    virtual framepos_t transport_frame() { return 0; }
+    virtual framepos_t transport_frame() const { return 0; }
 
     /** If @param yn is true, become the time master for any inter-application transport
      * timebase, otherwise cease to be the time master for the same.
@@ -279,9 +276,7 @@ class AudioBackend {
      */
     virtual int set_time_master (bool /*yn*/) { return 0; }
 
-    virtual framecnt_t sample_rate () const;
-    virtual pframes_t  samples_per_cycle () const;
-    virtual int        usecs_per_cycle () const { return 1000000 * (samples_per_cycle() / sample_rate()); }
+    virtual int        usecs_per_cycle () const { return 1000000 * (buffer_size() / sample_rate()); }
     virtual size_t     raw_buffer_size (DataType t);
     
     /* Process time */
@@ -338,7 +333,7 @@ class AudioBackend {
      */
     virtual int create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize) = 0;
     
-  private:
+  protected:
     AudioEngine&          engine;
 };
 
index d7d9ca8224a4cdd1b5a227a20a05de9d21c14d44..4ac9221238c98e4ad27385d08e043dbc8d9e919f 100644 (file)
@@ -104,7 +104,8 @@ public:
     pframes_t      samples_since_cycle_start ();
     bool           get_sync_offset (pframes_t& offset) const;
     int            create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize);
-    
+    bool           is_realtime() const;
+
     /* END BACKEND PROXY API */
 
     bool freewheeling() const { return _freewheeling; }
@@ -180,13 +181,21 @@ public:
     static void destroy();
     void died ();
     
-    /* The backend will cause this at the appropriate time(s)
+    /* The backend will cause these at the appropriate time(s)
      */
-    int process_callback (pframes_t nframes);
+    int  process_callback (pframes_t nframes);
+    int  buffer_size_change (pframes_t nframes);
+    int  sample_rate_change (pframes_t nframes);
+    void freewheel_callback (bool);
+    void timebase_callback (TransportState state, pframes_t nframes, framepos_t pos, int new_position);
+    int  sync_callback (TransportState state, framepos_t position);
+    int  port_registration_callback ();
+    void latency_callback (bool for_playback);
+    void halted_callback (const char* reason);
+
+    /* sets up the process callback thread */
+    static void thread_init_callback (void *);
 
-    int buffer_size_change (pframes_t nframes);
-    int sample_rate_change (pframes_t nframes);
-    
   private:
     AudioEngine (const std::string&  client_name, const std::string& session_uuid);
 
index 6d2683790c15a789ef960d2fc0d10e90479a4179..8f6e636d1af85a96c52123d863ca3bc2cb348e6a 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <string>
 #include <vector>
+#include <map>
 
 #include <stdint.h>
 
@@ -38,10 +39,11 @@ class JackConnection;
 
 class JACKAudioBackend : public AudioBackend {
   public:
-    JACKAudioBackend (AudioEngine& e);
+    JACKAudioBackend (AudioEngine& e, void*);
     ~JACKAudioBackend ();
 
     std::string name() const;
+    void* private_handle() const;
     bool connected() const;
     bool is_realtime () const;
 
@@ -61,34 +63,53 @@ class JACKAudioBackend : public AudioBackend {
     int set_systemic_input_latency (uint32_t);
     int set_systemic_output_latency (uint32_t);
 
-    std::string  get_device_name () const;
-    float        get_sample_rate () const;
-    uint32_t     get_buffer_size () const;
-    SampleFormat get_sample_format () const;
-    bool         get_interleaved () const;
-    uint32_t     get_input_channels () const;
-    uint32_t     get_output_channels () const;
-    uint32_t     get_systemic_input_latency () const;
-    uint32_t     get_systemic_output_latency () const;
+    std::string  device_name () const;
+    float        sample_rate () const;
+    uint32_t     buffer_size () const;
+    SampleFormat sample_format () const;
+    bool         interleaved () const;
+    uint32_t     input_channels () const;
+    uint32_t     output_channels () const;
+    uint32_t     systemic_input_latency () const;
+    uint32_t     systemic_output_latency () const;
 
     int start ();
     int stop ();
     int pause ();
     int freewheel (bool);
 
+    float cpu_load() const;
+
+    pframes_t sample_time ();
+    pframes_t sample_time_at_cycle_start ();
+    pframes_t samples_since_cycle_start ();
+
+    size_t raw_buffer_size (DataType t);
+
+    int create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize);
+
+    void transport_start ();
+    void transport_stop ();
+    void transport_locate (framepos_t /*pos*/);
+    TransportState transport_state () const;
+    framepos_t transport_frame() const;
+
+    int set_time_master (bool /*yn*/);
+    bool get_sync_offset (pframes_t& /*offset*/) const;
+
   private:
-    JackConnection* _jack_connection;
+    JackConnection* _jack_connection; //< shared with JACKPortEngine
+    bool            _running;
+    bool            _freewheeling;
+    std::map<DataType,size_t> _raw_buffer_sizes;
 
     static int  _xrun_callback (void *arg);
-    static int  _graph_order_callback (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);
     static void _jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int, void*);
     static int  _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
     static void _freewheel_callback (int , void *arg);
-    static void _registration_callback (jack_port_id_t, int, void *);
-    static void _connect_callback (jack_port_id_t, jack_port_id_t, int, void *);
     static void _latency_callback (jack_latency_callback_mode_t, void*);
 #ifdef HAVE_JACK_SESSION
     static void _session_callback (jack_session_event_t *event, void *arg);
@@ -99,12 +120,12 @@ class JACKAudioBackend : public AudioBackend {
     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);
     int  process_callback (pframes_t nframes);
     void jack_latency_callback (jack_latency_callback_mode_t);
-    
+    void disconnected (const char*);
+
     void set_jack_callbacks ();
-    int connect_to_jack (std::string client_name, std::string session_uuid);
+    int reconnect_to_jack ();
     
     struct ThreadData {
        JACKAudioBackend* engine;
@@ -136,6 +157,8 @@ class JACKAudioBackend : public AudioBackend {
     uint32_t _current_sample_rate;
     uint32_t _current_buffer_size;
     uint32_t _current_usecs_per_cycle;
+    uint32_t _current_systemic_input_latency;
+    uint32_t _current_systemic_output_latency;
     
 };
 
index 2456adc27204e93f153ac73e3aa6242666d02eb0..60aa52fb6baa0a8295974d9515ad2954f01709d0 100644 (file)
 #ifndef __libardour_jack_portengine_h__
 #define __libardour_jack_portengine_h__
 
+#include <string>
+#include <vector>
+
+#include <stdint.h>
+
+#include "ardour/port_engine.h"
+#include "ardour/types.h"
+
 namespace ARDOUR {
 
+class JackConnection;
+
 class JACKPortEngine : public PortEngine 
 {
   public:
-    JACKPortEngine (const std::string& client_name,
-                   const std::string& session_uuid);
+    JACKPortEngine (void* arg); // argument is a JackConnection
+
+    bool  connected() const;
+    void* private_handle() const;
+
+    int         set_port_name (PortHandle, const std::string&);
+    std::string get_port_name (PortHandle) const;
+    PortHandle* get_port_by_name (const std::string&) const;
+
+    std::string make_port_name_relative (const std::string& name) const;
+    std::string make_port_name_non_relative (const std::string& name) const;
+    bool        port_is_mine (const std::string& fullname) const;
+
+    PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
+    void  unregister_port (PortHandle);
+
+    bool  connected (PortHandle);
+    bool  connected_to (PortHandle, const std::string&);
+    bool  physically_connected (PortHandle);
+
+    int   get_connections (PortHandle, std::vector<std::string>&);
+
+    int   connect (PortHandle, const std::string&);
+    int   disconnect (PortHandle, const std::string&);
+    int   disconnect_all (PortHandle);
+
+    int   connect (const std::string& src, const std::string& dst);
+    int   disconnect (const std::string& src, const std::string& dst);
+    
+    /* MIDI */
+
+    void     midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index);
+    int      midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size);
+    uint32_t get_midi_event_count (void* port_buffer);
+    void     midi_clear (void* port_buffer);
+
+    /* Monitoring */
+
+    bool  can_monitor_input() const;
+    int   request_input_monitoring (PortHandle, bool);
+    int   ensure_input_monitoring (PortHandle, bool);
+    bool  monitoring_input (PortHandle);
+
+    /* Latency management
+     */
+    
+    void          set_latency_range (PortHandle, bool for_playback, LatencyRange);
+    LatencyRange  get_latency_range (PortHandle, bool for_playback);
+    LatencyRange  get_connected_latency_range (PortHandle, int dir);
+
+    void* get_buffer (PortHandle, pframes_t);
+
+    pframes_t last_frame_time () const;
+
+  private:
+    JackConnection* _jack_connection;
+
+    static int  _graph_order_callback (void *arg);
+    static void _registration_callback (jack_port_id_t, int, void *);
+    static void _connect_callback (jack_port_id_t, jack_port_id_t, int, void *);
+
+    void connect_callback (jack_port_id_t, jack_port_id_t, int);
+
 };
 
 } // namespace 
index 0e9a84ea8cc32a6f9c52cfd6d9bfdefd2ad28349..29a566aa2d075928b1c1597eb63c92d36424deda 100644 (file)
@@ -55,10 +55,12 @@ class PortManager
     
     /* Port connectivity */
     
-    int connect (const std::string& source, const std::string& destination);
-    int disconnect (const std::string& source, const std::string& destination);
-    int disconnect (boost::shared_ptr<Port>);
+    int  connect (const std::string& source, const std::string& destination);
+    int  disconnect (const std::string& source, const std::string& destination);
+    int  disconnect (boost::shared_ptr<Port>);
     bool connected (const std::string&);
+    int  reestablish_ports ();
+    int  reconnect_ports ();
 
     /* other Port management */
     
index a782680082ac5f800807d5dfe630eac392fb7f84..4c005ffa7438bef6244fda3ed67fab9120ca47ca 100644 (file)
@@ -1426,8 +1426,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
         */
        std::list<GQuark> _current_trans_quarks;
 
-       void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
-       int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
+        // void timebase_callback (TransportState, pframes_t, jack_position_t*, int);
+        int  jack_sync_callback (TransportState, framepos_t);
        void reset_jack_connection (jack_client_t* jack);
        void process_rtop (SessionEvent*);
 
index 1e43c590a0fb8c3d7cac829607c8acf25bf2d48c..1f26e12a3bf52e34d50da199e45ed7c8a59344a8 100644 (file)
@@ -165,6 +165,33 @@ AudioEngine::split_cycle (pframes_t offset)
        }
 }
 
+int
+AudioEngine::sample_rate_change (pframes_t nframes)
+{
+       /* check for monitor input change every 1/10th of second */
+
+       monitor_check_interval = nframes / 10;
+       last_monitor_check = 0;
+
+       if (_session) {
+               _session->set_frame_rate (nframes);
+       }
+
+       SampleRateChanged (nframes); /* EMIT SIGNAL */
+
+       return 0;
+}
+
+int 
+AudioEngine::buffer_size_change (pframes_t bufsiz)
+{
+       if (_session) {
+               _session->set_block_size (bufsiz);
+               last_monitor_check = 0;
+       }
+
+       return 0;
+}
 
 /** Method called by our ::process_thread when there is work to be done.
  *  @param nframes Number of frames to process.
@@ -399,7 +426,7 @@ AudioEngine::set_session (Session *s)
 
                start_metering_thread ();
 
-               pframes_t blocksize = _backend->get_buffer_size ();
+               pframes_t blocksize = _backend->buffer_size ();
 
                /* page in as much of the session process code as we
                   can before we really start running.
@@ -558,6 +585,12 @@ AudioEngine::start ()
                if (_backend->start() == 0) {
                        _running = true;
                        _has_run = true;
+                       last_monitor_check = 0;
+
+                       if (_session && _session->config.get_jack_time_master()) {
+                               _backend->set_time_master (true);
+                       }
+
                        Running(); /* EMIT SIGNAL */
                } else {
                        /* should report error? */
@@ -573,8 +606,19 @@ AudioEngine::stop ()
        if (!_backend) {
                return 0;
        }
-       
-       return _backend->stop ();
+
+       Glib::Threads::Mutex::Lock lm (_process_lock);
+
+       if (_backend->stop () == 0) {
+               _running = false;
+               stop_metering_thread ();
+
+               Stopped (); /* EMIT SIGNAL */
+
+               return 0;
+       }
+
+       return -1;
 }
 
 int
@@ -584,7 +628,13 @@ AudioEngine::pause ()
                return 0;
        }
        
-       return _backend->pause ();
+       if (_backend->pause () == 0) {
+               _running = false;
+               Stopped(); /* EMIT SIGNAL */
+               return 0;
+       }
+
+       return -1;
 }
 
 int
@@ -605,7 +655,17 @@ AudioEngine::get_cpu_load() const
        if (!_backend) {
                return 0.0;
        }
-       return _backend->get_cpu_load ();
+       return _backend->cpu_load ();
+}
+
+bool
+AudioEngine::is_realtime() const 
+{
+       if (!_backend) {
+               return false;
+       }
+
+       return _backend->is_realtime();
 }
 
 void
@@ -668,7 +728,7 @@ AudioEngine::samples_per_cycle () const
        if (!_backend) {
                return 0;
        }
-       return _backend->samples_per_cycle ();
+       return _backend->buffer_size ();
 }
 
 int
@@ -677,7 +737,7 @@ AudioEngine::usecs_per_cycle () const
        if (!_backend) {
                return -1;
        }
-       return _backend->start ();
+       return _backend->usecs_per_cycle ();
 }
 
 size_t
@@ -734,3 +794,73 @@ AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr
        return _backend->create_process_thread (func, thr, stacksize);
 }
 
+
+void
+AudioEngine::thread_init_callback (void* arg)
+{
+       /* make sure that anybody who needs to know about this thread
+          knows about it.
+       */
+
+       pthread_set_name (X_("audioengine"));
+
+       PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
+       PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
+
+       SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
+
+       MIDI::JackMIDIPort::set_process_thread (pthread_self());
+
+       if (arg) {
+               AudioEngine* ae = static_cast<AudioEngine*> (arg);
+               /* the special thread created/managed by the backend */
+               ae->_main_thread = new ProcessThread;
+       }
+}
+
+/* XXXX
+void
+AudioEngine::timebase_callback (TransportState state, pframes_t nframes, jack_position_t pos, int new_position)
+{
+       if (_session && _session->synced_to_jack()) {
+               // _session->timebase_callback (state, nframes, pos, new_position);
+       }
+}
+*/
+
+int
+AudioEngine::sync_callback (TransportState state, framepos_t position)
+{
+       if (_session) {
+               return _session->jack_sync_callback (state, position);
+       }
+       return 0;
+}
+
+void
+AudioEngine::freewheel_callback (bool onoff)
+{
+       if (onoff) {
+               _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
+               MIDI::Manager::instance()->mmc()->enable_send (false);
+       } else {
+               MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
+       }
+}
+
+void
+AudioEngine::latency_callback (bool for_playback)
+{
+        if (_session) {
+                _session->update_latency (for_playback);
+        }
+}
+
+void
+AudioEngine::halted_callback (const char* why)
+{
+        stop_metering_thread ();
+       
+       MIDI::JackMIDIPort::EngineHalted (); /* EMIT SIGNAL */
+       Halted (why); /* EMIT SIGNAL */
+}
index bc2a1b9e3bb5c59d0e975de4cb33914f5b62a829..7575e8387e4dc592842e8b5cc2289fcc52b5ec1b 100644 (file)
 #include <math.h>
 
 #include <boost/scoped_ptr.hpp>
+#include <glibmm/timer.h>
+
+#include "pbd/error.h"
+
+#include "midi++/manager.h"
 
 #include "ardour/audioengine.h"
 #include "ardour/types.h"
 #include "ardour/jack_connection.h"
 #include "ardour/jack_portengine.h"
 
+#include "i18n.h"
+
 using namespace ARDOUR;
+using namespace PBD;
 using std::string;
+using std::vector;
 
-#define GET_PRIVATE_JACK_POINTER(localvar)  jack_client_t* localvar = _jack_connection->jack(); if (!(v)) { return; }
-#define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(v)) { return r; }
-
-extern "C" {
-
-
-       /* functions looked up using dlopen-and-cousins, and so naming scope
-        * must be non-mangled.
-        */
-
-       AudioBackend* backend_factory (AudioEngine& ae, void* backend_data)
-       {
-               JACKAudioBackend* ab = new JACKAudioBackend (ae, backend_data);
-               return ab;
-       }
-
-       PortEngine* portengine_factory (PortEngine& ae, void* backend_data)
-       {
-               JACKPortEngine* pe = new JACKPortEngine (ae, backend_data);
-               return pe;
-       }
-
-       int
-       instantiate (const std::string& arg1, const std::string& arg2, void** backend_data)
-       {
-               JackConnection *jc;
-               try {
-                       jc = new JackConnection (arg1, arg2);
-               } catch {
-                       return -1;
-               }
-               
-               *backend_data = (void*) jc;
-               return 0;
-       }
-       
-       int 
-       deinstantiate (void* backend_data)
-       {
-               JackConnection* jc = static_cast<JackConnection*> (backend_data);
-               delete jc;
-       }
-}
+#define GET_PRIVATE_JACK_POINTER(localvar)  jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
+#define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
 
 JACKAudioBackend::JACKAudioBackend (AudioEngine& e, void* jc)
        : AudioBackend (e)
-       , _jack_connection (jc)
+       , _jack_connection (static_cast<JackConnection*>(jc))
+       , _running (false)
+       , _freewheeling (false)
        , _target_sample_rate (48000)
        , _target_buffer_size (1024)
-       , _target_sample_format (FloatingPoint)
+       , _target_sample_format (FormatFloat)
        , _target_interleaved (false)
        , _target_input_channels (-1)
        , _target_output_channels (-1)
@@ -95,9 +65,9 @@ JACKAudioBackend::name() const
 }
 
 void*
-JACKAudioBackend::private_handle()
+JACKAudioBackend::private_handle() const
 {
-       return _jack_connection->jack()
+       return _jack_connection->jack();
 }
 
 bool
@@ -107,7 +77,7 @@ JACKAudioBackend::connected() const
 }
 
 bool
-JACKAudioBackend::is_realtime ()
+JACKAudioBackend::is_realtime () const
 {
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack,false);
        return jack_is_realtime (_priv_jack);
@@ -125,8 +95,8 @@ JACKAudioBackend::available_sample_rates (const string& /*device*/) const
 {
        vector<float> f;
        
-       if (_jack) {
-               f.push_back (get_sample_rate());
+       if (connected()) {
+               f.push_back (sample_rate());
                return f;
        }
 
@@ -153,8 +123,8 @@ JACKAudioBackend::available_buffer_sizes (const string& /*device*/) const
 {
        vector<uint32_t> s;
        
-       if (_jack) {
-               s.push_back (get_buffer_size());
+       if (connected()) {
+               s.push_back (buffer_size());
                return s;
        }
 
@@ -174,13 +144,13 @@ JACKAudioBackend::available_buffer_sizes (const string& /*device*/) const
 }
 
 uint32_t
-JACKAudioBackend::available_input_channel_count (const string& /*device*/)
+JACKAudioBackend::available_input_channel_count (const string& /*device*/) const
 {
        return 128;
 }
 
 uint32_t
-JACKAudioBackend::available_output_channel_count (const string& /*device*/)
+JACKAudioBackend::available_output_channel_count (const string& /*device*/) const
 {
        return 128;
 }
@@ -190,7 +160,7 @@ JACKAudioBackend::available_output_channel_count (const string& /*device*/)
 int
 JACKAudioBackend::set_device_name (const string& dev)
 {
-       if (_jack) {
+       if (connected()) {
                /* need to stop and restart JACK for this to work, at present */
                return -1;
        }
@@ -203,12 +173,17 @@ int
 JACKAudioBackend::set_sample_rate (float sr)
 {
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+       
+       if (!connected()) {
+               _target_sample_rate = sr;
+               return 0;
+       }
 
        if (sr == jack_get_sample_rate (_priv_jack)) {
                 return 0;
        }
 
-       return jack_set_sample_rate (_priv_jack, lrintf (sr));
+       return -1;
 }
 
 int
@@ -216,6 +191,11 @@ JACKAudioBackend::set_buffer_size (uint32_t nframes)
 {
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
 
+       if (!connected()) {
+               _target_buffer_size = nframes;
+               return 0;
+       }
+
        if (nframes == jack_get_buffer_size (_priv_jack)) {
                 return 0;
        }
@@ -229,7 +209,7 @@ JACKAudioBackend::set_sample_format (SampleFormat sf)
        /* as far as JACK clients are concerned, the hardware is always
         * floating point format.
         */
-       if (sf == FloatingPoint) {
+       if (sf == FormatFloat) {
                return 0;
        }
        return -1;
@@ -250,167 +230,179 @@ JACKAudioBackend::set_interleaved (bool yn)
 int
 JACKAudioBackend::set_input_channels (uint32_t cnt)
 {
-       if (_jack) {
+       if (connected()) {
                return -1;
        }
 
        _target_input_channels = cnt;
+       
+       return 0;
 }
 
 int
 JACKAudioBackend::set_output_channels (uint32_t cnt)
 {
-       if (_jack) {
+       if (connected()) {
                return -1;
        }
 
        _target_output_channels = cnt;
+
+       return 0;
 }
 
 int
 JACKAudioBackend::set_systemic_input_latency (uint32_t l)
 {
-       if (_jack) {
+       if (connected()) {
                return -1;
        }
 
        _target_systemic_input_latency = l;
+
+       return 0;
 }
 
 int
 JACKAudioBackend::set_systemic_output_latency (uint32_t l)
 {
-       if (_jack) {
+       if (connected()) {
                return -1;
        }
 
        _target_systemic_output_latency = l;
+
+       return 0;
 }
 
 /* --- Parameter retrieval --- */
 
 std::string
-JACKAudioBackend::get_device_name () const
+JACKAudioBackend::device_name () const
 {
+       return string();
 }
 
 float
-JACKAudioBackend::get_sample_rate () const
+JACKAudioBackend::sample_rate () const
 {
-       if (_jack) {
+       if (connected()) {
                return _current_sample_rate;
        }
        return _target_sample_rate;
 }
 
 uint32_t
-JACKAudioBackend::get_buffer_size () const
+JACKAudioBackend::buffer_size () const
 {
-       if (_jack) {
+       if (connected()) {
                return _current_buffer_size;
        }
        return _target_buffer_size;
 }
 
 SampleFormat
-JACKAudioBackend::get_sample_format () const
+JACKAudioBackend::sample_format () const
 {
-       return FloatingPoint;
+       return FormatFloat;
 }
 
 bool
-JACKAudioBackend::get_interleaved () const
+JACKAudioBackend::interleaved () const
 {
        return false;
 }
 
 uint32_t
-JACKAudioBackend::get_input_channels () const
+JACKAudioBackend::input_channels () const
 {
-       if (_jack) {
-               return n_physical (JackPortIsInput);
+       if (connected()) {
+               return n_physical (JackPortIsInput).n_audio();
        } 
        return _target_input_channels;
 }
 
 uint32_t
-JACKAudioBackend::get_output_channels () const
+JACKAudioBackend::output_channels () const
 {
-       if (_jack) {
-               return n_physical (JackPortIsOutput);
+       if (connected()) {
+               return n_physical (JackPortIsOutput).n_audio();
        } 
        return _target_output_channels;
 }
 
 uint32_t
-JACKAudioBackend::get_systemic_input_latency () const
+JACKAudioBackend::systemic_input_latency () const
 {
        return _current_systemic_output_latency;
 }
 
 uint32_t
-JACKAudioBackend::get_systemic_output_latency () const
+JACKAudioBackend::systemic_output_latency () const
 {
        return _current_systemic_output_latency;
 }
 
+size_t 
+JACKAudioBackend::raw_buffer_size(DataType t)
+{
+       std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
+       return (s != _raw_buffer_sizes.end()) ? s->second : 0;
+}
+
 /* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */
 
 int
 JACKAudioBackend::start ()
 {
-       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
-
-       if (!_running) {
-
-                if (!jack_port_type_get_buffer_size) {
-                        warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
-               }
-
-               if (_session) {
-                       BootMessage (_("Connect session to engine"));
-                       _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
-               }
-
-                /* a proxy for whether jack_activate() will definitely call the buffer size
-                 * callback. with older versions of JACK, this function symbol will be null.
-                 * this is reliable, but not clean.
-                 */
-
-                if (!jack_port_type_get_buffer_size) {
-                       jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
-                }
-               
-               _processed_frames = 0;
-               last_monitor_check = 0;
+       if (!connected()) {
+               _jack_connection->open ();
+       }
 
-                set_jack_callbacks ();
+       engine.reestablish_ports ();
+       
+       if (!jack_port_type_get_buffer_size) {
+               warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
+       }
+       
+       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
 
-               if (jack_activate (_priv_jack) == 0) {
-                       _running = true;
-                       _has_run = true;
-                       Running(); /* EMIT SIGNAL */
-               } else {
-                       // error << _("cannot activate JACK client") << endmsg;
-               }
+       engine.sample_rate_change (jack_get_sample_rate (_priv_jack));
+       
+       /* testing the nullity of this function name is a proxy for
+        * whether jack_activate() will definitely call the buffer size
+        * callback. with older versions of JACK, this function symbol
+        * will be null.  this is sort of reliable, but not clean since
+        * weak symbol support is highly platform and compiler
+        * specific.
+        */
+       if (!jack_port_type_get_buffer_size) {
+               jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
        }
-               
-       return _running ? 0 : -1;
+       
+       set_jack_callbacks ();
+       
+       if (jack_activate (_priv_jack) == 0) {
+               _running = true;
+       } else {
+               // error << _("cannot activate JACK client") << endmsg;
+       }
+       
+       engine.reconnect_ports ();
+
+       return 0;
 }
 
 int
 JACKAudioBackend::stop ()
 {
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+       
+       _jack_connection->close ();
 
-       {
-               Glib::Threads::Mutex::Lock lm (_process_lock);
-               jack_client_close (_priv_jack);
-               _jack = 0;
-       }
+       _current_buffer_size = 0;
+       _current_sample_rate = 0;
 
-       _buffer_size = 0;
-       _frame_rate = 0;
        _raw_buffer_sizes.clear();
 
        return 0;
@@ -439,121 +431,12 @@ JACKAudioBackend::freewheel (bool onoff)
                return 0;
        }
 
-       return jack_set_freewheel (_priv_jack, onoff);
-}
-
-int
-JACKAudioBackend::set_parameters (const Parameters& params)
-{
-       return 0;
-}
-
-int 
-JACKAudioBackend::get_parameters (Parameters& params) const
-{
-       return 0;
-}
-
-/* parameters */
-
-ARDOUR::pframes_t
-AudioEngine::frames_per_cycle () const
-{
-       GET_PRIVATE_JACK_POINTER_RET (_priv_jack,0);
-
-       if (_buffer_size == 0) {
-               return jack_get_buffer_size (_priv_jack);
-       } else {
-               return _buffer_size;
-       }
-}
-
-ARDOUR::framecnt_t
-AudioEngine::frame_rate () const
-{
-       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
-       if (_frame_rate == 0) {
-               return (_frame_rate = jack_get_sample_rate (_priv_jack));
-       } else {
-               return _frame_rate;
-       }
-}
-
-size_t
-AudioEngine::raw_buffer_size (DataType t)
-{
-       std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
-       return (s != _raw_buffer_sizes.end()) ? s->second : 0;
-}
-
-
-
-/*--- private support methods ---*/
-
-int
-JACKAudioBackend::reconnect_to_jack ()
-{
-       if (_jack_connection->connected()) {
-               _jack_connection->close ();
-               /* XXX give jackd a chance */
-               Glib::usleep (250000);
-       }
-
-       if (_jack_connection->open()) {
-               error << _("failed to connect to JACK") << endmsg;
-               return -1;
-       }
-
-       Ports::iterator i;
-
-       boost::shared_ptr<Ports> p = ports.reader ();
-
-       for (i = p->begin(); i != p->end(); ++i) {
-               if (i->second->reestablish ()) {
-                       break;
-               }
-       }
-
-       if (i != p->end()) {
-               /* failed */
-               remove_all_ports ();
-               return -1;
-       }
-
-       GET_PRIVATE_JACK_POINTER_RET (_priv_jack,-1);
-
-       MIDI::Manager::instance()->reestablish (_priv_jack);
-
-       if (_session) {
-               _session->reset_jack_connection (_priv_jack);
-                jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
-               _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
-       }
-
-       last_monitor_check = 0;
-
-        set_jack_callbacks ();
-
-       if (jack_activate (_priv_jack) == 0) {
-               _running = true;
-               _has_run = true;
-       } else {
-               return -1;
-       }
-
-       /* re-establish connections */
-
-       for (i = p->begin(); i != p->end(); ++i) {
-               i->second->reconnect ();
+       if (jack_set_freewheel (_priv_jack, onoff) == 0) {
+               _freewheeling = true;
+               return 0;
        }
 
-       MIDI::Manager::instance()->reconnect ();
-
-       Running (); /* EMIT SIGNAL*/
-
-       start_metering_thread ();
-
-       return 0;
+       return -1;
 }
 
 /* --- TRANSPORT STATE MANAGEMENT --- */
@@ -586,8 +469,8 @@ JACKAudioBackend::transport_frame () const
        return jack_get_current_transport_frame (_priv_jack);
 }
 
-JACKAudioBackend::TransportState
-JACKAudioBackend::transport_state ()
+TransportState
+JACKAudioBackend::transport_state () const
 {
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, ((TransportState) JackTransportStopped));
        jack_position_t pos;
@@ -601,29 +484,12 @@ JACKAudioBackend::set_time_master (bool yn)
        if (yn) {
                return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
        } else {
-               return jack_release_timebase (_jack);
+               return jack_release_timebase (_priv_jack);
        }
 }
 
 /* process-time */
 
-framecnt_t 
-JACKAudioBackend::sample_rate () const
-{
-
-}
-pframes_t 
-JACKAudioBackend::samples_per_cycle () const
-{
-}
-
-size_t 
-JACKAudioBackend::raw_buffer_size(DataType t)
-{
-       std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
-       return (s != _raw_buffer_sizes.end()) ? s->second : 0;
-}
-
 bool
 JACKAudioBackend::get_sync_offset (pframes_t& offset) const
 {
@@ -651,33 +517,24 @@ JACKAudioBackend::get_sync_offset (pframes_t& offset) const
 }
 
 pframes_t
-JACKAudioBackend::frames_since_cycle_start ()
+JACKAudioBackend::sample_time ()
 {
-       jack_client_t* _priv_jack = _jack;
-       if (!_running || !_priv_jack) {
-               return 0;
-       }
-       return jack_frames_since_cycle_start (_priv_jack);
+       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+       return jack_frame_time (_priv_jack);
 }
 
 pframes_t
-JACKAudioBackend::frame_time ()
+JACKAudioBackend::sample_time_at_cycle_start ()
 {
-       jack_client_t* _priv_jack = _jack;
-       if (!_running || !_priv_jack) {
-               return 0;
-       }
-       return jack_frame_time (_priv_jack);
+       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+       return jack_last_frame_time (_priv_jack);
 }
 
 pframes_t
-JACKAudioBackend::frame_time_at_cycle_start ()
+JACKAudioBackend::samples_since_cycle_start ()
 {
-       jack_client_t* _priv_jack = _jack;
-       if (!_running || !_priv_jack) {
-               return 0;
-       }
-       return jack_last_frame_time (_priv_jack);
+       GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+       return jack_frames_since_cycle_start (_priv_jack);
 }
 
 /* JACK Callbacks */
@@ -693,21 +550,15 @@ JACKAudioBackend::set_jack_callbacks ()
 {
        GET_PRIVATE_JACK_POINTER (_priv_jack);
 
-        jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
+        jack_set_thread_init_callback (_priv_jack, AudioEngine::thread_init_callback, 0);
+
         jack_set_process_thread (_priv_jack, _process_thread, this);
         jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
         jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
-        jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
-        jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
-        jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
         jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
         jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
         jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
 
-        if (_session && _session->config.get_jack_time_master()) {
-                jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
-        }
-
 #ifdef HAVE_JACK_SESSION
         if( jack_set_session_callback)
                 jack_set_session_callback (_priv_jack, _session_callback, this);
@@ -724,40 +575,75 @@ void
 JACKAudioBackend::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
                                      jack_position_t* pos, int new_position, void *arg)
 {
-       static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
+       static_cast<JACKAudioBackend*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
 }
 
 void
-JACKAudioBackend::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
-                                    jack_position_t* pos, int new_position)
+JACKAudioBackend::jack_timebase_callback (jack_transport_state_t state, pframes_t /*nframes*/,
+                                         jack_position_t* pos, int /*new_position*/)
 {
-       if (_jack && _session && _session->synced_to_jack()) {
-               _session->jack_timebase_callback (state, nframes, pos, new_position);
+       TransportState tstate;
+       framepos_t position;
+
+       switch (state) {
+       case JackTransportStopped:
+               tstate = TransportStopped;
+               break;
+       case JackTransportRolling:
+               tstate = TransportRolling;
+               break;
+       case JackTransportLooping:
+               tstate = TransportLooping;
+               break;
+       case JackTransportStarting:
+               tstate = TransportStarting;
+               break;
+       }
+
+       if (pos) {
+               position = pos->frame;
        }
+
+       // engine.timebase_callback (tstate, nframes, position, new_position);
 }
 
 int
 JACKAudioBackend::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
 {
-       return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
+       return static_cast<JACKAudioBackend*> (arg)->jack_sync_callback (state, pos);
 }
 
 int
 JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
 {
-       if (_jack && _session) {
-               return _session->jack_sync_callback (state, pos);
+       TransportState tstate;
+
+       switch (state) {
+       case JackTransportStopped:
+               tstate = TransportStopped;
+               break;
+       case JackTransportRolling:
+               tstate = TransportRolling;
+               break;
+       case JackTransportLooping:
+               tstate = TransportLooping;
+               break;
+       case JackTransportStarting:
+               tstate = TransportStarting;
+               break;
        }
 
+       return engine.sync_callback (tstate, pos->frame);
+
        return true;
 }
 
 int
 JACKAudioBackend::_xrun_callback (void *arg)
 {
-       AudioEngine* ae = static_cast<AudioEngine*> (arg);
+       JACKAudioBackend* ae = static_cast<JACKAudioBackend*> (arg);
        if (ae->connected()) {
-               ae->Xrun (); /* EMIT SIGNAL */
+               ae->engine.Xrun (); /* EMIT SIGNAL */
        }
        return 0;
 }
@@ -766,99 +652,30 @@ JACKAudioBackend::_xrun_callback (void *arg)
 void
 JACKAudioBackend::_session_callback (jack_session_event_t *event, void *arg)
 {
-       AudioEngine* ae = static_cast<AudioEngine*> (arg);
+       JACKAudioBackend* ae = static_cast<JACKAudioBackend*> (arg);
        if (ae->connected()) {
-               ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
+               ae->engine.JackSessionEvent (event); /* EMIT SIGNAL */
        }
 }
 #endif
 
-int
-JACKAudioBackend::_graph_order_callback (void *arg)
-{
-       AudioEngine* ae = static_cast<AudioEngine*> (arg);
-
-       if (ae->connected() && !ae->port_remove_in_progress) {
-               ae->GraphReordered (); /* EMIT SIGNAL */
-       }
-       
-       return 0;
-}
-
 void
 JACKAudioBackend::_freewheel_callback (int onoff, void *arg)
 {
-       static_cast<AudioEngine*>(arg)->freewheel_callback (onoff);
+       static_cast<JACKAudioBackend*>(arg)->freewheel_callback (onoff);
 }
 
 void
 JACKAudioBackend::freewheel_callback (int onoff)
 {
        _freewheeling = onoff;
-
-       if (onoff) {
-               _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
-               MIDI::Manager::instance()->mmc()->enable_send (false);
-       } else {
-               MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
-       }
-}
-
-void
-JACKAudioBackend::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
-{
-       AudioEngine* ae = static_cast<AudioEngine*> (arg);
-
-       if (!ae->port_remove_in_progress) {
-               ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
-       }
+       engine.freewheel_callback (onoff);
 }
 
 void
 JACKAudioBackend::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
 {
-       return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
-}
-
-void
-JACKAudioBackend::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
-{
-       AudioEngine* ae = static_cast<AudioEngine*> (arg);
-       ae->connect_callback (id_a, id_b, conn);
-}
-
-void
-JACKAudioBackend::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
-{
-       if (port_remove_in_progress) {
-               return;
-       }
-
-       GET_PRIVATE_JACK_POINTER (_priv_jack);
-
-       jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
-       jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
-
-       boost::shared_ptr<Port> port_a;
-       boost::shared_ptr<Port> port_b;
-       Ports::iterator x;
-       boost::shared_ptr<Ports> pr = ports.reader ();
-
-       x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
-       if (x != pr->end()) {
-               port_a = x->second;
-       }
-
-       x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
-       if (x != pr->end()) {
-               port_b = x->second;
-       }
-
-       PortConnectedOrDisconnected (
-               port_a, jack_port_name (jack_port_a),
-               port_b, jack_port_name (jack_port_b),
-               conn == 0 ? false : true
-               ); /* EMIT SIGNAL */
+       return static_cast<JACKAudioBackend*> (arg)->jack_latency_callback (mode);
 }
 
 int
@@ -890,7 +707,7 @@ JACKAudioBackend::_start_process_thread (void* arg)
 void*
 JACKAudioBackend::_process_thread (void *arg)
 {
-       return static_cast<AudioEngine *> (arg)->process_thread ();
+       return static_cast<JACKAudioBackend*> (arg)->process_thread ();
 }
 
 void*
@@ -899,9 +716,7 @@ JACKAudioBackend::process_thread ()
         /* JACK doesn't do this for us when we use the wait API
          */
 
-        _thread_init_callback (0);
-
-        _main_thread = new ProcessThread;
+        AudioEngine::thread_init_callback (this);
 
         while (1) {
                 GET_PRIVATE_JACK_POINTER_RET(_priv_jack,0);
@@ -921,41 +736,26 @@ JACKAudioBackend::process_thread ()
 int
 JACKAudioBackend::_sample_rate_callback (pframes_t nframes, void *arg)
 {
-       return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
+       return static_cast<JACKAudioBackend*> (arg)->jack_sample_rate_callback (nframes);
 }
 
 int
 JACKAudioBackend::jack_sample_rate_callback (pframes_t nframes)
 {
-       _frame_rate = nframes;
-       _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
-
-       /* check for monitor input change every 1/10th of second */
-
-       monitor_check_interval = nframes / 10;
-       last_monitor_check = 0;
-
-       if (_session) {
-               _session->set_frame_rate (nframes);
-       }
-
-       SampleRateChanged (nframes); /* EMIT SIGNAL */
-
-       return 0;
+       _current_sample_rate = nframes;
+       return engine.sample_rate_change (nframes);
 }
 
 void
 JACKAudioBackend::jack_latency_callback (jack_latency_callback_mode_t mode)
 {
-        if (_session) {
-                _session->update_latency (mode == JackPlaybackLatency);
-        }
+       engine.latency_callback (mode == JackPlaybackLatency);
 }
 
 int
 JACKAudioBackend::_bufsize_callback (pframes_t nframes, void *arg)
 {
-       return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
+       return static_cast<JACKAudioBackend*> (arg)->jack_bufsize_callback (nframes);
 }
 
 int
@@ -970,8 +770,7 @@ JACKAudioBackend::jack_bufsize_callback (pframes_t nframes)
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 1);
 
        _current_buffer_size = nframes;
-       _current_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
-       last_monitor_check = 0;
+       _current_usecs_per_cycle = (int) floor ((((double) nframes / sample_rate())) * 1000000.0);
 
         if (jack_port_type_get_buffer_size) {
                 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
@@ -993,66 +792,29 @@ JACKAudioBackend::jack_bufsize_callback (pframes_t nframes)
                 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
         }
 
-       BufferSizeChange (nframes);
-
-       if (_session) {
-               _session->set_block_size (_buffer_size);
-       }
+       engine.buffer_size_change (nframes);
 
        return 0;
 }
 
 void
-JACKAudioBackend::halted_info (jack_status_t code, const char* reason, void *arg)
+JACKAudioBackend::disconnected (const char* why)
 {
         /* called from jack shutdown handler  */
 
-        AudioEngine* ae = static_cast<AudioEngine *> (arg);
-        bool was_running = ae->_running;
+       bool was_running = _running;
 
-        ae->stop_metering_thread ();
-
-        ae->_running = false;
-        ae->_buffer_size = 0;
-        ae->_frame_rate = 0;
-        ae->_jack = 0;
+        _running = false;
+        _current_buffer_size = 0;
+        _current_sample_rate = 0;
 
         if (was_running) {
-               MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
-#ifdef HAVE_JACK_ON_INFO_SHUTDOWN
-                switch (code) {
-                case JackBackendError:
-                        ae->Halted(reason); /* EMIT SIGNAL */
-                        break;
-                default:
-                        ae->Halted(""); /* EMIT SIGNAL */
-                }
-#else
-                ae->Halted(""); /* EMIT SIGNAL */
-#endif
+               engine.halted_callback (why); /* EMIT SIGNAL */
         }
 }
-
-void
-JACKAudioBackend::halted (void *arg)
+float 
+JACKAudioBackend::cpu_load() const 
 {
-        cerr << "HALTED by JACK\n";
-
-        /* called from jack shutdown handler  */
-
-       AudioEngine* ae = static_cast<AudioEngine *> (arg);
-       bool was_running = ae->_running;
-
-       ae->stop_metering_thread ();
-
-       ae->_running = false;
-       ae->_buffer_size = 0;
-       ae->_frame_rate = 0;
-        ae->_jack = 0;
-
-       if (was_running) {
-               MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
-               ae->Halted(""); /* EMIT SIGNAL */
-       }
+       GET_PRIVATE_JACK_POINTER_RET(_priv_jack,0);
+       return jack_cpu_load (_priv_jack);
 }
-
index e0937ea7678031722f9ced807f819db25ac08508..b6ac28b22a961594ad2cab18a5851e9fa4d5205a 100644 (file)
@@ -62,6 +62,8 @@ JackConnection::open ()
         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
        jack_status_t status;
 
+       close ();
+
         /* revert all environment settings back to whatever they were when ardour started
          */
 
index f830785baed05049cb09913856b9de00193f49cb..99b0bd2b9a153b7d7a31802503a8e7c8ea9b1036 100644 (file)
@@ -1,3 +1,74 @@
+JACKPortEngine::init ()
+{
+        jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
+        jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
+        jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
+}
+
+void
+JACKPortEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
+{
+       JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
+
+       if (!pm->port_remove_in_progress) {
+               pm->engine.PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
+       }
+}
+
+void
+JACKPortEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
+{
+       JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
+       pm->connect_callback (id_a, id_b, conn);
+}
+
+void
+JACKPortEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
+{
+       if (port_remove_in_progress) {
+               return;
+       }
+
+       GET_PRIVATE_JACK_POINTER (_priv_jack);
+
+       jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
+       jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
+
+       boost::shared_ptr<Port> port_a;
+       boost::shared_ptr<Port> port_b;
+       Ports::iterator x;
+       boost::shared_ptr<Ports> pr = ports.reader ();
+
+       x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
+       if (x != pr->end()) {
+               port_a = x->second;
+       }
+
+       x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
+       if (x != pr->end()) {
+               port_b = x->second;
+       }
+
+       PortConnectedOrDisconnected (
+               port_a, jack_port_name (jack_port_a),
+               port_b, jack_port_name (jack_port_b),
+               conn == 0 ? false : true
+               ); /* EMIT SIGNAL */
+}
+
+int
+JACKPortEngine::_graph_order_callback (void *arg)
+{
+       JACKPortEngine* pm = static_cast<JACKAudioBackend*> (arg);
+
+       if (pm->connected() && !pm->port_remove_in_progress) {
+               pm->engine.GraphReordered (); /* EMIT SIGNAL */
+       }
+       
+       return 0;
+}
+
+
 JACKPortEngine::physically_connected (PortHandle p)
 {
        jack_port_t* _jack_port = (jack_port_t*) p;
index 5ea76934a5ffe85923ee5be67d6c052aaacb45c5..1f0859bc8d74ffda89b0e0199509da76fc31f43e 100644 (file)
@@ -289,7 +289,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
        _latency_control_port   = 0;
        _next_cycle_start       = std::numeric_limits<framepos_t>::max();
        _next_cycle_speed       = 1.0;
-       _block_length           = _engine.frames_per_cycle();
+       _block_length           = _engine.samples_per_cycle();
        _seq_size               = _engine.raw_buffer_size(DataType::MIDI);
        _state_version          = 0;
        _was_activated          = false;
@@ -1901,7 +1901,7 @@ LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** buf
        return port;
 }
 
-static bool lv2_filter (const string& str, void *arg)
+static bool lv2_filter (const string& str, void* /*arg*/)
 {
        /* Not a dotfile, has a prefix before a period, suffix is "lv2" */
        
index c279cf6d27b5d6e33a90f0c538d2fd08172c918f..1a08849791cbd027cf07b7267cdc67a8873223a6 100644 (file)
@@ -473,3 +473,42 @@ AudioEngine::disconnect (boost::shared_ptr<Port> port)
        return port->disconnect_all ();
 }
 
+int
+PortManager::reestablish_ports ()
+{
+       Ports::iterator i;
+
+       boost::shared_ptr<Ports> p = ports.reader ();
+
+       for (i = p->begin(); i != p->end(); ++i) {
+               if (i->second->reestablish ()) {
+                       break;
+               }
+       }
+
+       if (i != p->end()) {
+               /* failed */
+               remove_all_ports ();
+               return -1;
+       }
+
+       MIDI::Manager::instance()->reestablish ();
+
+       return 0;
+}
+
+int
+PortManager::reconnect_ports ()
+{
+       boost::shared_ptr<Ports> p = ports.reader ();
+
+       /* re-establish connections */
+       
+       for (i = p->begin(); i != p->end(); ++i) {
+               i->second->reconnect ();
+       }
+
+       MIDI::Manager::instance()->reconnect ();
+
+       return 0;
+}
index 18805afa90b6aba1c239dd336d96d36a25a09c26..088712f62539db0b5dda29d9fcfd7dc266432e28 100644 (file)
@@ -180,31 +180,30 @@ Session::timecode_time (Timecode::Time &t)
 }
 
 int
-Session::jack_sync_callback (jack_transport_state_t state,
-                            jack_position_t* pos)
+Session::jack_sync_callback (TransportState state, framepos_t pos)
 {
        bool slave = synced_to_jack();
 
        switch (state) {
-       case JackTransportStopped:
-               if (slave && _transport_frame != pos->frame && post_transport_work() == 0) {
-                       request_locate (pos->frame, false);
+       case TransportStopped:
+               if (slave && _transport_frame != pos && post_transport_work() == 0) {
+                       request_locate (pos, false);
                        // cerr << "SYNC: stopped, locate to " << pos->frame << " from " << _transport_frame << endl;
                        return false;
                } else {
                        return true;
                }
 
-       case JackTransportStarting:
+       case TransportStarting:
                // cerr << "SYNC: starting @ " << pos->frame << " a@ " << _transport_frame << " our work = " <<  post_transport_work() << " pos matches ? " << (_transport_frame == pos->frame) << endl;
                if (slave) {
-                       return _transport_frame == pos->frame && post_transport_work() == 0;
+                       return _transport_frame == pos && post_transport_work() == 0;
                } else {
                        return true;
                }
                break;
 
-       case JackTransportRolling:
+       case TransportRolling:
                // cerr << "SYNC: rolling slave = " << slave << endl;
                if (slave) {
                        start_transport ();
@@ -212,17 +211,21 @@ Session::jack_sync_callback (jack_transport_state_t state,
                break;
 
        default:
-               error << string_compose (_("Unknown JACK transport state %1 in sync callback"), state)
+               error << string_compose (_("Unknown transport state %1 in sync callback"), state)
                      << endmsg;
        }
 
        return true;
 }
 
+/* XXX REQUIRES SOMEWAY TO EFFICIENTLY ACCESS jack_position_t WITHOUT BRIDGING
+ * THE ENTIRE DATA STRUCTURE
+ */
+#if 0 
 void
-Session::jack_timebase_callback (jack_transport_state_t /*state*/,
+Session::jack_timebase_callback (TransportState /*state*/,
                                 pframes_t /*nframes*/,
-                                jack_position_t* pos,
+                                framepos_t pos,
                                 int /*new_position*/)
 {
        Timecode::BBT_Time bbt;
@@ -299,6 +302,7 @@ Session::jack_timebase_callback (jack_transport_state_t /*state*/,
        }
 #endif
 }
+#endif /* jack data structure issues */
 
 ARDOUR::framecnt_t
 Session::convert_to_frames (AnyTime const & position)
index 8eb52436e95c0d0d98b6ca4e02fdcc6c8041038e..a4749d95aab841ee5d40954b85606ec4f38bc8e1 100644 (file)
@@ -435,9 +435,11 @@ def build(bld):
     # the JACK audio backend
 
     obj = bld.shlib (features = 'c cxx cshlib cxxshlib', 
-                     source = [ 'jack_connection.cc',
-                               'jack_audiobackend.cc'
-                               ])
+                     source = [ 
+            'jack_api.cc',
+            'jack_connection.cc',
+            'jack_audiobackend.cc'
+            ])
     obj.cxxflags = [ '-fPIC' ]
     obj.name     = 'jack_audiobackend'
     obj.target   = 'jack_audiobackend'