split up session code that uses parts of the JACK API (timebase + session event handl...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Aug 2013 16:15:37 +0000 (12:15 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Aug 2013 16:15:37 +0000 (12:15 -0400)
i've made the audiobackend call the session directly so that only one object (ARDOUR::Session) has a need for the JACK types
and only one .cc file (session_jack.cc) needs jack.h. having ARDOUR::AudioEngine act as an intermediary would be cleaner
conceptually but would end up causing two different ARDOUR objects to have jack types in their own API.

gtk2_ardour/ardour_ui_dialogs.cc
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/session.h
libs/ardour/audioengine.cc
libs/ardour/jack_audiobackend.cc
libs/ardour/session_jack.cc [new file with mode: 0644]
libs/ardour/session_state.cc
libs/ardour/session_time.cc
libs/ardour/wscript

index 24f6511b4cdd0f7bd8bba5cfeb91f595b9073730..81c0be223c04cd730a9752643174b3043f8fe50b 100644 (file)
@@ -161,10 +161,6 @@ ARDOUR_UI::set_session (Session *s)
        _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
        _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
 
-#ifdef HAVE_JACK_SESSION
-       engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
-#endif
-
        /* Clocks are on by default after we are connected to a session, so show that here.
        */
 
index 509d330f12364339facdff884a4095e85b5b2635..f05944797d35fefafaf85c823593a83fd05cf249 100644 (file)
@@ -129,7 +129,8 @@ public:
     
     void set_session (Session *);
     void remove_session (); // not a replacement for SessionHandle::session_going_away()
-    
+    Session* session() const { return _session; }
+
     class NoBackendAvailable : public std::exception {
       public:
        virtual const char *what() const throw() { return "could not connect to engine backend"; }
@@ -148,12 +149,7 @@ public:
     PBD::Signal1<int, pframes_t> Freewheel;
     
     PBD::Signal0<void> Xrun;
-    
 
-#ifdef HAVE_JACK_SESSION
-    PBD::Signal1<void,jack_session_event_t *> JackSessionEvent;
-#endif
-    
     /* this signal is emitted if the sample rate changes */
     
     PBD::Signal1<void, framecnt_t> SampleRateChanged;
index c2912208748aeb69f3a41206578d4da9171260dd..31f06589312b96724067e7b1d9ea1152a99141f4 100644 (file)
@@ -381,9 +381,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        framecnt_t worst_track_latency ()  const { return _worst_track_latency; }
        framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; }
 
-#ifdef HAVE_JACK_SESSION
-       void jack_session_event (jack_session_event_t* event);
-#endif
        int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
        int restore_state (std::string snapshot_name);
        int save_template (std::string template_name);
@@ -863,6 +860,15 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
        boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
 
+        /* Callbacks specifically related to JACK, and called directly
+        * from the JACK audio backend.
+         */
+
+#ifdef HAVE_JACK_SESSION
+       void jack_session_event (jack_session_event_t* event);
+#endif
+        void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
+
   protected:
        friend class AudioEngine;
        void set_block_size (pframes_t nframes);
@@ -1436,9 +1442,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
         */
        std::list<GQuark> _current_trans_quarks;
 
-        // 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);
+        int  backend_sync_callback (TransportState, framepos_t);
+
        void process_rtop (SessionEvent*);
 
        void  update_latency (bool playback);
index 45cc33cdc1eb993bebce2d2e4c372383630295f0..2b9a50f1efff581a78761c0303cbe69410a59ff1 100644 (file)
@@ -891,21 +891,11 @@ AudioEngine::thread_init_callback (void* arg)
        }
 }
 
-/* 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 _session->backend_sync_callback (state, position);
        }
        return 0;
 }
index a3bbaecb2dba9550ff0eebd64386ecfb13ec57bc..ece8c4788e2d6be43c016c2de8f84b169071790a 100644 (file)
@@ -28,7 +28,9 @@
 #include "jack/thread.h"
 
 #include "ardour/audioengine.h"
+#include "ardour/session.h"
 #include "ardour/types.h"
+
 #include "ardour/jack_audiobackend.h"
 #include "ardour/jack_connection.h"
 #include "ardour/jack_portengine.h"
@@ -680,32 +682,14 @@ JACKAudioBackend::_jack_timebase_callback (jack_transport_state_t state, pframes
 }
 
 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)
 {
-       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;
-       }
+       ARDOUR::Session* session = engine.session();
 
-       if (pos) {
-               position = pos->frame;
+       if (session) {
+               session->jack_timebase_callback (state, nframes, pos, new_position);
        }
-
-       // engine.timebase_callback (tstate, nframes, position, new_position);
 }
 
 int
@@ -754,8 +738,10 @@ void
 JACKAudioBackend::_session_callback (jack_session_event_t *event, void *arg)
 {
        JACKAudioBackend* ae = static_cast<JACKAudioBackend*> (arg);
-       if (ae->connected()) {
-               ae->engine.JackSessionEvent (event); /* EMIT SIGNAL */
+       ARDOUR::Session* session = ae->engine.session();
+
+       if (session) {
+               session->jack_session_event (event);
        }
 }
 #endif
