X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_process.cc;h=cd3c023f3eed5ad40e565687838be052937aa079;hb=02ec346c2b8a8872bfb3b7f231556c0f514ff95f;hp=8a677105bd81509398a54829e2ad21c54a0be2f8;hpb=a473d630eb165272992e90f8d854b1d66ec0be63;p=ardour.git diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 8a677105bd..cd3c023f3e 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -38,6 +38,9 @@ #include "ardour/timestamps.h" #include "ardour/graph.h" #include "ardour/audio_port.h" +#include "ardour/tempo.h" +#include "ardour/ticker.h" +#include "ardour/cycle_timer.h" #include "midi++/manager.h" #include "midi++/mmc.h" @@ -55,6 +58,8 @@ using namespace std; void Session::process (pframes_t nframes) { + framepos_t transport_at_start = _transport_frame; + MIDI::Manager::instance()->cycle_start(nframes); _silent = false; @@ -76,13 +81,19 @@ Session::process (pframes_t nframes) _engine.main_thread()->drop_buffers (); - // the ticker is for sending time information like MidiClock - framepos_t transport_frames = transport_frame(); - Timecode::BBT_Time transport_bbt; - bbt_time(transport_frames, transport_bbt); - Timecode::Time transport_timecode; - timecode_time(transport_frames, transport_timecode); - tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */ + /* deliver MIDI clock. Note that we need to use the transport frame + * position at the start of process(), not the value at the end of + * it. We may already have ticked() because of a transport state + * change, for example. + */ + + try { + if (Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) { + midi_clock->tick (transport_at_start); + } + } catch (...) { + /* don't bother with a message */ + } SendFeedback (); /* EMIT SIGNAL */ @@ -98,6 +109,8 @@ Session::fail_roll (pframes_t nframes) int Session::no_roll (pframes_t nframes) { + PT_TIMING_CHECK (4); + framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ?? int ret = 0; bool declick = get_transport_declick_required(); @@ -107,10 +120,11 @@ Session::no_roll (pframes_t nframes) _click_io->silence (nframes); } - if (route_graph->threads_in_use() > 0) { + if (_process_graph) { DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n"); - route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick); + _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick); } else { + PT_TIMING_CHECK (10); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->is_hidden()) { @@ -119,24 +133,26 @@ Session::no_roll (pframes_t nframes) (*i)->set_pending_declick (declick); - if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(), - actively_recording(), declick)) { + if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) { error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg; ret = -1; break; } } + PT_TIMING_CHECK (11); } + PT_TIMING_CHECK (5); return ret; } +/** @param need_butler to be set to true by this method if it needs the butler, + * otherwise it must be left alone. + */ int Session::process_routes (pframes_t nframes, bool& need_butler) { - bool record_active; int declick = get_transport_declick_required(); - bool rec_monitors = get_rec_monitors_input(); boost::shared_ptr r = routes.reader (); if (transport_sub_state & StopPendingCapture) { @@ -144,18 +160,12 @@ Session::process_routes (pframes_t nframes, bool& need_butler) declick = -1; } - record_active = actively_recording(); // || (get_record_enabled() && get_punch_in()); - const framepos_t start_frame = _transport_frame; const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed); - /* XXX this is hack to force use of the graph even if we are only - using 1 thread. its needed because otherwise when we remove - tracks, the graph never gets updated. - */ - if (1 || route_graph->threads_in_use() > 0) { + if (_process_graph) { DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n"); - route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler); + _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler); } else { for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { @@ -168,38 +178,35 @@ Session::process_routes (pframes_t nframes, bool& need_butler) (*i)->set_pending_declick (declick); - if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) { + bool b = false; + + if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) { stop_transport (); return -1; } + + if (b) { + need_butler = true; + } } } return 0; } +/** @param need_butler to be set to true by this method if it needs the butler, + * otherwise it must be left alone. + */ int Session::silent_process_routes (pframes_t nframes, bool& need_butler) { - bool record_active = actively_recording(); - int declick = get_transport_declick_required(); - bool rec_monitors = get_rec_monitors_input(); boost::shared_ptr 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 + lrintf(nframes * _transport_speed); - /* XXX this is hack to force use of the graph even if we are only - using 1 thread. its needed because otherwise when we remove - tracks, the graph never gets updated. - */ - if (1 || route_graph->threads_in_use() > 0) { - route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler); + if (_process_graph) { + _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler); } else { for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { @@ -209,10 +216,16 @@ Session::silent_process_routes (pframes_t nframes, bool& need_butler) continue; } - if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) { + bool b = false; + + if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) { stop_transport (); return -1; } + + if (b) { + need_butler = true; + } } } @@ -250,6 +263,8 @@ Session::get_track_statistics () void Session::process_with_events (pframes_t nframes) { + PT_TIMING_CHECK (3); + SessionEvent* ev; pframes_t this_nframes; framepos_t end_frame; @@ -625,7 +640,7 @@ Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta } void -Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta) +Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/) { if (slave_speed != 0.0f) { @@ -705,7 +720,6 @@ Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size); average_slave_delta = 0L; - this_delta = 0; } } @@ -1147,11 +1161,23 @@ Session::process_event (SessionEvent* ev) framepos_t Session::compute_stop_limit () const { - bool const punching = (config.get_punch_in () && _locations->auto_punch_location()); - - if (!actively_recording() && !punching && Config->get_stop_at_session_end()) { - return current_end_frame (); + if (!Config->get_stop_at_session_end ()) { + return max_framepos; + } + + bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location()); + bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location()); + + if (actively_recording ()) { + /* permanently recording */ + return max_framepos; + } else if (punching_in && !punching_out) { + /* punching in but never out */ + return max_framepos; + } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) { + /* punching in and punching out after session end */ + return max_framepos; } - return max_framepos; + return current_end_frame (); }