Add Lua bindings for MIDI-parser and Async ports
[ardour.git] / libs / ardour / session_process.cc
index ca1f3b9b7a7393ac7f1e2d3578e00909346913e7..7acc3a57daf64483a033aa5691b638dbdf668f5f 100644 (file)
@@ -292,18 +292,63 @@ Session::process_with_events (pframes_t nframes)
                process_event (ev);
        }
 
-       /* count in */
+       /* only count-in when going to roll at speed 1.0 */
        if (_transport_speed != 1.0 && _count_in_samples > 0) {
                _count_in_samples = 0;
        }
+       if (_transport_speed == 0.0) {
+               _remaining_latency_preroll = 0;
+       }
 
-       if (_count_in_samples > 0) {
-               samplecnt_t ns = std::min ((samplecnt_t)nframes, _count_in_samples);
+       assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
 
-               no_roll (ns);
-               run_click (_transport_sample - _count_in_samples, ns);
+       while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
+               samplecnt_t ns;
+
+               if (_remaining_latency_preroll > 0) {
+                       ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
+               } else {
+                       ns = std::min ((samplecnt_t)nframes, _count_in_samples);
+               }
+
+               boost::shared_ptr<RouteList> r = routes.reader ();
+               for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+                       samplecnt_t route_offset = (*i)->playback_latency ();
+                       if (_remaining_latency_preroll > route_offset + ns) {
+                               /* route will no-roll for complete pre-roll cycle */
+                               continue;
+                       }
+                       if (_remaining_latency_preroll > route_offset) {
+                               /* route may need partial no-roll and partial roll from
+                               * (_transport_sample - _remaining_latency_preroll) ..  +ns.
+                               * shorten and split the cycle.
+                               */
+                               ns = std::min (ns, (_remaining_latency_preroll - route_offset));
+                       }
+               }
+
+               if (_count_in_samples > 0) {
+                       run_click (_transport_sample - _count_in_samples, ns);
+                       assert (_count_in_samples >= ns);
+                       _count_in_samples -= ns;
+               }
+
+               if (_remaining_latency_preroll > 0) {
+                       if (_count_in_samples == 0) {
+                               click (_transport_sample - _remaining_latency_preroll, ns);
+                       }
+                       if (process_routes (ns, session_needs_butler)) {
+                               fail_roll (ns);
+                       }
+               } else {
+                       no_roll (ns);
+               }
+
+               if (_remaining_latency_preroll > 0) {
+                       assert (_remaining_latency_preroll >= ns);
+                       _remaining_latency_preroll -= ns;
+               }
 
-               _count_in_samples -= ns;
                nframes -= ns;
 
                /* process events.. */
@@ -388,13 +433,9 @@ Session::process_with_events (pframes_t nframes)
                }
        }
 
-       if (_transport_speed == 1.0) {
-               samples_moved = (samplecnt_t) nframes;
-       } else {
-               interpolation.set_target_speed (_target_transport_speed);
-               interpolation.set_speed (_transport_speed);
-               samples_moved = (samplecnt_t) interpolation.interpolate (0, nframes, 0, 0);
-       }
+       assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
+
+       samples_moved = (samplecnt_t) nframes * _transport_speed;
 
        end_sample = _transport_sample + samples_moved;
 
@@ -409,13 +450,11 @@ Session::process_with_events (pframes_t nframes)
 
                if (!_exporting && _slave) {
                        if (!follow_slave (nframes)) {
-                               cerr << "P-w-E: FS fail\n";
                                return;
                        }
                }
 
                if (_transport_speed == 0) {
-                       cerr << "P-w-E: ts = 0\n";
                        no_roll (nframes);
                        return;
                }
@@ -429,7 +468,6 @@ Session::process_with_events (pframes_t nframes)
                samplepos_t stop_limit = compute_stop_limit ();
 
                if (maybe_stop (stop_limit)) {
-                       cerr << "P-w-E: mebbe stop\n";
                        no_roll (nframes);
                        return;
                }
@@ -461,7 +499,6 @@ Session::process_with_events (pframes_t nframes)
                                click (_transport_sample, this_nframes);
 
                                if (process_routes (this_nframes, session_needs_butler)) {
-                                       cerr << "P-w-E: PR fail\n";
                                        fail_roll (nframes);
                                        return;
                                }
@@ -476,8 +513,6 @@ Session::process_with_events (pframes_t nframes)
                                        increment_transport_position (samples_moved);
                                }
 
-                               cerr << "P-w-E: ts now = " << _transport_sample << endl;
-
                                maybe_stop (stop_limit);
                                check_declick_out ();
                        }
@@ -502,7 +537,6 @@ Session::process_with_events (pframes_t nframes)
                        /* if an event left our state changing, do the right thing */
 
                        if (nframes && non_realtime_work_pending()) {
-                               cerr << "P-w-E: nrtwp no roll\n";
                                no_roll (nframes);
                                break;
                        }
@@ -515,8 +549,6 @@ Session::process_with_events (pframes_t nframes)
 
        } /* implicit release of route lock */
 
-       cerr << "P-w-E: final ts = " << _transport_sample << endl;
-
        if (session_needs_butler) {
                DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
                _butler->summon ();
@@ -851,9 +883,8 @@ Session::process_without_events (pframes_t nframes)
        if (_transport_speed == 1.0) {
                samples_moved = (samplecnt_t) nframes;
        } else {
-               interpolation.set_target_speed (_target_transport_speed);
                interpolation.set_speed (_transport_speed);
-               samples_moved = (samplecnt_t) interpolation.interpolate (0, nframes, 0, 0);
+               samples_moved = interpolation.distance (nframes);
        }
 
        if (!_exporting && !timecode_transmission_suspended()) {
@@ -1126,7 +1157,7 @@ Session::process_event (SessionEvent* ev)
 
        case SessionEvent::PunchIn:
                // cerr << "PunchIN at " << transport_sample() << endl;
-               if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
+               if (config.get_punch_in() && record_status() == Enabled) {
                        enable_record ();
                }
                remove = false;
@@ -1135,21 +1166,13 @@ Session::process_event (SessionEvent* ev)
 
        case SessionEvent::PunchOut:
                // cerr << "PunchOUT at " << transport_sample() << endl;
-               if (config.get_punch_out() && !preroll_record_punch_enabled()) {
+               if (config.get_punch_out()) {
                        step_back_from_record ();
                }
                remove = false;
                del = false;
                break;
 
-       case SessionEvent::RecordStart:
-               if (preroll_record_punch_enabled() && record_status() == Enabled) {
-                       enable_record ();
-               }
-               remove = false;
-               del = false;
-               break;
-
        case SessionEvent::StopOnce:
                if (!non_realtime_work_pending()) {
                        _clear_event_type (SessionEvent::StopOnce);
@@ -1240,10 +1263,6 @@ Session::compute_stop_limit () const
                return max_samplepos;
        }
 
-       if (preroll_record_punch_enabled ()) {
-               return max_samplepos;
-       }
-
        bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
        bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());