2 Copyright (C) 2012 Paul Davis
3 Witten by 2012 Robin Gareus <robin@gareus.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <sys/types.h>
26 #include "pbd/error.h"
28 #include "ardour/debug.h"
29 #include "ardour/slave.h"
30 #include "ardour/session.h"
31 #include "ardour/audioengine.h"
32 #include "ardour/audio_port.h"
37 using namespace ARDOUR;
40 using namespace Timecode;
42 LTC_Slave::LTC_Slave (Session& s)
45 frames_per_ltc_frame = 1920.0; // samplerate / framerate
46 ltc_transport_pos = 0;
50 decoder = ltc_decoder_create((int) frames_per_ltc_frame, 128 /*queue size*/);
53 LTC_Slave::~LTC_Slave()
55 if (did_reset_tc_format) {
56 session.config.set_timecode_format (saved_tc_format);
59 ltc_decoder_free(decoder);
63 LTC_Slave::give_slave_full_control_over_transport_speed() const
65 return true; // DLL align to engine transport
66 // return false; // for Session-level computed varispeed
70 LTC_Slave::resolution () const
72 return (framecnt_t) (frames_per_ltc_frame);
76 LTC_Slave::seekahead_distance () const
78 return (framecnt_t) (frames_per_ltc_frame * 2);
82 LTC_Slave::locked () const
94 LTC_Slave::parse_ltc(const jack_nframes_t nframes, const jack_default_audio_sample_t * const in, const framecnt_t posinfo)
97 unsigned char sound[8192];
98 if (nframes > 8192) return 1;
100 for (i = 0; i < nframes; i++) {
101 const int snd=(int)rint((127.0*in[i])+128.0);
102 sound[i] = (unsigned char) (snd&0xff);
104 ltc_decoder_write(decoder, sound, nframes, posinfo);
109 LTC_Slave::process_ltc(framepos_t now, framecnt_t nframes)
112 bool have_frame = false;
114 framepos_t sess_pos = session.transport_frame(); // corresponds to now
115 //sess_pos -= session.engine().frames_since_cycle_start();
117 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC Process eng-tme: %1 eng-pos: %2\n", now, sess_pos));
120 while (ltc_decoder_read(decoder,&frame)) {
122 ltc_frame_to_time(&stime, &frame.ltc, 0);
124 fprintf(stdout, "LTC %02d:%02d:%02d%c%02d | %8lld %8lld%s\n",
128 (frame.ltc.dfbit) ? '.' : ':',
132 frame.reverse ? " R" : " "
136 timecode.negative = false;
137 timecode.subframes = 0;
138 timecode.drop = (frame.ltc.dfbit)? true : false;
139 timecode.rate = 25.0; // XXX
141 /* when a full LTC frame is decoded, the timecode the LTC frame
142 * is referring has just passed.
143 * So we send the _next_ timecode which
144 * is expected to start at the end of the current frame
146 int fps_i = ceil(timecode.rate);
147 if (!frame.reverse) {
148 ltc_frame_increment(&frame.ltc, fps_i , 0);
149 ltc_frame_to_time(&stime, &frame.ltc, 0);
151 ltc_frame_decrement(&frame.ltc, fps_i , 0);
152 int off = frame.off_end - frame.off_start;
153 frame.off_start += off;
154 frame.off_end += off;
157 timecode.hours = stime.hours;
158 timecode.minutes = stime.mins;
159 timecode.seconds = stime.secs;
160 timecode.frames = stime.frame;
162 framepos_t ltc_frame;
163 session.timecode_to_sample (timecode, ltc_frame, true, false);
165 double poff = (frame.off_end - now);
167 ltc_transport_pos = ltc_frame - poff;
168 frames_per_ltc_frame = (double(session.frame_rate()) / timecode.rate);
169 //frames_per_ltc_frame = frame.off_end - frame.off_start; // the first one is off.
171 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC frame: %1 poff: %2 pos :%3\n", ltc_frame, poff, ltc_transport_pos));
173 if (last_timestamp == 0 || ((now - last_timestamp) > 4 * frames_per_ltc_frame) ) {
174 init_ltc_dll(ltc_frame, frames_per_ltc_frame);
175 ltc_speed = 1.0; // XXX
178 double e = (double(ltc_frame) - poff - double(sess_pos));
184 ltc_speed = (t1 - t0) / frames_per_ltc_frame;
185 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", t0, t1, e, ltc_speed, e2 - frames_per_ltc_frame));
188 last_timestamp = now;
189 last_ltc_frame = ltc_frame;
196 LTC_Slave::init_ltc_dll(framepos_t tme, double dt)
198 omega = 2.0 * M_PI * dt / double(session.frame_rate());
199 b = 1.4142135623730950488 * omega;
205 DEBUG_TRACE (DEBUG::LTC, string_compose ("[re-]init LTC DLL %1 %2 %3\n", t0, t1, e2));
208 /* main entry point from session_process.cc
209 * called from jack_process callback context
212 LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
215 framepos_t now = session.engine().frame_time_at_cycle_start();
216 framecnt_t nframes = session.engine().frames_per_cycle();
217 jack_default_audio_sample_t *in;
218 jack_latency_range_t ltc_latency;
220 Port *ltcport = session.engine().ltc_input_port();
221 ltcport->get_connected_latency_range(ltc_latency, false);
222 in = (jack_default_audio_sample_t*) jack_port_get_buffer (ltcport->jack_port(), nframes);
224 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC_Slave::speed_and_position - TID:%1 | latency: %2\n", ::pthread_self(), ltc_latency.max));
227 parse_ltc(nframes, in, now + ltc_latency.max );
228 if (!process_ltc(now, nframes)) {
230 double elapsed = (now - last_timestamp) * ltc_speed;
231 ltc_transport_pos = last_ltc_frame + elapsed;
232 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC fly wheel elapsed: %1 @speed %2\n", elapsed, ltc_speed));
236 if (((now - last_timestamp) > 4 * frames_per_ltc_frame) ) {
237 DEBUG_TRACE (DEBUG::LTC, "LTC no-signal - reset\n");
238 speed = ltc_speed = 0;
239 pos = session.transport_frame();
244 pos = ltc_transport_pos;
250 Timecode::TimecodeFormat
251 LTC_Slave::apparent_timecode_format () const
253 /* XXX to be computed, determined from incoming stream */
258 LTC_Slave::approximate_current_position() const
260 return "88:88:88:88";