Some improvements to performance with crossfades: don't recompute a whole track's...
[ardour.git] / libs / ardour / session_transport.cc
index 5b2c351b883db6924065242a3f2689b289e484e2..a20856b818700417c5629d50515531bdf2a9d125 100644 (file)
 #include <sigc++/bind.h>
 #include <sigc++/retype.h>
 
-#include <pbd/undo.h>
-#include <pbd/error.h>
+#include "pbd/undo.h"
+#include "pbd/error.h"
 #include <glibmm/thread.h>
-#include <pbd/pthread_utils.h>
-#include <pbd/memento_command.h>
-#include <pbd/stacktrace.h>
+#include "pbd/pthread_utils.h"
+#include "pbd/memento_command.h"
+#include "pbd/stacktrace.h"
 
-#include <midi++/mmc.h>
-#include <midi++/port.h>
+#include "midi++/mmc.h"
+#include "midi++/port.h"
 
-#include <ardour/ardour.h>
-#include <ardour/audioengine.h>
-#include <ardour/session.h>
-#include <ardour/audio_diskstream.h>
-#include <ardour/auditioner.h>
-#include <ardour/slave.h>
-#include <ardour/location.h>
+#include "ardour/ardour.h"
+#include "ardour/audioengine.h"
+#include "ardour/session.h"
+#include "ardour/audio_diskstream.h"
+#include "ardour/auditioner.h"
+#include "ardour/slave.h"
+#include "ardour/location.h"
 
 #include "i18n.h"
 
@@ -176,15 +176,13 @@ Session::realtime_stop (bool abort)
        reset_slave_state ();
 
        _transport_speed = 0;
-       phi = 0;
-       target_phi = 0;
-       phase = 0;
+       _target_transport_speed = 0;
 
-       if (Config->get_use_video_sync()) {
+       if (config.get_use_video_sync()) {
                waiting_for_sync_offset = true;
        }
 
-       transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
+       transport_sub_state = ((Config->get_slave_source() == None && config.get_auto_return()) ? AutoReturning : 0);
 }
 
 void
@@ -345,7 +343,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
                        /* stopped recording before current end */
 
-                       if (_end_location_is_free) {
+                       if (config.get_end_marker_is_free()) {
 
                                /* first capture for this session, move end back to where we are */
 
@@ -366,7 +364,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                         add_command (new MementoCommand<Location>(*loc, &before, &after));
                }
 
-               _end_location_is_free = false;
+               config.set_end_marker_is_free (false);
                _have_captured = true;
        }
 
@@ -390,7 +388,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                update_latency_compensation (true, abort);
        }
 
-       if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
+       bool const auto_return_enabled =
+               (Config->get_slave_source() == None && config.get_auto_return());
+       
+       if (auto_return_enabled ||
            (post_transport_work & PostTransportLocate) ||
            (_requested_return_frame >= 0) ||
            synced_to_jack()) {
@@ -399,9 +400,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                        flush_all_inserts ();
                }
 
-               if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
-                    synced_to_jack() ||
-                    _requested_return_frame >= 0) &&
+               if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
                    !(post_transport_work & PostTransportLocate)) {
 
                        bool do_locate = false;
@@ -411,8 +410,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
                                _requested_return_frame = -1;
                                do_locate = true;
                        } else {
-                               _transport_frame = last_stop_frame;
-                               _requested_return_frame = -1;
+                               _transport_frame = _last_roll_location;
                        }
 
                        if (synced_to_jack() && !play_loop) {
@@ -444,13 +442,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
        }
 #endif
 
-        if (_requested_return_frame < 0) {
-               last_stop_frame = _transport_frame;
-       } else {
-               last_stop_frame = _requested_return_frame;
-               _requested_return_frame = -1;
-       }
-
         have_looped = false; 
 
         send_full_time_code (0);
@@ -651,7 +642,6 @@ Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush,
                }
 
        } else {
-
                locate (target_frame, with_roll, with_flush, with_loop);
        }
 }
@@ -709,7 +699,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
                }
        }
 
-       if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
+       if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
                realtime_stop (false);
        }
 
@@ -748,7 +738,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
                        for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
-                                       (*i)->monitor_input (!Config->get_auto_input());
+                                       (*i)->monitor_input (!config.get_auto_input());
                                }
                        }
                }
@@ -795,6 +785,8 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
        loop_changing = false;
 
        _send_smpte_update = true;
+
+       Located (); /* EMIT SIGNAL */
 }
 
 /** Set the transport speed.
@@ -808,7 +800,11 @@ Session::set_transport_speed (double speed, bool abort)
                return;
        }
 
-       target_phi = (uint64_t) (0x1000000 * fabs(speed));
+       _target_transport_speed = fabs(speed);
+
+       /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
+          and user needs. We really need CD-style "skip" playback for ffwd and rewind.
+       */
        
        if (speed > 0) {
                speed = min (8.0, speed);
@@ -851,7 +847,7 @@ Session::set_transport_speed (double speed, bool abort)
                        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
 
                        for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
-                               if (Config->get_auto_input() && (*i)->record_enabled ()) {
+                               if (config.get_auto_input() && (*i)->record_enabled ()) {
                                        //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (false);
                                }
@@ -896,7 +892,6 @@ Session::set_transport_speed (double speed, bool abort)
 
                if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
                        post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
-                       last_stop_frame = _transport_frame;
                }
 
                _last_transport_speed = _transport_speed;
@@ -970,7 +965,7 @@ Session::start_transport ()
 
        switch (record_status()) {
        case Enabled:
-               if (!Config->get_punch_in()) {
+               if (!config.get_punch_in()) {
                        enable_record ();
                }
                break;
@@ -988,9 +983,7 @@ Session::start_transport ()
        transport_sub_state |= PendingDeclickIn;
        
        _transport_speed = 1.0;
-       target_phi       = 0x1000000; // speed = 1
-       phi              = target_phi;
-       phase            = 0;
+       _target_transport_speed = 1.0;
 
        boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
        for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
@@ -1023,7 +1016,7 @@ Session::post_transport ()
 
        if (post_transport_work & PostTransportLocate) {
 
-               if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
+               if (((Config->get_slave_source() == None && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
                        start_transport ();
 
                } else {
@@ -1336,11 +1329,12 @@ Session::update_latency_compensation (bool with_stop, bool abort)
                                                        (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
                }
 
-               nframes_t old_latency = (*i)->signal_latency ();
+               nframes_t old_latency = (*i)->output()->signal_latency ();
                nframes_t track_latency = (*i)->update_total_latency ();
 
                if (old_latency != track_latency) {
-                       (*i)->update_port_total_latencies ();
+                       (*i)->input()->update_port_total_latencies ();
+                       (*i)->output()->update_port_total_latencies ();
                        update_jack = true;
                }