summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2020-05-13 16:08:48 +0200
committerRobin Gareus <robin@gareus.org>2020-05-13 17:39:06 +0200
commit7289be59c984192d269e63d081809ef835d7b477 (patch)
tree785a0397fe888ca1cf897c92e4442c4d1ea36408 /libs/ardour
parent5120b650c5ec6cb25099976e5476934cb969d7cf (diff)
Set timecode format from active master only
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/transport_master.h38
-rw-r--r--libs/ardour/ardour/transport_master_manager.h26
-rw-r--r--libs/ardour/ltc_slave.cc60
-rw-r--r--libs/ardour/mtc_slave.cc53
-rw-r--r--libs/ardour/transport_master.cc3
-rw-r--r--libs/ardour/transport_master_manager.cc52
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;
}