diff options
author | Robin Gareus <robin@gareus.org> | 2020-05-13 16:08:48 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2020-05-13 17:39:06 +0200 |
commit | 7289be59c984192d269e63d081809ef835d7b477 (patch) | |
tree | 785a0397fe888ca1cf897c92e4442c4d1ea36408 /libs | |
parent | 5120b650c5ec6cb25099976e5476934cb969d7cf (diff) |
Set timecode format from active master only
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/transport_master.h | 38 | ||||
-rw-r--r-- | libs/ardour/ardour/transport_master_manager.h | 26 | ||||
-rw-r--r-- | libs/ardour/ltc_slave.cc | 60 | ||||
-rw-r--r-- | libs/ardour/mtc_slave.cc | 53 | ||||
-rw-r--r-- | libs/ardour/transport_master.cc | 3 | ||||
-rw-r--r-- | libs/ardour/transport_master_manager.cc | 52 |
6 files changed, 97 insertions, 135 deletions
diff --git a/libs/ardour/ardour/transport_master.h b/libs/ardour/ardour/transport_master.h index 02f728e483..ee311d290b 100644 --- a/libs/ardour/ardour/transport_master.h +++ b/libs/ardour/ardour/transport_master.h @@ -474,8 +474,10 @@ public: TimecodeTransportMaster (std::string const& name, SyncSource type); virtual Timecode::TimecodeFormat apparent_timecode_format () const = 0; - samplepos_t timecode_offset; - bool timecode_negative_offset; + + bool apparent_timecode_format_valid () const { + return timecode_format_valid; + } bool fr2997 () const { @@ -486,6 +488,10 @@ public: protected: void register_properties (); + samplepos_t timecode_offset; + bool timecode_negative_offset; + bool timecode_format_valid; + private: PBD::Property<bool> _fr2997; }; @@ -536,8 +542,7 @@ private: samplepos_t window_begin; samplepos_t window_end; samplepos_t first_mtc_timestamp; - bool did_reset_tc_format; - Timecode::TimecodeFormat saved_tc_format; + Glib::Threads::Mutex reset_lock; uint32_t reset_pending; bool reset_position; @@ -545,12 +550,9 @@ private: int busy_guard1; int busy_guard2; - double speedup_due_to_tc_mismatch; double quarter_frame_duration; Timecode::TimecodeFormat mtc_timecode; - Timecode::TimecodeFormat a3e_timecode; Timecode::Time timecode; - bool printed_timecode_warning; void queue_reset (bool with_pos); void maybe_reset (); @@ -616,26 +618,20 @@ private: void parameter_changed (std::string const& p); void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string, boost::weak_ptr<ARDOUR::Port>, std::string, bool); - bool did_reset_tc_format; - Timecode::TimecodeFormat saved_tc_format; - LTCDecoder* decoder; double samples_per_ltc_frame; Timecode::Time timecode; LTCFrameExt prev_frame; bool fps_detected; - samplecnt_t monotonic_cnt; - uint64_t frames_since_reset; - int delayedlocked; - - int ltc_detect_fps_cnt; - int ltc_detect_fps_max; - bool printed_timecode_warning; - bool sync_lock_broken; - Timecode::TimecodeFormat ltc_timecode; - Timecode::TimecodeFormat a3e_timecode; - double samples_per_timecode_frame; + samplecnt_t monotonic_cnt; + uint64_t frames_since_reset; + int delayedlocked; + + int ltc_detect_fps_cnt; + int ltc_detect_fps_max; + bool sync_lock_broken; + double samples_per_timecode_frame; PBD::ScopedConnection port_connection; PBD::ScopedConnectionList session_connections; diff --git a/libs/ardour/ardour/transport_master_manager.h b/libs/ardour/ardour/transport_master_manager.h index 0aaf1bf00c..6035a18b8b 100644 --- a/libs/ardour/ardour/transport_master_manager.h +++ b/libs/ardour/ardour/transport_master_manager.h @@ -96,26 +96,32 @@ class LIBARDOUR_API TransportMasterManager : public boost::noncopyable mutable Glib::Threads::RWLock lock; double _master_speed; samplepos_t _master_position; - boost::shared_ptr<TransportMaster> _current_master; + + boost::shared_ptr<TransportMaster> _current_master; Session* _session; bool _master_invalid_this_cycle; bool disk_output_blocked; - // a DLL to chase the transport master - - int transport_dll_initstate; - double t0; /// time at the beginning of ??? - double t1; /// calculated end of the ??? - double e2; /// second order loop error - double bandwidth; /// DLL filter bandwidth - double b, c, omega; /// DLL filter coefficients + /* a DLL to chase the transport master, calculate playback speed + * by matching Ardour's current playhead position against + * the position of the transport-master */ + double t0; // PH position at the beginning of this cycle + double t1; // expected PH position if next cycle + double e2; // second order loop error + double bandwidth; // DLL filter bandwidth + double b, c, omega; // DLL filter coefficients void init_transport_master_dll (double speed, samplepos_t pos); - int master_dll_initstate; + int master_dll_initstate; // play-direction -1, +1, or 0: not initialized static TransportMasterManager* _instance; + /* original TC format in case the slave changed it */ + boost::optional<Timecode::TimecodeFormat> _session_tc_format; + void maybe_restore_tc_format (); + void maybe_set_tc_format (); + int add_locked (boost::shared_ptr<TransportMaster>); double compute_matching_master_speed (pframes_t nframes, samplepos_t, bool& locate_required); int set_current_locked (boost::shared_ptr<TransportMaster>); diff --git a/libs/ardour/ltc_slave.cc b/libs/ardour/ltc_slave.cc index 266a9bc305..b76f3ad647 100644 --- a/libs/ardour/ltc_slave.cc +++ b/libs/ardour/ltc_slave.cc @@ -48,8 +48,6 @@ using namespace Timecode; LTC_TransportMaster::LTC_TransportMaster (std::string const & name) : TimecodeTransportMaster (name, LTC) - , did_reset_tc_format (false) - , saved_tc_format (timecode_24) // whatever .... , decoder (0) , samples_per_ltc_frame (0) , fps_detected (false) @@ -58,10 +56,7 @@ LTC_TransportMaster::LTC_TransportMaster (std::string const & name) , delayedlocked (10) , ltc_detect_fps_cnt (0) , ltc_detect_fps_max (0) - , printed_timecode_warning (false) , sync_lock_broken (false) - , ltc_timecode (Timecode::timecode_24) - , a3e_timecode (Timecode::timecode_24) , samples_per_timecode_frame (0) { memset (&prev_frame, 0, sizeof(LTCFrameExt)); @@ -94,9 +89,6 @@ LTC_TransportMaster::set_session (Session *s) samples_per_ltc_frame = _session->samples_per_timecode_frame(); timecode.drop = _session->timecode_drop_frames(); - printed_timecode_warning = false; - ltc_timecode = _session->config.get_timecode_format(); - a3e_timecode = _session->config.get_timecode_format(); if (decoder) { ltc_decoder_free (decoder); @@ -117,10 +109,6 @@ LTC_TransportMaster::~LTC_TransportMaster() port_connection.disconnect(); session_connections.drop_connections(); - if (did_reset_tc_format) { - _session->config.set_timecode_format (saved_tc_format); - } - ltc_decoder_free(decoder); } @@ -234,6 +222,7 @@ LTC_TransportMaster::reset (bool with_position) monotonic_cnt = 0; memset (&prev_frame, 0, sizeof(LTCFrameExt)); frames_since_reset = 0; + timecode_format_valid = false; } void @@ -358,6 +347,8 @@ LTC_TransportMaster::detect_ltc_fps(int frameno, bool df) } } + timecode_format_valid = true; /* SET FLAG */ + if (timecode.rate != detected_fps || timecode.drop != df) { DEBUG_TRACE (DEBUG::LTC, string_compose ("detected FPS: %1%2\n", detected_fps, df?"df":"ndf")); } else { @@ -378,50 +369,7 @@ LTC_TransportMaster::detect_ltc_fps(int frameno, bool df) } TimecodeFormat tc_format = apparent_timecode_format(); - - if (_session) { - - /* poll and check session TC */ - - TimecodeFormat cur_timecode = _session->config.get_timecode_format(); - - if (Config->get_timecode_sync_frame_rate()) { - /* enforce time-code */ - if (!did_reset_tc_format) { - saved_tc_format = cur_timecode; - did_reset_tc_format = true; - } - if (cur_timecode != tc_format) { - if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) { - warning << string_compose(_("Session framerate adjusted from %1 to LTC's %2."), - Timecode::timecode_format_name(cur_timecode), - Timecode::timecode_format_name(tc_format)) - << endmsg; - } - _session->config.set_timecode_format (tc_format); - } - } else { - /* only warn about TC mismatch */ - if (ltc_timecode != tc_format) printed_timecode_warning = false; - if (a3e_timecode != cur_timecode) printed_timecode_warning = false; - - if (cur_timecode != tc_format && ! printed_timecode_warning) { - if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) { - warning << string_compose(_("Session and LTC framerate mismatch: LTC:%1 Session:%2."), - Timecode::timecode_format_name(tc_format), - Timecode::timecode_format_name(cur_timecode)) - << endmsg; - } - printed_timecode_warning = true; - } - } - - a3e_timecode = cur_timecode; - } - - ltc_timecode = tc_format; - - samples_per_timecode_frame = ENGINE->sample_rate() / Timecode::timecode_to_frames_per_second (ltc_timecode); + samples_per_timecode_frame = ENGINE->sample_rate() / Timecode::timecode_to_frames_per_second (tc_format); return fps_changed; } diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 181c4f277e..38a5f01978 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -61,13 +61,11 @@ MTC_TransportMaster::MTC_TransportMaster (std::string const & name) , window_begin (0) , window_end (0) , first_mtc_timestamp (0) - , did_reset_tc_format (false) , reset_pending (0) , reset_position (false) , transport_direction (1) , busy_guard1 (0) , busy_guard2 (0) - , printed_timecode_warning (false) { init (); } @@ -76,10 +74,6 @@ MTC_TransportMaster::~MTC_TransportMaster() { port_connections.drop_connections(); session_connections.drop_connections(); - - if (_session && did_reset_tc_format) { - _session->config.set_timecode_format (saved_tc_format); - } } void @@ -135,7 +129,6 @@ MTC_TransportMaster::set_session (Session *s) last_mtc_fps_byte = _session->get_mtc_timecode_bits (); quarter_frame_duration = (double) (_session->samples_per_timecode_frame() / 4.0); mtc_timecode = _session->config.get_timecode_format(); - a3e_timecode = _session->config.get_timecode_format(); parse_timecode_offset (); reset (true); @@ -265,6 +258,7 @@ MTC_TransportMaster::reset (bool with_position) window_end = 0; transport_direction = 1; _current_delta = 0; + timecode_format_valid = false; } void @@ -342,7 +336,7 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp */ DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", pthread_name())); TimecodeFormat tc_format; - bool reset_tc = true; + bool have_tc = true; timecode.hours = msg[3]; timecode.minutes = msg[2]; @@ -397,46 +391,12 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp } timecode.rate = _session->timecode_frames_per_second(); timecode.drop = _session->timecode_drop_frames(); - reset_tc = false; + have_tc = false; } - if (reset_tc) { - TimecodeFormat cur_timecode = _session->config.get_timecode_format(); - if (Config->get_timecode_sync_frame_rate()) { - /* enforce time-code */ - if (!did_reset_tc_format) { - saved_tc_format = cur_timecode; - did_reset_tc_format = true; - } - if (cur_timecode != tc_format) { - if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) { - warning << string_compose(_("Session framerate adjusted from %1 TO: MTC's %2."), - Timecode::timecode_format_name(cur_timecode), - Timecode::timecode_format_name(tc_format)) - << endmsg; - } - } - _session->config.set_timecode_format (tc_format); - } else { - /* only warn about TC mismatch */ - if (mtc_timecode != tc_format) printed_timecode_warning = false; - if (a3e_timecode != cur_timecode) printed_timecode_warning = false; - - if (cur_timecode != tc_format && ! printed_timecode_warning) { - if (ceil(Timecode::timecode_to_frames_per_second(cur_timecode)) != ceil(Timecode::timecode_to_frames_per_second(tc_format))) { - warning << string_compose(_("Session and MTC framerate mismatch: MTC:%1 %2:%3."), - Timecode::timecode_format_name(tc_format), - PROGRAM_NAME, - Timecode::timecode_format_name(cur_timecode)) - << endmsg; - } - printed_timecode_warning = true; - } - } + if (have_tc) { mtc_timecode = tc_format; - a3e_timecode = cur_timecode; - - speedup_due_to_tc_mismatch = timecode.rate / Timecode::timecode_to_frames_per_second(a3e_timecode); + timecode_format_valid = true; /* SET FLAG */ } /* do a careful conversion of the timecode value to a position @@ -452,8 +412,7 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp timecode_negative_offset, timecode_offset ); - DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC at %1 TC %2 = mtc_frame %3 (from full message ? %4) tc-ratio %5\n", - now, timecode, mtc_frame, was_full, speedup_due_to_tc_mismatch)); + DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC at %1 TC %2 = mtc_frame %3 (from full message ? %4)\n", now, timecode, mtc_frame, was_full)); if (was_full || outside_window (mtc_frame)) { DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC %1 or outside window %2 MTC %3\n", was_full, outside_window (mtc_frame), mtc_frame)); diff --git a/libs/ardour/transport_master.cc b/libs/ardour/transport_master.cc index d7e0a040c5..b31227cddc 100644 --- a/libs/ardour/transport_master.cc +++ b/libs/ardour/transport_master.cc @@ -511,6 +511,9 @@ TransportMaster::set_request_mask (TransportRequestType t) TimecodeTransportMaster::TimecodeTransportMaster (std::string const & name, SyncSource type) : TransportMaster (type, name) + , timecode_offset (0) + , timecode_negative_offset (false) + , timecode_format_valid (false) , _fr2997 (Properties::fr2997, false) { register_properties (); diff --git a/libs/ardour/transport_master_manager.cc b/libs/ardour/transport_master_manager.cc index 2875021966..779d10e7e0 100644 --- a/libs/ardour/transport_master_manager.cc +++ b/libs/ardour/transport_master_manager.cc @@ -102,6 +102,8 @@ TransportMasterManager::set_session (Session* s) Glib::Threads::RWLock::ReaderLock lm (lock); + maybe_restore_tc_format (); + config_connection.disconnect (); _session = s; @@ -177,6 +179,7 @@ TransportMasterManager::pre_process_transport_masters (pframes_t nframes, sample } if (!_session->config.get_external_sync()) { + maybe_restore_tc_format (); DEBUG_TRACE (DEBUG::Slave, string_compose ("no external sync, use session actual speed of %1\n", _session->actual_speed() ? _session->actual_speed() : 1.0)); return _session->actual_speed () ? _session->actual_speed() : 1.0; } @@ -231,7 +234,7 @@ TransportMasterManager::pre_process_transport_masters (pframes_t nframes, sample if (master_dll_initstate == 0) { init_transport_master_dll (_master_speed, _master_position); - DEBUG_TRACE (DEBUG::Slave, string_compose ("no roll3 - still initializing master DLL, will be %1 next process cycle\n", master_dll_initstate)); + DEBUG_TRACE (DEBUG::Slave, string_compose ("initializing master DLL, will be %1 next process cycle\n", master_dll_initstate)); return _master_speed; } @@ -298,11 +301,56 @@ TransportMasterManager::pre_process_transport_masters (pframes_t nframes, sample _master_invalid_this_cycle = false; + maybe_set_tc_format (); + DEBUG_TRACE (DEBUG::Slave, string_compose ("computed resampling ratio as %1 with position = %2 and speed = %3\n", engine_speed, _master_position, _master_speed)); return engine_speed; } +void +TransportMasterManager::maybe_restore_tc_format () +{ + if (_session && _session_tc_format) { + _session->config.set_timecode_format (*_session_tc_format); + } + _session_tc_format.reset (); +} + +void +TransportMasterManager::maybe_set_tc_format () +{ + if (!Config->get_timecode_sync_frame_rate() || !_session) { + return; + } + boost::shared_ptr<TimecodeTransportMaster> tcm; + if ((tcm = boost::dynamic_pointer_cast<TimecodeTransportMaster>(_current_master)) == 0) { + return; + } + + if (!tcm->apparent_timecode_format_valid ()) { + return; + } + + Timecode::TimecodeFormat stf = _session->config.get_timecode_format(); + Timecode::TimecodeFormat mtf = tcm->apparent_timecode_format (); + + if (stf == mtf) { + return; + } + + /* save session's original TC */ + if (!_session_tc_format) { + _session_tc_format = stf; + } + + warning << string_compose(_("Transport master adjusted framerate from %1 to %2."), + Timecode::timecode_format_name(stf), + Timecode::timecode_format_name(mtf)) + << endmsg; + + _session->config.set_timecode_format (mtf); +} void TransportMasterManager::init_transport_master_dll (double speed, samplepos_t pos) @@ -423,6 +471,8 @@ TransportMasterManager::set_current_locked (boost::shared_ptr<TransportMaster> c } } + maybe_restore_tc_format (); + if (!c->usable()) { return -1; } |