From 0f9cac978eff240c6290978986187334d576156c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 25 May 2015 20:56:03 -0400 Subject: [PATCH] (re)implement Yevgeny's LTC branch changes in the context of ardour-merge-from-tracks (just the libs/* section) --- libs/ardour/ardour/session.h | 13 +++++++++---- libs/ardour/ardour/slave.h | 30 +++++++++++++++--------------- libs/ardour/ltc_slave.cc | 10 ++++++++-- libs/ardour/session.cc | 12 ++++++++---- libs/ardour/session_transport.cc | 19 +++++++++++++++++++ libs/ardour/utils.cc | 4 ++++ 6 files changed, 63 insertions(+), 25 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a2f8c164c8..f75e38cff6 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -300,7 +300,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop /* Timecode status signals */ PBD::Signal1 MTCSyncStateChanged; - + PBD::Signal1 LTCSyncStateChanged; + /* Record status signals */ PBD::Signal0 RecordStateChanged; /* signals changes in recording state (i.e. are we recording) */ @@ -610,6 +611,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void request_sync_source (Slave*); bool synced_to_engine() const { return _slave && config.get_external_sync() && Config->get_sync_source() == Engine; } bool synced_to_mtc () const { return config.get_external_sync() && Config->get_sync_source() == MTC && g_atomic_int_get (const_cast(&_mtc_active)); } + bool synced_to_ltc () const { return config.get_external_sync() && Config->get_sync_source() == LTC && g_atomic_int_get (const_cast(&_ltc_active)); } double transport_speed() const { return _transport_speed; } bool transport_stopped() const { return _transport_speed == 0.0f; } @@ -1017,6 +1019,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void reconnect_mtc_ports (); void reconnect_mmc_ports (bool); + void reconnect_ltc_input (); + void reconnect_ltc_output (); + protected: friend class AudioEngine; void set_block_size (pframes_t nframes); @@ -1090,6 +1095,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void mtc_status_changed (bool); PBD::ScopedConnection mtc_status_connection; + void ltc_status_changed (bool); + PBD::ScopedConnection ltc_status_connection; void initialize_latencies (); void set_worst_io_latencies (); @@ -1129,6 +1136,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop SlaveState _slave_state; gint _mtc_active; + gint _ltc_active; framepos_t slave_wait_end; void reset_slave_state (); @@ -1796,9 +1804,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop boost::shared_ptr _ltc_input; boost::shared_ptr _ltc_output; - void reconnect_ltc_input (); - void reconnect_ltc_output (); - /* Scene Changing */ SceneChanger* _scene_changer; diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 2beacd7bf7..bda47ceba0 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -237,19 +237,21 @@ struct LIBARDOUR_API SafeTime { class LIBARDOUR_API TimecodeSlave : public Slave { public: - TimecodeSlave () {} - - virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0; - - /* this is intended to be used by a UI and polled from a timeout. it should - return a string describing the current position of the TC source. it - should NOT do any computation, but should use a cached value - of the TC source position. - */ - virtual std::string approximate_current_position() const = 0; - - framepos_t timecode_offset; - bool timecode_negative_offset; + TimecodeSlave () {} + + virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0; + + /* this is intended to be used by a UI and polled from a timeout. it should + return a string describing the current position of the TC source. it + should NOT do any computation, but should use a cached value + of the TC source position. + */ + virtual std::string approximate_current_position() const = 0; + + framepos_t timecode_offset; + bool timecode_negative_offset; + + PBD::Signal1 ActiveChanged; }; class LIBARDOUR_API MTC_Slave : public TimecodeSlave { @@ -273,8 +275,6 @@ class LIBARDOUR_API MTC_Slave : public TimecodeSlave { std::string approximate_current_position() const; std::string approximate_current_delta() const; - PBD::Signal1 ActiveChanged; - private: Session& session; MidiPort* port; diff --git a/libs/ardour/ltc_slave.cc b/libs/ardour/ltc_slave.cc index c5840f68d4..5f15f460f8 100644 --- a/libs/ardour/ltc_slave.cc +++ b/libs/ardour/ltc_slave.cc @@ -26,6 +26,7 @@ #include "pbd/pthread_utils.h" #include "ardour/debug.h" +#include "ardour/profile.h" #include "ardour/slave.h" #include "ardour/session.h" #include "ardour/audioengine.h" @@ -151,6 +152,8 @@ LTC_Slave::reset() ltc_speed = 0; engine_dll_initstate = 0; sync_lock_broken = false; + + ActiveChanged (false); /* EMIT SIGNAL */ } void @@ -443,8 +446,10 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos) if (last_timestamp == 0) { engine_dll_initstate = 0; if (delayedlocked < 10) ++delayedlocked; - } - else if (engine_dll_initstate != transport_direction && ltc_speed != 0) { + } else if (engine_dll_initstate != transport_direction && ltc_speed != 0) { + + ActiveChanged (true); /* EMIT SIGNAL */ + engine_dll_initstate = transport_direction; init_engine_dll(last_ltc_frame + rint(ltc_speed * double(2 * nframes + now - last_timestamp)), session.engine().samples_per_cycle()); @@ -488,6 +493,7 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos) reset(); speed = 0; pos = session.transport_frame(); + ActiveChanged (false); /* EMIT SIGNAL */ return true; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index eb6e97cd0e..ef7bf5d200 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -191,7 +191,8 @@ Session::Session (AudioEngine &eng, , average_dir (0) , have_first_delta_accumulator (false) , _slave_state (Stopped) - , _mtc_active (false) + , _mtc_active (false) + , _ltc_active (false) , post_export_sync (false) , post_export_position (0) , _exporting (false) @@ -6132,6 +6133,11 @@ Session::reconnect_ltc_input () if (src != _("None") && !src.empty()) { _ltc_input->nth (0)->connect (src); } + + if ( ARDOUR::Profile->get_trx () ) { + // Tracks need this signal to update timecode_source_dropdown + MtcOrLtcInputPortChanged (); //emit signal + } } } @@ -6140,15 +6146,13 @@ Session::reconnect_ltc_output () { if (_ltc_output) { -#if 0 - string src = Config->get_ltc_sink_port(); + string src = Config->get_ltc_output_port(); _ltc_output->disconnect (this); if (src != _("None") && !src.empty()) { _ltc_output->nth (0)->connect (src); } -#endif } } diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index c0765c3991..80bfb10998 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -1618,6 +1618,13 @@ Session::mtc_status_changed (bool yn) MTCSyncStateChanged( yn ); } +void +Session::ltc_status_changed (bool yn) +{ + g_atomic_int_set (&_ltc_active, yn); + LTCSyncStateChanged( yn ); +} + void Session::use_sync_source (Slave* new_slave) { @@ -1642,6 +1649,18 @@ Session::use_sync_source (Slave* new_slave) mtc_status_connection.disconnect (); } + LTC_Slave* ltc_slave = dynamic_cast (_slave); + if (ltc_slave) { + ltc_slave->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1)); + LTCSyncStateChanged (ltc_slave->locked() ); + } else { + if (g_atomic_int_get (&_ltc_active) ){ + g_atomic_int_set (&_ltc_active, 0); + LTCSyncStateChanged( false ); + } + ltc_status_connection.disconnect (); + } + DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave)); // need to queue this for next process() cycle diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index 6d6511bb9f..2ada8ce79b 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -467,6 +467,10 @@ ARDOUR::string_to_sync_source (string str) return Engine; } + if (str == _("LTC")) { + return LTC; + } + fatal << string_compose (_("programming error: unknown sync source string \"%1\""), str) << endmsg; abort(); /*NOTREACHED*/ return Engine;