diff --git a/libs/ardour/session_jack.cc b/libs/ardour/session_jack.cc
new file mode 100644 (file)
index 0000000..af8a93f
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+  Copyright (C) 1999-2013 Paul Davis
+
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  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.
+
+*/
+
+
+#ifdef WAF_BUILD
+#include "libardour-config.h"
+#endif
+
+#include <time.h>
+
+#include <glibmm/miscutils.h>
+
+#include "jack/jack.h"
+#include "jack/session.h"
+
+#include "ardour/audioengine.h"
+#include "ardour/filename_extensions.h"
+#include "ardour/session.h"
+#include "ardour/session_directory.h"
+#include "ardour/tempo.h"
+
+using namespace ARDOUR;
+using std::string;
+
+#ifdef HAVE_JACK_SESSION
+void
+Session::jack_session_event (jack_session_event_t* event)
+{
+        char timebuf[128], *tmp;
+        time_t n;
+        struct tm local_time;
+
+        time (&n);
+        localtime_r (&n, &local_time);
+        strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
+
+        while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
+
+        if (event->type == JackSessionSaveTemplate)
+        {
+                if (save_template( timebuf )) {
+                        event->flags = JackSessionSaveError;
+                } else {
+                        string cmd ("ardour3 -P -U ");
+                        cmd += event->client_uuid;
+                        cmd += " -T ";
+                        cmd += timebuf;
+
+                        event->command_line = strdup (cmd.c_str());
+                }
+        }
+        else
+        {
+                if (save_state (timebuf)) {
+                        event->flags = JackSessionSaveError;
+                } else {
+                       std::string xml_path (_session_dir->root_path());
+                       std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
+                       xml_path = Glib::build_filename (xml_path, legalized_filename);
+
+                        string cmd ("ardour3 -P -U ");
+                        cmd += event->client_uuid;
+                        cmd += " \"";
+                        cmd += xml_path;
+                        cmd += '\"';
+
+                        event->command_line = strdup (cmd.c_str());
+                }
+        }
+
+       /* this won't be called if the port engine in use is not JACK, so we do 
+          not have to worry about the type of PortEngine::private_handle()
+       */
+
+       jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
+       
+       if (jack_client) {
+               jack_session_reply (jack_client, event);
+       }
+
+       if (event->type == JackSessionSaveAndQuit) {
+               Quit (); /* EMIT SIGNAL */
+       }
+
+       jack_session_event_free( event );
+}
+#endif
+
+void
+Session::jack_timebase_callback (jack_transport_state_t /*state*/,
+                                pframes_t /*nframes*/,
+                                jack_position_t* pos,
+                                int /*new_position*/)
+{
+       Timecode::BBT_Time bbt;
+
+       /* BBT info */
+
+       if (_tempo_map) {
+
+               TempoMetric metric (_tempo_map->metric_at (_transport_frame));
+
+               try {
+                       _tempo_map->bbt_time_rt (_transport_frame, bbt);
+
+                       pos->bar = bbt.bars;
+                       pos->beat = bbt.beats;
+                       pos->tick = bbt.ticks;
+                       
+                       // XXX still need to set bar_start_tick
+                       
+                       pos->beats_per_bar = metric.meter().divisions_per_bar();
+                       pos->beat_type = metric.meter().note_divisor();
+                       pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
+                       pos->beats_per_minute = metric.tempo().beats_per_minute();
+                       
+                       pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
+
+               } catch (...) {
+                       /* no message */
+               }
+       }
+
+#ifdef HAVE_JACK_VIDEO_SUPPORT
+       //poke audio video ratio so Ardour can track Video Sync
+       pos->audio_frames_per_video_frame = frame_rate() / timecode_frames_per_second();
+       pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
+#endif
+
+#if 0
+       /* Timecode info */
+
+       pos->timecode_offset = config.get_timecode_offset();
+       t.timecode_frame_rate = timecode_frames_per_second();
+       pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
+
+       if (_transport_speed) {
+
+               if (play_loop) {
+
+                       Location* location = _locations.auto_loop_location();
+
+                       if (location) {
+
+                               t.transport_state = JackTransportLooping;
+                               t.loop_start = location->start();
+                               t.loop_end = location->end();
+                               t.valid = jack_transport_bits_t (t.valid | JackTransportLoop);
+
+                       } else {
+
+                               t.loop_start = 0;
+                               t.loop_end = 0;
+                               t.transport_state = JackTransportRolling;
+
+                       }
+
+               } else {
+
+                       t.loop_start = 0;
+                       t.loop_end = 0;
+                       t.transport_state = JackTransportRolling;
+
+               }
+
+       }
+#endif
+}
+
index c4522f76e7d4608f7b5b9f647613b6abaf2ac606..50905ef434716f3b1ecbee52ce7b31db6211e1f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1999-2002 Paul Davis
+  Copyright (C) 1999-2013 Paul Davis
 
   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
@@ -689,70 +689,6 @@ Session::remove_state (string snapshot_name)
        }
 }
 
