From 16dccfcb8af5eb3c5462ee6a7b3a00596fb8164e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 12 May 2015 12:17:17 -0400 Subject: Add some libardour support for indicating MTC active status. The general design here is wrong, because it should be more general and cover all possible sync sources. But it does work, it is used in Tracks, and my attempt to do it correctly revealed the problem to be an EXTREMELY difficult design issue (as in: two weeks of work on it did not really solve the fundamental issues with slave design). So, here it is for now, c/o Grygorii --- libs/ardour/ardour/session.h | 13 +++++++++- libs/ardour/ardour/slave.h | 2 ++ libs/ardour/mtc_slave.cc | 3 +++ libs/ardour/session.cc | 52 +++++++++++++++++++++------------------- libs/ardour/session_transport.cc | 19 +++++++++++++++ 5 files changed, 63 insertions(+), 26 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 0a4ca3951c..48243179f8 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -297,6 +297,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop PBD::Signal0 IOConnectionsComplete; + /* Timecode status signals */ + PBD::Signal1 MTCSyncStateChanged; + /* Record status signals */ PBD::Signal0 RecordStateChanged; /* signals changes in recording state (i.e. are we recording) */ @@ -343,6 +346,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop /* Step Editing status changed */ PBD::Signal1 StepEditStatusChange; + /* Timecode state signals */ + PBD::Signal0 MtcOrLtcInputPortChanged; + void queue_event (SessionEvent*); void request_roll_at_and_return (framepos_t start, framepos_t return_to); @@ -600,7 +606,8 @@ 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)); } + double transport_speed() const { return _transport_speed; } bool transport_stopped() const { return _transport_speed == 0.0f; } bool transport_rolling() const { return _transport_speed != 0.0f; } @@ -1070,6 +1077,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop bool _under_nsm_control; unsigned int _xrun_count; + void mtc_status_changed (bool); + PBD::ScopedConnection mtc_status_connection; + void initialize_latencies (); void set_worst_io_latencies (); void set_worst_playback_latency (); @@ -1107,6 +1117,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop bool have_first_delta_accumulator; SlaveState _slave_state; + gint _mtc_active; framepos_t slave_wait_end; void reset_slave_state (); diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 8396a337d7..2beacd7bf7 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -273,6 +273,8 @@ 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/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 1a1c5f2bec..83d61163c9 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -213,6 +213,7 @@ MTC_Slave::reset (bool with_position) window_end = 0; transport_direction = 1; current_delta = 0; + ActiveChanged(false); } void @@ -468,6 +469,7 @@ MTC_Slave::update_mtc_time (const MIDI::byte *msg, bool was_full, framepos_t now first_mtc_timestamp = now; init_mtc_dll(mtc_frame, qtr); mtc_frame_dll = mtc_frame; + ActiveChanged (true); // emit signal } current.guard1++; current.position = mtc_frame; @@ -626,6 +628,7 @@ MTC_Slave::speed_and_position (double& speed, framepos_t& pos) session.request_transport_speed (0); engine_dll_initstate = 0; queue_reset (false); + ActiveChanged (false); DEBUG_TRACE (DEBUG::MTC, "MTC not seen for 2 frames - reset pending\n"); return false; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index e60c27bf77..c0f717ec1c 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -184,6 +184,7 @@ Session::Session (AudioEngine &eng, , average_dir (0) , have_first_delta_accumulator (false) , _slave_state (Stopped) + , _mtc_active (false) , post_export_sync (false) , post_export_position (0) , _exporting (false) @@ -2671,36 +2672,37 @@ Session::reconnect_midi_scene_ports(bool inputs) } void -Session::reconnect_mtc_ports() +Session::reconnect_mtc_ports () { -#if 0 boost::shared_ptr mtc_in_ptr = _midi_ports->mtc_input_port(); - if (mtc_in_ptr) { - mtc_in_ptr->disconnect_all (); - - std::vector midi_port_states; - EngineStateController::instance()->get_physical_midi_input_states (midi_port_states); - - std::vector::iterator state_iter = midi_port_states.begin(); - - for (; state_iter != midi_port_states.end(); ++state_iter) { - if (state_iter->available && state_iter->mtc_in) { - mtc_in_ptr->connect (state_iter->name); - } - } - - if (!_midi_ports->mtc_input_port ()->connected () && - config.get_external_sync () && - (Config->get_sync_source () == MTC) ) { - config.set_external_sync (false); - } - if ( ARDOUR::Profile->get_trx () ) { - // Tracks need this signal to update timecode_source_dropdown - MtcOrLtcInputPortChanged (); //emit signal + if (!mtc_in_ptr) { + return; + } + + mtc_in_ptr->disconnect_all (); + + std::vector midi_port_states; + EngineStateController::instance()->get_physical_midi_input_states (midi_port_states); + + std::vector::iterator state_iter = midi_port_states.begin(); + + for (; state_iter != midi_port_states.end(); ++state_iter) { + if (state_iter->available && state_iter->mtc_in) { + mtc_in_ptr->connect (state_iter->name); } } -#endif + + if (!_midi_ports->mtc_input_port ()->connected () && + config.get_external_sync () && + (Config->get_sync_source () == MTC) ) { + config.set_external_sync (false); + } + + if ( ARDOUR::Profile->get_trx () ) { + // Tracks need this signal to update timecode_source_dropdown + MtcOrLtcInputPortChanged (); //emit signal + } } void diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 4e93565f11..1c9293c760 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -1542,6 +1542,13 @@ Session::reset_rf_scale (framecnt_t motion) } } +void +Session::mtc_status_changed (bool yn) +{ + g_atomic_int_set (&_mtc_active, yn); + MTCSyncStateChanged( yn ); +} + void Session::use_sync_source (Slave* new_slave) { @@ -1554,6 +1561,18 @@ Session::use_sync_source (Slave* new_slave) delete _slave; _slave = new_slave; + MTC_Slave* mtc_slave = dynamic_cast(_slave); + if (mtc_slave) { + mtc_slave->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1)); + MTCSyncStateChanged(mtc_slave->locked() ); + } else { + if (g_atomic_int_get (&_mtc_active) ){ + g_atomic_int_set (&_mtc_active, 0); + MTCSyncStateChanged( false ); + } + mtc_status_connection.disconnect (); + } + DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave)); // need to queue this for next process() cycle -- cgit v1.2.3