clickless meter-point changes
[ardour.git] / libs / ardour / session_process.cc
index 680f2861de2a2bdae8e90515ea89c96ef1fdd0d8..7db46f915724b3b605670975aae0e2760058da8a 100644 (file)
@@ -75,6 +75,17 @@ Session::process (pframes_t nframes)
 
        (this->*process_function) (nframes);
 
+       /* realtime-safe meter-position changes
+        *
+        * ideally this would be done in
+        * Route::process_output_buffers() but various functions
+        * callig it hold a _processor_lock reader-lock
+        */
+       boost::shared_ptr<RouteList> r = routes.reader ();
+       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+               (*i)->apply_meter_change_rt();
+       }
+
        _engine.main_thread()->drop_buffers ();
 
        /* deliver MIDI clock. Note that we need to use the transport frame
@@ -154,17 +165,15 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
        int  declick = get_transport_declick_required();
        boost::shared_ptr<RouteList> r = routes.reader ();
 
-       if (transport_sub_state & StopPendingCapture) {
-               /* force a declick out */
-               declick = -1;
-       }
-
        const framepos_t start_frame = _transport_frame;
        const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
        
        if (_process_graph) {
                DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
-               _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
+               if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
+                       stop_transport ();
+                       return -1;
+               }
        } else {
 
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
@@ -375,6 +384,8 @@ Session::process_with_events (pframes_t nframes)
                        send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
                }
 
+               ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
+
                framepos_t stop_limit = compute_stop_limit ();
 
                if (maybe_stop (stop_limit)) {
@@ -581,7 +592,7 @@ Session::follow_slave (pframes_t nframes)
 #endif
 
                        if (_slave->give_slave_full_control_over_transport_speed()) {
-                               set_transport_speed (slave_speed, false, false);
+                               set_transport_speed (slave_speed, 0, false, false);
                                //std::cout << "set speed = " << slave_speed << "\n";
                        } else {
                                float adjusted_speed = slave_speed + (1.5 * (delta /  float(_current_frame_rate)));
@@ -762,7 +773,7 @@ Session::follow_slave_silently (pframes_t nframes, float slave_speed)
                   for now.
                */
 
-               bool need_butler;
+               bool need_butler = false;
 
                silent_process_routes (nframes, need_butler);
 
@@ -1061,6 +1072,15 @@ Session::process_event (SessionEvent* ev)
                _send_timecode_update = true;
                break;
 
+       case SessionEvent::Skip:
+               if (Config->get_skip_playback()) {
+                       start_locate (ev->target_frame, true, true, false);
+                       _send_timecode_update = true;
+               }
+               remove = false;
+               del = false;
+               break;
+
        case SessionEvent::LocateRollLocate:
                // locate is handled by ::request_roll_at_and_return()
                _requested_return_frame = ev->target_frame;
@@ -1069,7 +1089,7 @@ Session::process_event (SessionEvent* ev)
 
 
        case SessionEvent::SetTransportSpeed:
-               set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
+               set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
                break;
 
        case SessionEvent::PunchIn:
@@ -1092,8 +1112,8 @@ Session::process_event (SessionEvent* ev)
 
        case SessionEvent::StopOnce:
                if (!non_realtime_work_pending()) {
-                       stop_transport (ev->yes_or_no);
                        _clear_event_type (SessionEvent::StopOnce);
+                       stop_transport (ev->yes_or_no);
                }
                remove = false;
                del = false;
@@ -1142,6 +1162,10 @@ Session::process_event (SessionEvent* ev)
                set_play_range (ev->audio_range, (ev->speed == 1.0f));
                break;
 
+       case SessionEvent::CancelPlayAudioRange:
+               unset_play_range();
+               break;
+
        case SessionEvent::RealTimeOperation:
                process_rtop (ev);
                del = false; // other side of RT request needs to clean up
@@ -1161,7 +1185,7 @@ Session::process_event (SessionEvent* ev)
 
        default:
          fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
-               /*NOTREACHED*/
+               abort(); /*NOTREACHED*/
                break;
        };