tweaks to be ready for more information timecode display in Timecode clock mode
[ardour.git] / libs / ardour / ltc_slave.cc
1 /*
2     Copyright (C) 2012 Paul Davis
3     Witten by 2012 Robin Gareus <robin@gareus.org>
4
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.
9
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.
14
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.
18
19 */
20 #include <iostream>
21 #include <errno.h>
22 #include <poll.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25
26 #include "pbd/error.h"
27
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"
33
34 #include "i18n.h"
35
36 using namespace std;
37 using namespace ARDOUR;
38 using namespace MIDI;
39 using namespace PBD;
40 using namespace Timecode;
41
42 LTC_Slave::LTC_Slave (Session& s)
43         : session (s)
44 {
45         frames_per_ltc_frame = 1920.0; // samplerate / framerate
46         ltc_transport_pos = 0;
47         ltc_speed = 1.0;
48         last_timestamp = 0;
49
50         decoder = ltc_decoder_create((int) frames_per_ltc_frame, 128 /*queue size*/);
51 }
52
53 LTC_Slave::~LTC_Slave()
54 {
55         if (did_reset_tc_format) {
56                 session.config.set_timecode_format (saved_tc_format);
57         }
58
59         ltc_decoder_free(decoder);
60 }
61
62 bool
63 LTC_Slave::give_slave_full_control_over_transport_speed() const
64 {
65         return true; // DLL align to engine transport
66         // return false; // for Session-level computed varispeed
67 }
68
69 ARDOUR::framecnt_t
70 LTC_Slave::resolution () const
71 {
72         return (framecnt_t) (frames_per_ltc_frame);
73 }
74
75 ARDOUR::framecnt_t
76 LTC_Slave::seekahead_distance () const
77 {
78         return (framecnt_t) (frames_per_ltc_frame * 2);
79 }
80
81 bool
82 LTC_Slave::locked () const
83 {
84         return true;
85 }
86
87 bool
88 LTC_Slave::ok() const
89 {
90         return true;
91 }
92
93 int
94 LTC_Slave::parse_ltc(const jack_nframes_t nframes, const jack_default_audio_sample_t * const in, const framecnt_t posinfo)
95 {
96         jack_nframes_t i;
97         unsigned char sound[8192];
98         if (nframes > 8192) return 1;
99
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);
103         }
104         ltc_decoder_write(decoder, sound, nframes, posinfo);
105         return 0;
106 }
107
108 bool
109 LTC_Slave::process_ltc(framepos_t now, framecnt_t nframes)
110 {
111         Time timecode;
112         bool have_frame = false;
113
114         framepos_t sess_pos = session.transport_frame(); // corresponds to now
115         //sess_pos -= session.engine().frames_since_cycle_start();
116
117         DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC Process eng-tme: %1 eng-pos: %2\n", now, sess_pos));
118
119         LTCFrameExt frame;
120         while (ltc_decoder_read(decoder,&frame)) {
121                 SMPTETimecode stime;
122                 ltc_frame_to_time(&stime, &frame.ltc, 0);
123 #if 1
124                 fprintf(stdout, "LTC %02d:%02d:%02d%c%02d | %8lld %8lld%s\n",
125                         stime.hours,
126                         stime.mins,
127                         stime.secs,
128                         (frame.ltc.dfbit) ? '.' : ':',
129                         stime.frame,
130                         frame.off_start,
131                         frame.off_end,
132                         frame.reverse ? " R" : "  "
133                         );
134 #endif
135
136                 timecode.negative  = false;
137                 timecode.subframes  = 0;
138                 timecode.drop  = (frame.ltc.dfbit)? true : false;
139                 timecode.rate  = 25.0; // XXX
140
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
145                  */
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);
150                 } else {
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;
155                 }
156
157                 timecode.hours   = stime.hours;
158                 timecode.minutes = stime.mins;
159                 timecode.seconds = stime.secs;
160                 timecode.frames  = stime.frame;
161
162                 framepos_t ltc_frame;
163                 session.timecode_to_sample (timecode, ltc_frame, true, false);
164
165                 double poff = (frame.off_end - now);
166
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.
170
171                 DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC frame: %1 poff: %2 pos :%3\n", ltc_frame, poff, ltc_transport_pos));
172
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
176                 } else {
177
178                         double e = (double(ltc_frame) - poff - double(sess_pos));
179                         // update DLL
180                         t0 = t1;
181                         t1 += b * e + e2;
182                         e2 += c * e;
183
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));
186
187                 }
188                 last_timestamp = now;
189                 last_ltc_frame = ltc_frame;
190                 have_frame = true;
191         }
192         return have_frame;
193 }
194
195 void
196 LTC_Slave::init_ltc_dll(framepos_t tme, double dt)
197 {
198         omega = 2.0 * M_PI * dt / double(session.frame_rate());
199         b = 1.4142135623730950488 * omega;
200         c = omega * omega;
201
202         e2 = dt;
203         t0 = double(tme);
204         t1 = t0 + e2;
205         DEBUG_TRACE (DEBUG::LTC, string_compose ("[re-]init LTC DLL %1 %2 %3\n", t0, t1, e2));
206 }
207
208 /* main entry point from session_process.cc
209  * called from jack_process callback context
210  */
211 bool
212 LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
213 {
214
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;
219
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);
223
224         DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC_Slave::speed_and_position - TID:%1 | latency: %2\n", ::pthread_self(), ltc_latency.max));
225
226         if (in) {
227                 parse_ltc(nframes, in, now  + ltc_latency.max );
228                 if (!process_ltc(now, nframes)) {
229                         /* fly wheel */
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));
233                 }
234         }
235
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();
240                 last_timestamp = 0;
241                 return true;
242         }
243
244         pos = ltc_transport_pos;
245         speed = ltc_speed;
246
247         return true;
248 }
249
250 Timecode::TimecodeFormat
251 LTC_Slave::apparent_timecode_format () const
252 {
253         /* XXX to be computed, determined from incoming stream */
254         return timecode_25;
255 }
256
257 std::string 
258 LTC_Slave::approximate_current_position() const
259 {
260         return "88:88:88:88";
261 }