X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_transport.cc;h=0b0351f5063992aaf13f5630ba066a2ec7d62ab3;hb=682ebad62bdc85df151ad0b81dc27cc9f3e71cec;hp=27896f6e67839decfac6459e8f0d66ded3f2a0ab;hpb=c0f7f044f3e117660641d0b8b026c7bc4f53163c;p=ardour.git diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 27896f6e67..0b0351f506 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -99,6 +99,7 @@ Session::request_sync_source (Slave* new_slave) _was_seamless = seamless; ev->slave = new_slave; + DEBUG_TRACE (DEBUG::Slave, "sent request for new slave\n"); queue_event (ev); } @@ -203,6 +204,7 @@ Session::realtime_stop (bool abort, bool clear_state) if (_transport_speed < 0.0f) { todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse)); + _default_transport_speed = 1.0; } else { todo = PostTransportWork (todo | PostTransportStop); } @@ -299,8 +301,8 @@ Session::butler_transport_work () if (tr) { tr->adjust_playback_buffering (); /* and refill those buffers ... */ - tr->non_realtime_locate (_transport_frame); } + (*i)->non_realtime_locate (_transport_frame); } } @@ -344,10 +346,8 @@ Session::butler_transport_work () if (!(ptw & PostTransportLocate)) { for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); - if (tr && !tr->hidden()) { - tr->non_realtime_locate (_transport_frame); - } + (*i)->non_realtime_locate (_transport_frame); + if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) { /* new request, stop seeking, and start again */ g_atomic_int_dec_and_test (&_butler->should_do_transport_work); @@ -420,10 +420,7 @@ Session::non_realtime_locate () { boost::shared_ptr rl = routes.reader(); for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { - boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); - if (tr) { - tr->non_realtime_locate (_transport_frame); - } + (*i)->non_realtime_locate (_transport_frame); } /* XXX: it would be nice to generate the new clicks here (in the non-RT thread) @@ -494,7 +491,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { + if (!(*i)->is_auditioner()) { (*i)->set_pending_declick (0); } } @@ -601,10 +598,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n")); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name())); - boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); - if (tr && !tr->hidden()) { - tr->non_realtime_locate (_transport_frame); - } + (*i)->non_realtime_locate (_transport_frame); if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) { finished = false; @@ -625,9 +619,19 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } if ((ptw & PostTransportLocate) && get_record_enabled()) { - /* capture start has been changed, so save pending state */ - save_state ("", true); - saved = true; + /* This is scheduled by realtime_stop(), which is also done + * when a slave requests /locate/ for an initial sync. + * We can't hold up the slave for long with a save() here, + * without breaking its initial sync cycle. + * + * save state only if there's no slave or if it's not yet locked. + */ + if (!_slave || !_slave->locked()) { + DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: pending save\n")); + /* capture start has been changed, so save pending state */ + save_state ("", true); + saved = true; + } } /* always try to get rid of this */ @@ -646,14 +650,19 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } PositionChanged (_transport_frame); /* EMIT SIGNAL */ + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed)); TransportStateChange (); /* EMIT SIGNAL */ /* and start it up again if relevant */ if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) { request_transport_speed (1.0); - pending_locate_roll = false; } + + /* Even if we didn't do a pending locate roll this time, we don't want it hanging + around for next time. + */ + pending_locate_roll = false; } void @@ -774,6 +783,7 @@ Session::set_play_loop (bool yn) unset_play_loop (); } + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed)); TransportStateChange (); } void @@ -798,6 +808,14 @@ Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, if (target_frame != pos) { + if (config.get_jack_time_master()) { + /* actually locate now, since otherwise jack_timebase_callback + will use the incorrect _transport_frame and report an old + and incorrect time to Jack transport + */ + locate (target_frame, with_roll, with_flush, with_loop, force); + } + /* tell JACK to change transport position, and we will follow along later in ::follow_slave() */ @@ -848,7 +866,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool * though, is all the housekeeping that is associated with non-linear * changes in the value of _transport_frame. */ - + if (actively_recording() && !for_seamless_loop) { return; } @@ -880,6 +898,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool // Update Timecode time // [DR] FIXME: find out exactly where this should go below _transport_frame = target_frame; + _last_roll_or_reversal_location = target_frame; timecode_time(_transport_frame, transmitting_timecode_time); outbound_mtc_timecode_frame = _transport_frame; next_quarter_frame_to_send = 0; @@ -918,7 +937,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool /* this is functionally what clear_clicks() does but with a tentative lock */ - Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK); if (clickm.locked()) { @@ -998,15 +1017,20 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool void Session::set_transport_speed (double speed, bool abort, bool clear_state, bool as_default) { - DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %5\n", + DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n", speed, abort, clear_state, _transport_speed, _transport_frame, as_default)); if (_transport_speed == speed) { + if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what? + _default_transport_speed = 1.0; + } return; } if (actively_recording() && speed != 1.0 && speed != 0.0) { /* no varispeed during recording */ + DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n", + _transport_speed, _transport_frame)); return; } @@ -1116,6 +1140,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a _butler->schedule_transport_work (); } + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed)); TransportStateChange (); /* EMIT SIGNAL */ } } @@ -1227,7 +1252,6 @@ Session::start_transport () if (tr) { tr->realtime_set_speed (tr->speed(), true); } - (*i)->automation_snapshot (_transport_frame, true); } if (!_engine.freewheeling()) { @@ -1238,6 +1262,7 @@ Session::start_transport () } } + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed)); TransportStateChange (); /* EMIT SIGNAL */ } @@ -1310,6 +1335,8 @@ Session::use_sync_source (Slave* new_slave) delete _slave; _slave = new_slave; + DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave)); + send_full_time_code (_transport_frame); boost::shared_ptr rl = routes.reader(); @@ -1359,6 +1386,21 @@ Session::switch_to_sync_source (SyncSource src) } break; + case LTC: + if (_slave && dynamic_cast(_slave)) { + return; + } + + try { + new_slave = new LTC_Slave (*this); + } + + catch (failed_constructor& err) { + return; + } + + break; + case MIDIClock: if (_slave && dynamic_cast(_slave)) { return; @@ -1382,7 +1424,7 @@ Session::switch_to_sync_source (SyncSource src) return; } - new_slave = new JACK_Slave (_engine.jack()); + new_slave = new JACK_Slave (*AudioEngine::instance()); break; default: @@ -1486,6 +1528,7 @@ Session::set_play_range (list& range, bool leave_rolling) ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false); merge_event (ev); + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed)); TransportStateChange (); } @@ -1528,6 +1571,7 @@ Session::engine_halted () non_realtime_stop (false, 0, ignored); transport_sub_state = 0; + DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed)); TransportStateChange (); /* EMIT SIGNAL */ } @@ -1570,16 +1614,6 @@ Session::allow_auto_play (bool yn) auto_play_legal = yn; } -void -Session::reset_jack_connection (jack_client_t* jack) -{ - JACK_Slave* js; - - if (_slave && ((js = dynamic_cast (_slave)) != 0)) { - js->reset_client (jack); - } -} - bool Session::maybe_stop (framepos_t limit) {