X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_transport.cc;h=946d3ea890af83b57ec2ed94657819321e7dc53b;hb=ad547e53fc168410b22628a8cb125e8d4da4b293;hp=037d041895be646cfeea4caccdafb6f68b8b5472;hpb=10ef65b696492e5e6e9abe009f2e2c4a3af51994;p=ardour.git diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 037d041895..946d3ea890 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -30,6 +30,7 @@ #include "midi++/mmc.h" #include "midi++/port.h" +#include "midi++/manager.h" #include "ardour/ardour.h" #include "ardour/audioengine.h" @@ -141,7 +142,7 @@ void Session::request_play_loop (bool yn, bool leave_rolling) { SessionEvent* ev; - Location *location = _locations.auto_loop_location(); + Location *location = _locations->auto_loop_location(); if (location == 0 && yn) { error << _("Cannot loop - no loop range defined") @@ -181,12 +182,6 @@ Session::realtime_stop (bool abort, bool clear_state) /* assume that when we start, we'll be moving forwards */ - // FIXME: where should this really be? [DR] - //send_full_time_code(); - - _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop)); - send_mmc_locate (_transport_frame); - if (_transport_speed < 0.0f) { todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse)); } else { @@ -245,7 +240,7 @@ Session::realtime_stop (bool abort, bool clear_state) waiting_for_sync_offset = true; } - transport_sub_state = ((!config.get_external_sync()&& config.get_auto_return()) ? AutoReturning : 0); + transport_sub_state = 0; } void @@ -437,6 +432,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n")); + + if (abort && did_record) { + /* no reason to save the session file when we remove sources + */ + _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup); + } + for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); if (tr) { @@ -444,6 +446,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } } + if (abort && did_record) { + _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup); + } + boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { @@ -497,7 +503,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) if (!synced_to_jack()) { - Location *location = _locations.auto_loop_location(); + Location *location = _locations->auto_loop_location(); if (location != 0) { _transport_frame = location->start(); @@ -563,6 +569,8 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) have_looped = false; send_full_time_code (_transport_frame); + MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop)); + send_mmc_locate (_transport_frame); if ((ptw & PostTransportLocate) && get_record_enabled()) { /* capture start has been changed, so save pending state */ @@ -645,13 +653,11 @@ Session::set_play_loop (bool yn) Location *loc; - if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) { + if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) { /* nothing to do, or can't change loop status while recording */ return; } - set_dirty(); - if (yn && Config->get_seamless_loop() && synced_to_jack()) { warning << string_compose (_("Seamless looping cannot be supported while %1 is using JACK transport.\n" "Recommend changing the configured options"), PROGRAM_NAME) @@ -865,7 +871,7 @@ Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool /* cancel looped playback if transport pos outside of loop range */ if (play_loop) { - Location* al = _locations.auto_loop_location(); + Location* al = _locations->auto_loop_location(); if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { // cancel looping directly, this is called from event handling context @@ -1129,11 +1135,12 @@ Session::start_transport () if (tr) { tr->realtime_set_speed (tr->speed(), true); } + (*i)->automation_snapshot (_transport_frame, true); } Timecode::Time time; timecode_time_subframes (_transport_frame, time); - _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay)); + MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay)); TransportStateChange (); /* EMIT SIGNAL */ } @@ -1246,17 +1253,11 @@ Session::switch_to_sync_source (SyncSource src) return; } - if (_mtc_input_port) { - try { - new_slave = new MTC_Slave (*this, *_mtc_input_port); - } - - catch (failed_constructor& err) { - return; - } + try { + new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port()); + } - } else { - error << _("No MTC port defined: MTC slaving is impossible.") << endmsg; + catch (failed_constructor& err) { return; } break; @@ -1266,17 +1267,11 @@ Session::switch_to_sync_source (SyncSource src) return; } - if (_midi_clock_input_port) { - try { - new_slave = new MIDIClock_Slave (*this, *_midi_clock_input_port, 24); - } - - catch (failed_constructor& err) { - return; - } - - } else { - error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg; + try { + new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24); + } + + catch (failed_constructor& err) { return; } break; @@ -1286,6 +1281,10 @@ Session::switch_to_sync_source (SyncSource src) return; } + if (config.get_video_pullup() != 0.0f) { + return; + } + new_slave = new JACK_Slave (_engine.jack()); break; @@ -1570,5 +1569,29 @@ Session::send_mmc_locate (nframes64_t t) { Timecode::Time time; timecode_time_subframes (t, time); - _mmc->send (MIDI::MachineControlCommand (time)); + MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time)); +} + +/** Ask the transport to not send timecode until further notice. The suspension + * will come into effect some finite time after this call, and timecode_transmission_suspended() + * should be checked by the caller to find out when. + */ +void +Session::request_suspend_timecode_transmission () +{ + SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false); + queue_event (ev); +} + +void +Session::request_resume_timecode_transmission () +{ + SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true); + queue_event (ev); +} + +bool +Session::timecode_transmission_suspended () const +{ + return g_atomic_int_get (&_suspend_timecode_transmission) == 1; }