-#ifdef HAVE_JACK_SESSION
-void
-Session::jack_session_event (jack_session_event_t * event)
-{
-        char timebuf[128], *tmp;
-        time_t n;
-        struct tm local_time;
-
-        time (&n);
-        localtime_r (&n, &local_time);
-        strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
-
-        while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
-
-        if (event->type == JackSessionSaveTemplate)
-        {
-                if (save_template( timebuf )) {
-                        event->flags = JackSessionSaveError;
-                } else {
-                        string cmd ("ardour3 -P -U ");
-                        cmd += event->client_uuid;
-                        cmd += " -T ";
-                        cmd += timebuf;
-
-                        event->command_line = strdup (cmd.c_str());
-                }
-        }
-        else
-        {
-                if (save_state (timebuf)) {
-                        event->flags = JackSessionSaveError;
-                } else {
-                       std::string xml_path (_session_dir->root_path());
-                       std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
-                       xml_path = Glib::build_filename (xml_path, legalized_filename);
-
-                        string cmd ("ardour3 -P -U ");
-                        cmd += event->client_uuid;
-                        cmd += " \"";
-                        cmd += xml_path;
-                        cmd += '\"';
-
-                        event->command_line = strdup (cmd.c_str());
-                }
-        }
-
-       /* this won't be called if the port engine in use is not JACK, so we do 
-          not have to worry about the type of PortEngine::private_handle()
-       */
-
-       jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
-       
-       if (jack_client) {
-               jack_session_reply (jack_client, event);
-       }
-
-       if (event->type == JackSessionSaveAndQuit) {
-               Quit (); /* EMIT SIGNAL */
-       }
-
-       jack_session_event_free( event );
-}
-#endif
-
 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
 int
 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
index 088712f62539db0b5dda29d9fcfd7dc266432e28..0f2186c09b8eefd5020326976b7a6985501b5987 100644 (file)
@@ -180,7 +180,7 @@ Session::timecode_time (Timecode::Time &t)
 }
 
 int
-Session::jack_sync_callback (TransportState state, framepos_t pos)
+Session::backend_sync_callback (TransportState state, framepos_t pos)
 {
        bool slave = synced_to_jack();
 
@@ -218,91 +218,6 @@ Session::jack_sync_callback (TransportState state, framepos_t pos)
        return true;
 }
 
-/* XXX REQUIRES SOMEWAY TO EFFICIENTLY ACCESS jack_position_t WITHOUT BRIDGING
- * THE ENTIRE DATA STRUCTURE
- */
-#if 0 
-void
-Session::jack_timebase_callback (TransportState /*state*/,
-                                pframes_t /*nframes*/,
-                                framepos_t pos,
-                                int /*new_position*/)
-{
-       Timecode::BBT_Time bbt;
-
-       /* BBT info */
-
-       if (_tempo_map) {
-
-               TempoMetric metric (_tempo_map->metric_at (_transport_frame));
-
-               try {
-                       _tempo_map->bbt_time_rt (_transport_frame, bbt);
-
-                       pos->bar = bbt.bars;
-                       pos->beat = bbt.beats;
-                       pos->tick = bbt.ticks;
-                       
-                       // XXX still need to set bar_start_tick
-                       
-                       pos->beats_per_bar = metric.meter().divisions_per_bar();
-                       pos->beat_type = metric.meter().note_divisor();
-                       pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
-                       pos->beats_per_minute = metric.tempo().beats_per_minute();
-                       
-                       pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
-
-               } catch (...) {
-                       /* no message */
-               }
-       }
-
-#ifdef HAVE_JACK_VIDEO_SUPPORT
-       //poke audio video ratio so Ardour can track Video Sync
-       pos->audio_frames_per_video_frame = frame_rate() / timecode_frames_per_second();
-       pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
-#endif
-
-#if 0
-       /* Timecode info */
-
-       pos->timecode_offset = config.get_timecode_offset();
-       t.timecode_frame_rate = timecode_frames_per_second();
-       pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
-
-       if (_transport_speed) {
-
-               if (play_loop) {
-
-                       Location* location = _locations.auto_loop_location();
-
-                       if (location) {
-
-                               t.transport_state = JackTransportLooping;
-                               t.loop_start = location->start();
-                               t.loop_end = location->end();
-                               t.valid = jack_transport_bits_t (t.valid | JackTransportLoop);
-
-                       } else {
-
-                               t.loop_start = 0;
-                               t.loop_end = 0;
-                               t.transport_state = JackTransportRolling;
-
-                       }
-
-               } else {
-
-                       t.loop_start = 0;
-                       t.loop_end = 0;
-                       t.transport_state = JackTransportRolling;
-
-               }
-
-       }
-#endif
-}
-#endif /* jack data structure issues */
 
 ARDOUR::framecnt_t
 Session::convert_to_frames (AnyTime const & position)
index c140c6eb3aaa2a6641cbc1dd751da06911dd3e6e..57b68a0fdee9e507c4ae1fc9a91f192ae1a1a0b0 100644 (file)
@@ -180,6 +180,7 @@ libardour_sources = [
         'session_events.cc',
         'session_export.cc',
         'session_handle.cc',
+        'session_jack.cc',
         'session_ltc.cc',
         'session_metadata.cc',
         'session_midi.cc',