diff --git a/ardour.rc.in b/ardour_system.rc
similarity index 88%
rename from ardour.rc.in
rename to ardour_system.rc
index ffee881be5..7534d79bf2 100644
--- a/ardour.rc.in
+++ b/ardour_system.rc
@@ -10,9 +10,9 @@
-
-
-
+
+
+
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc
index 16c893e645..c59c3c949e 100644
--- a/gtk2_ardour/rc_option_editor.cc
+++ b/gtk2_ardour/rc_option_editor.cc
@@ -1070,7 +1070,7 @@ RCOptionEditor::RCOptionEditor ()
"When enabled the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
"When disabled the session video frame rate will not be changed to match that of the selected external timecode source."
"Instead the frame rate indication in the main clock will flash red and Ardour will convert between the external "
- "timecode standard and the session standard"));
+ "timecode standard and the session standard."));
add_option (_("Transport"), _sync_framerate);
@@ -1082,7 +1082,7 @@ RCOptionEditor::RCOptionEditor ()
);
Gtkmm2ext::UI::instance()->set_tip
(_sync_genlock->tip_widget(),
- _("When enabled indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface"));
+ _("When enabled indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
add_option (_("Transport"), _sync_genlock);
@@ -1094,8 +1094,14 @@ RCOptionEditor::RCOptionEditor ()
sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
);
Gtkmm2ext::UI::instance()->set_tip
- (_sync_genlock->tip_widget(),
- _("When enabled the external timecode source is assumed to use 29.97 fps instead of 30000/1001"));
+ (_sync_source_2997->tip_widget(),
+ _("When enabled the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
+ "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
+ "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
+ "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
+ "That is not the actual rate, however some vendor use that rate - despite it being against the specs - "
+ "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
+ ));
add_option (_("Transport"), _sync_source_2997);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 507f25b118..89744669e7 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1201,6 +1201,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
framepos_t ltc_enc_pos;
double ltc_enc_cnt;
framepos_t ltc_enc_off;
+ bool restarting;
jack_latency_range_t ltc_out_latency;
diff --git a/libs/ardour/ltc_slave.cc b/libs/ardour/ltc_slave.cc
index 28c6331628..d52a70cab5 100644
--- a/libs/ardour/ltc_slave.cc
+++ b/libs/ardour/ltc_slave.cc
@@ -53,8 +53,8 @@ LTC_Slave::LTC_Slave (Session& s)
monotonic_cnt = 0;
fps_detected=false;
- ltc_timecode = timecode_60; // track changes of LTC fps
- a3e_timecode = timecode_60; // track changes of Ardour's fps
+ ltc_timecode = session.config.get_timecode_format();
+ a3e_timecode = session.config.get_timecode_format();
printed_timecode_warning = false;
ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
memset(&prev_frame, 0, sizeof(LTCFrameExt));
@@ -198,22 +198,23 @@ LTC_Slave::detect_ltc_fps(int frameno, bool df)
}
ltc_detect_fps_cnt++;
- if (ltc_detect_fps_cnt > 40)
- {
- if (ltc_detect_fps_cnt > ltc_detect_fps_max
- && ( ceil(timecode.rate) != (ltc_detect_fps_max + 1)
- || timecode.drop != df
- )
- )
- {
- DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC detected FPS %1%2",
- ltc_detect_fps_max + 1, timecode.drop ? "df" : ""));
+ if (ltc_detect_fps_cnt > 40) {
+ if (ltc_detect_fps_cnt > ltc_detect_fps_max) {
detected_fps = ltc_detect_fps_max + 1;
if (df) {
/* LTC df -> indicates fractional framerate */
- detected_fps = detected_fps * 1000.0 / 1001.0;
+ if (Config->get_timecode_source_2997()) {
+ detected_fps = detected_fps * 999.0 / 1000.0;
+ } else {
+ detected_fps = detected_fps * 1000.0 / 1001.0;
+ }
+ }
+
+ if (timecode.rate != detected_fps || timecode.drop != df) {
+ DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC detected FPS: %1%2\n", detected_fps, df?"df":"ndf"));
+ } else {
+ detected_fps = 0; /* no cange */
}
- DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC detected FPS: %1%2\n", detected_fps, df?"df":"ndf"));
}
ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
}
@@ -232,14 +233,6 @@ LTC_Slave::detect_ltc_fps(int frameno, bool df)
TimecodeFormat tc_format = apparent_timecode_format();
TimecodeFormat cur_timecode = session.config.get_timecode_format();
- if (Config->get_timecode_source_2997() && tc_format == Timecode::timecode_2997drop) {
- tc_format = Timecode::timecode_2997000drop;
- }
- else
- if (Config->get_timecode_source_2997() && tc_format == Timecode::timecode_2997) {
- tc_format = Timecode::timecode_2997000;
- }
-
if (Config->get_timecode_sync_frame_rate()) {
/* enforce time-code */
if (!did_reset_tc_format) {
@@ -519,9 +512,9 @@ LTC_Slave::apparent_timecode_format () const
else if (timecode.rate == 25 && !timecode.drop)
return timecode_25;
else if (rint(timecode.rate * 100) == 2997 && !timecode.drop)
- return timecode_2997;
+ return (Config->get_timecode_source_2997() ? timecode_2997000 : timecode_2997);
else if (rint(timecode.rate * 100) == 2997 && timecode.drop)
- return timecode_2997drop;
+ return (Config->get_timecode_source_2997() ? timecode_2997000drop : timecode_2997drop);
else if (timecode.rate == 30 && timecode.drop)
return timecode_2997drop; // timecode_30drop; // LTC counting to 30 frames w/DF *means* 29.97 df
else if (timecode.rate == 30 && !timecode.drop)
diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc
index f637d678a2..947de39486 100644
--- a/libs/ardour/mtc_slave.cc
+++ b/libs/ardour/mtc_slave.cc
@@ -313,9 +313,14 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now)
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS_DROP:
- timecode.rate = (30000.0/1001.0);
+ if (Config->get_timecode_source_2997()) {
+ tc_format = Timecode::timecode_2997000drop;
+ timecode.rate = (29970.0/1000.0);
+ } else {
+ tc_format = timecode_2997drop;
+ timecode.rate = (30000.0/1001.0);
+ }
timecode.drop = true;
- tc_format = timecode_2997drop;
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS:
diff --git a/libs/ardour/session_ltc.cc b/libs/ardour/session_ltc.cc
index cc146cbb59..0f7f280ef8 100644
--- a/libs/ardour/session_ltc.cc
+++ b/libs/ardour/session_ltc.cc
@@ -66,7 +66,7 @@ Session::ltc_tx_initialize()
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX init sr: %1 fps: %2\n", nominal_frame_rate(), timecode_to_frames_per_second(ltc_enc_tcformat)));
ltc_encoder = ltc_encoder_create(nominal_frame_rate(),
timecode_to_frames_per_second(ltc_enc_tcformat),
- 0);
+ -2);
ltc_encoder_set_bufsize(ltc_encoder, nominal_frame_rate(), 23.0);
ltc_encoder_set_filter(ltc_encoder, LTC_RISE_TIME(1.0));
@@ -81,6 +81,7 @@ Session::ltc_tx_initialize()
ltc_tx_resync_latency();
Xrun.connect_same_thread (*this, boost::bind (&Session::ltc_tx_reset, this));
engine().GraphReordered.connect_same_thread (*this, boost::bind (&Session::ltc_tx_resync_latency, this));
+ restarting = false;
}
void
@@ -113,6 +114,8 @@ Session::ltc_tx_reset()
ltc_buf_off = 0;
ltc_enc_byte = 0;
ltc_enc_cnt = 0;
+
+ ltc_encoder_reset(ltc_encoder);
}
void
@@ -134,6 +137,7 @@ Session::ltc_tx_recalculate_position()
config.get_subframes_per_frame(),
config.get_timecode_offset_negative(), config.get_timecode_offset()
);
+ restarting = false;
}
void
@@ -193,7 +197,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
TimecodeFormat cur_timecode = config.get_timecode_format();
if (cur_timecode != ltc_enc_tcformat) {
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX1: TC format mismatch - reinit sr: %1 fps: %2\n", nominal_frame_rate(), timecode_to_frames_per_second(cur_timecode)));
- if (ltc_encoder_reinit(ltc_encoder, nominal_frame_rate(), timecode_to_frames_per_second(cur_timecode), 0)) {
+ if (ltc_encoder_reinit(ltc_encoder, nominal_frame_rate(), timecode_to_frames_per_second(cur_timecode), -2)) {
PBD::error << _("LTC encoder: invalid framerate - LTC encoding is disabled for the remainder of this session.") << endmsg;
ltc_tx_cleanup();
return;
@@ -396,6 +400,12 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
maxdiff = slave()->resolution();
} else {
maxdiff = ceil(fabs(ltc_speed))*2.0;
+ if (nominal_frame_rate() != frame_rate()) {
+ maxdiff *= 3.0;
+ }
+ if (ltc_enc_tcformat == Timecode::timecode_23976 || ltc_enc_tcformat == Timecode::timecode_24976) {
+ maxdiff *= 15.0;
+ }
}
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX4: enc: %1 + %2 - %3 || buf-bytes: %4 enc-byte: %5\n",
@@ -464,6 +474,10 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX5 restart encoder: soff %1 byte %2 cycoff %3\n",
soff, ltc_enc_byte, cyc_off));
+ if ( (ltc_speed < 0 && ltc_enc_byte !=9 ) || (ltc_speed >= 0 && ltc_enc_byte !=0 ) ) {
+ restarting = true;
+ }
+
if (cyc_off > 0 && cyc_off <= nframes) {
/* offset in this cycle */
txf= rint(cyc_off / fabs(ltc_speed));
@@ -483,11 +497,11 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
/* reduce (low freq) jitter.
* The granularity of the LTC encoder speed is 1 byte =
* (frames-per-timecode-frame / 10) audio-samples.
- * Thus, tiny speed changes [as produced by the slave]
+ * Thus, tiny speed changes [as produced by some slaves]
* may not have any effect in the cycle when they occur,
* but they will add up over time.
*
- * This is a linear approx to compensate for this drift
+ * This is a linear approx to compensate for this jitter
* and prempt re-sync when the drift builds up.
*
* However, for very fast speeds - when 1 LTC bit is
@@ -536,13 +550,24 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
}
}
- if (ltc_encoder_encode_byte(ltc_encoder, ltc_enc_byte, (ltc_speed==0)?1.0:(1.0/ltc_speed))) {
- DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.3 encoder error byte %1\n", ltc_enc_byte));
- ltc_encoder_buffer_flush(ltc_encoder);
- ltc_tx_reset();
- return;
+ int enc_frames;
+
+ if (restarting) {
+ /* write zero bytes -- don't touch encoder until we're at a frame-boundary
+ * otherwise the biphase polarity may be inverted.
+ */
+ enc_frames = fptcf / 10.0;
+ memset(<c_enc_buf[ltc_buf_len], 127, enc_frames * sizeof(ltcsnd_sample_t));
+ } else {
+ if (ltc_encoder_encode_byte(ltc_encoder, ltc_enc_byte, (ltc_speed==0)?1.0:(1.0/ltc_speed))) {
+ DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.3 encoder error byte %1\n", ltc_enc_byte));
+ ltc_encoder_buffer_flush(ltc_encoder);
+ ltc_tx_reset();
+ return;
+ }
+ enc_frames = ltc_encoder_get_buffer(ltc_encoder, &(ltc_enc_buf[ltc_buf_len]));
}
- int enc_frames = ltc_encoder_get_buffer(ltc_encoder, &(ltc_enc_buf[ltc_buf_len]));
+
#ifdef LTC_GEN_FRAMEDBUG
DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.3 encoded %1 bytes for LTC-byte %2 at spd %3\n", enc_frames, ltc_enc_byte, ltc_speed));
#endif
@@ -573,6 +598,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
ltc_enc_cnt = 0;
} else if (ltc_enc_byte == 0) {
ltc_enc_cnt = 0;
+ restarting=false;
}
}
#ifdef LTC_GEN_FRAMEDBUG
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index ef108858f7..9524ca7708 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -285,7 +285,7 @@ def configure(conf):
autowaf.check_pkg(conf, 'libcurl', uselib_store='CURL',
atleast_version='7.0.0')
autowaf.check_pkg(conf, 'ltc', uselib_store='LTC',
- atleast_version='0.7.0', mandatory=False)
+ atleast_version='1.0.3', mandatory=False)
# we don't try to detect this, since its part of our source tree
diff --git a/libs/timecode/src/time.cc b/libs/timecode/src/time.cc
index b848db79b3..2d41d9b622 100644
--- a/libs/timecode/src/time.cc
+++ b/libs/timecode/src/time.cc
@@ -26,7 +26,7 @@
namespace Timecode {
-float Time::default_rate = 30.0;
+double Time::default_rate = 30.0;
/** Increment @a timecode by exactly one frame (keep subframes value).
@@ -424,7 +424,7 @@ hours_floor(Time& timecode)
}
}
-float
+double
timecode_to_frames_per_second(TimecodeFormat t)
{
switch (t) {
diff --git a/libs/timecode/timecode/time.h b/libs/timecode/timecode/time.h
index 256d8feaaf..23655bfe5d 100644
--- a/libs/timecode/timecode/time.h
+++ b/libs/timecode/timecode/time.h
@@ -48,17 +48,17 @@ enum TimecodeFormat {
};
struct Time {
- bool negative;
- uint32_t hours;
- uint32_t minutes;
- uint32_t seconds;
- uint32_t frames; ///< Timecode frames (not audio samples)
- uint32_t subframes; ///< Typically unused
- float rate; ///< Frame rate of this Time
- static float default_rate; ///< Rate to use for default constructor
- bool drop; ///< Whether this Time uses dropframe Timecode
+ bool negative;
+ uint32_t hours;
+ uint32_t minutes;
+ uint32_t seconds;
+ uint32_t frames; ///< Timecode frames (not audio samples)
+ uint32_t subframes; ///< Typically unused
+ double rate; ///< Frame rate of this Time
+ static double default_rate; ///< Rate to use for default constructor
+ bool drop; ///< Whether this Time uses dropframe Timecode
- Time (float a_rate = default_rate) {
+ Time (double a_rate = default_rate) {
negative = false;
hours = 0;
minutes = 0;
@@ -99,7 +99,7 @@ void seconds_floor (Time& timecode);
void minutes_floor (Time& timecode);
void hours_floor (Time& timecode);
-float timecode_to_frames_per_second(TimecodeFormat const t);
+double timecode_to_frames_per_second(TimecodeFormat const t);
bool timecode_has_drop_frames(TimecodeFormat const t);
std::string timecode_format_name (TimecodeFormat const t);
diff --git a/patchfiles/Yamaha-PSR-S900.midnam b/patchfiles/Yamaha-PSR-S900.midnam
index e7c978c545..ee501f96ae 100644
--- a/patchfiles/Yamaha-PSR-S900.midnam
+++ b/patchfiles/Yamaha-PSR-S900.midnam
@@ -2952,6 +2952,768 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8337,4 +9099,4 @@
-
+
\ No newline at end of file
diff --git a/wscript b/wscript
index e6a08bdce2..b812dd7eee 100644
--- a/wscript
+++ b/wscript
@@ -759,28 +759,7 @@ def build(bld):
for i in children:
bld.recurse(i)
- # ideally, we'd like to use the OS-provided MIDI API
- # for default ports. that doesn't work on at least
- # Fedora (Nov 9th, 2009) so use JACK MIDI on linux.
-
- if sys.platform == 'darwin':
- rc_subst_dict = {
- 'MIDITAG' : 'control',
- 'MIDITYPE' : 'coremidi',
- 'JACK_INPUT' : 'auditioner'
- }
- else:
- rc_subst_dict = {
- 'MIDITAG' : 'control',
- 'MIDITYPE' : 'jack',
- 'JACK_INPUT' : 'auditioner'
- }
-
- obj = bld(features = 'subst')
- obj.source = 'ardour.rc.in'
- obj.target = 'ardour_system.rc'
- obj.dict = rc_subst_dict
- obj.install_path = '${SYSCONFDIR}/ardour3'
+ bld.install_files (os.path.join(bld.env['SYSCONFDIR'], 'ardour3', ), 'ardour_system.rc')
def i18n(bld):
bld.recurse (i18n_children)