add LTC generator
[ardour.git] / libs / ardour / session_ltc.cc
1 /*
2   Copyright (C) 2012 Paul Davis
3   Written by 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 "ardour/debug.h"
21 #include "timecode/time.h"
22 #include "ardour/session.h"
23 #include "ardour/audioengine.h"
24 #include "ardour/audio_port.h"
25
26 #include "i18n.h"
27
28 using namespace std;
29 using namespace ARDOUR;
30 using namespace MIDI;
31 using namespace PBD;
32 using namespace Timecode;
33
34 //#define LTC_GEN_FRAMEDBUG
35
36 void
37 Session::ltc_tx_initialize()
38 {
39         ltc_enc_tcformat = config.get_timecode_format();
40
41         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)));
42         ltc_encoder = ltc_encoder_create(nominal_frame_rate(),
43                         timecode_to_frames_per_second(ltc_enc_tcformat),
44                         0);
45
46         ltc_encoder_set_bufsize(ltc_encoder, nominal_frame_rate(), 23.0);
47
48         /* buffersize for 1 LTC frame: (1 + sample-rate / fps) bytes
49          * usually returned by ltc_encoder_get_buffersize(encoder)
50          *
51          * since the fps can change and A3's  min fps: 24000/1001 */
52         ltc_enc_buf = (ltcsnd_sample_t*) calloc((nominal_frame_rate() / 23), sizeof(ltcsnd_sample_t));
53         ltc_speed = 0;
54         ltc_tx_reset();
55 }
56
57 void
58 Session::ltc_tx_cleanup()
59 {
60         DEBUG_TRACE (DEBUG::LTC, "LTC TX cleanup\n");
61         if (ltc_enc_buf) free(ltc_enc_buf);
62         ltc_encoder_free(ltc_encoder);
63         ltc_encoder = NULL;
64 }
65
66 void
67 Session::ltc_tx_reset()
68 {
69         DEBUG_TRACE (DEBUG::LTC, "LTC TX reset\n");
70         ltc_enc_pos = -1; // force re-start
71         ltc_buf_len = 0;
72         ltc_buf_off = 0;
73         ltc_enc_byte = 0;
74 }
75
76 int
77 Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, 
78                 double target_speed, double current_speed,
79                 pframes_t nframes)
80 {
81         assert(nframes > 0);
82
83         const float smult = 2.0/(3.0*255.0);
84         SMPTETimecode tc;
85         jack_default_audio_sample_t *out;
86         pframes_t txf = 0;
87         boost::shared_ptr<Port> ltcport = engine().ltc_output_port();
88
89         if (!ltc_encoder || !ltc_enc_buf || !ltcport || ! ltcport->jack_port()) return 0;
90
91         out = (jack_default_audio_sample_t*) jack_port_get_buffer (ltcport->jack_port(), nframes);
92         if (!out) return 0;
93
94         if (engine().freewheeling() || !Config->get_send_ltc()) {
95                 memset(out, 0, nframes * sizeof(jack_default_audio_sample_t));
96                 return nframes;
97         }
98
99         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX %1 to %2 / %3\n", start_frame, end_frame, nframes));
100
101         /* all systems go. Now here's the plan:
102          *
103          *  1) check if fps has changed
104          *  2) check direction of encoding, calc speed
105          *  3) calculate frame and byte to send aligned to jack-period size
106          *  4) check if it's the frame/byte that is already in the queue
107          *  5) if (4) mismatch, re-calculate offset of LTC frame relative to period size
108          *  6) actual LTC audio output
109          *  6a) send remaining part of already queued frame; break on nframes
110          *  6b) encode new LTC-frame byte
111          *  6c) goto 6a
112          *  7) done
113          */
114
115         // (1)
116         TimecodeFormat cur_timecode = config.get_timecode_format();
117         if (cur_timecode != ltc_enc_tcformat) {
118                 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)));
119                 if (ltc_encoder_reinit(ltc_encoder, nominal_frame_rate(), timecode_to_frames_per_second(cur_timecode), 0)) {
120                         PBD::error << _("LTC encoder: invalid framerate - LTC encoding is disabled for the remainder of this session.") << endmsg;
121                         ltc_tx_cleanup();
122                         return 0;
123                 }
124                 ltc_enc_tcformat = cur_timecode;
125                 ltc_tx_reset();
126         }
127
128         /* LTC is max. 30 fps */
129         if (timecode_to_frames_per_second(cur_timecode) > 30) {
130                 memset(out, 0, nframes * sizeof(jack_default_audio_sample_t));
131                 return nframes;
132         }
133
134         // (2)
135 #define SIGNUM(a) ( (a) < 0 ? -1 : 1)
136
137         framepos_t cycle_start_frame = (current_speed < 0) ? end_frame :start_frame;
138         double new_ltc_speed = double(labs(end_frame - start_frame) * SIGNUM(current_speed)) / double(nframes);
139
140         if (SIGNUM(new_ltc_speed) != SIGNUM (ltc_speed)) {
141                 // transport changed direction
142                 DEBUG_TRACE (DEBUG::LTC, "LTC TX2: transport direction changed\n");
143                 ltc_tx_reset();
144         }
145
146         if (ltc_speed != current_speed || target_speed != fabs(current_speed)) {
147                 /* TODO check ./libs/ardour/interpolation.cc  CubicInterpolation::interpolate
148                  * if target_speed != current_speed we should interpolate, too.
149                  *
150                  * However, currenly in A3 target_speed == current_speed for each process cycle
151                  * (except for the sign). Besides, above speed calulation uses the
152                  * difference (end_frame - start_frame).
153                  * end_frame is calculated from 'frames_moved' which includes the interpolation.
154                  * so we're good, except for the fact that each LTC byte is sent at fixed speed.
155                  */
156                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: speed change old: %1 cur: %2 tgt: %3 ctd: %4\n", ltc_speed, current_speed, target_speed, fabs(current_speed) - target_speed));
157         }
158
159         if (end_frame == start_frame || fabs(current_speed) < 0.1 ) {
160                 DEBUG_TRACE (DEBUG::LTC, "LTC TX2: transport is not rolling or absolute-speed < 0.1\n");
161                 /* keep repeating current frame
162                  *
163                  * an LTC generator must be able to continue generating LTC when Ardours transport is in stop
164                  * some machines do odd things if LTC goes away:
165                  * e.g. a tape based machine (video or audio), some think they have gone into park if LTC goes away,
166                  * so unspool the tape from the playhead. That might be inconvenient.
167                  * If LTC keeps arriving they remain in a stop position with the tape on the playhead.
168                  */
169                 new_ltc_speed = 0;
170         }
171
172         ltc_speed = new_ltc_speed;
173         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX2: transport speed %1.\n", ltc_speed));
174
175         if (fabs(ltc_speed) > 10.0) {
176                 DEBUG_TRACE (DEBUG::LTC, "LTC TX2: speed is out of bounds.\n");
177                 ltc_tx_reset();
178                 memset(out, 0, nframes * sizeof(jack_default_audio_sample_t));
179                 return nframes;
180         }
181
182         // (3)
183         Timecode::Time tc_start;
184         framepos_t tc_sample_start;
185
186         /* calc timecode frame from current position - round down to nearest timecode */
187         int boff;
188         if (ltc_speed == 0) {
189                 boff = 0;
190         }       else if (ltc_speed < 0) {
191                 boff = (ltc_enc_byte - 9) * frames_per_timecode_frame() / 10;
192         } else {
193                 boff = ltc_enc_byte * frames_per_timecode_frame() / 10;
194         }
195
196         sample_to_timecode(cycle_start_frame
197                         - boff
198                         - ltc_speed * (ltc_buf_len - ltc_buf_off),
199                         tc_start, true, false);
200
201         /* convert timecode back to sample-position */
202         Timecode::timecode_to_sample (tc_start, tc_sample_start, true, false,
203                 double(frame_rate()),
204                 config.get_subframes_per_frame(),
205                 config.get_timecode_offset_negative(), config.get_timecode_offset()
206                 );
207
208         /* difference between current frame and TC frame in samples */
209         frameoffset_t soff = cycle_start_frame - tc_sample_start;
210         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX3: now: %1 tra: %2 eoff %3\n", cycle_start_frame, tc_sample_start, soff));
211
212         // (4)
213         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX4: enc: %1 boff: %2 || enc-byte:%3\n", ltc_enc_pos, boff, ltc_enc_byte));
214         if (ltc_enc_pos != tc_sample_start) {
215
216                 /* re-calc timecode w/o buffer offset */
217                 sample_to_timecode(cycle_start_frame, tc_start, true, false);
218                 Timecode::timecode_to_sample (tc_start, tc_sample_start, true, false,
219                         double(frame_rate()),
220                         config.get_subframes_per_frame(),
221                         config.get_timecode_offset_negative(), config.get_timecode_offset()
222                         );
223                 soff = cycle_start_frame - tc_sample_start;
224                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX4: now: %1 trs: %2 toff %3\n", cycle_start_frame, tc_sample_start, soff));
225
226                 tc.hours = tc_start.hours;
227                 tc.mins = tc_start.minutes;
228                 tc.secs = tc_start.seconds;
229                 tc.frame = tc_start.frames;
230                 ltc_encoder_set_timecode(ltc_encoder, &tc);
231
232 #if 1
233                 /* workaround for libltc recognizing 29.97 and 30000/1001 as drop-frame TC.
234                  * in A3 only 30000/1001 is drop-frame and there are also other questionable
235                  * DF timecodes  such as 24k/1001 and 25k/1001.
236                  */
237                 LTCFrame ltcframe;
238                 ltc_encoder_get_frame(ltc_encoder, &ltcframe);
239                 ltcframe.dfbit = timecode_has_drop_frames(cur_timecode)?1:0;
240                 ltc_encoder_set_frame(ltc_encoder, &ltcframe);
241 #endif
242
243                 // (5)
244                 int fdiff = 0;
245                 if (soff < 0) {
246                         fdiff = ceil(-soff / frames_per_timecode_frame());
247                         soff += fdiff * frames_per_timecode_frame();
248                         for (int i=0; i < fdiff; ++i) {
249                                 ltc_encoder_inc_timecode(ltc_encoder);
250                         }
251                 }
252                 else if (soff >= frames_per_timecode_frame()) {
253                         fdiff = floor(soff / frames_per_timecode_frame());
254                         soff -= fdiff * frames_per_timecode_frame();
255                         for (int i=0; i < fdiff; ++i) {
256                                 ltc_encoder_dec_timecode(ltc_encoder);
257                         }
258                 }
259
260                 assert(soff >= 0 && soff < frames_per_timecode_frame());
261
262                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX5 restart encoder fdiff %1 sdiff %2\n", fdiff, soff));
263                 ltc_tx_reset();
264
265                 if (ltc_speed == 0) {
266                         // offset is irrelevant when not rolling
267                         soff = 0;
268                 }
269                 if (soff > 0 && soff <= nframes) {
270                         txf=soff;
271                         memset(out, 0, soff * sizeof(jack_default_audio_sample_t));
272                 } else if (soff > 0) {
273                         /* resync next cycle */
274                         memset(out, 0, soff * sizeof(jack_default_audio_sample_t));
275                         return nframes;
276                 }
277
278                 ltc_enc_byte = soff * 10 / frames_per_timecode_frame();
279
280                 if (ltc_speed < 0 ) {
281                         ltc_enc_byte = 9 - ltc_enc_byte;
282                 }
283
284                 ltc_enc_pos = tc_sample_start;
285                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX5 restart @ %1 byte %2\n", ltc_enc_pos, ltc_enc_byte));
286         }
287
288         // (6)
289         while (1) {
290 #ifdef LTC_GEN_FRAMEDBUG
291                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.1 @%1  [ %2 / %3 ]\n", txf, ltc_buf_off, ltc_buf_len));
292 #endif
293                 // (6a)
294                 while ((ltc_buf_off < ltc_buf_len) && (txf < nframes)) {
295                         const float v1 = ltc_enc_buf[ltc_buf_off++] - 128.0;
296                         const jack_default_audio_sample_t val = (jack_default_audio_sample_t) (v1*smult);
297                         out[txf++] = val;
298                 }
299 #ifdef LTC_GEN_FRAMEDBUG
300                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.2 @%1  [ %2 / %3 ]\n", txf, ltc_buf_off, ltc_buf_len));
301 #endif
302
303                 if (txf >= nframes) {
304                         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX7 txf = %1 nframes = %2\n", txf, nframes));
305                         return nframes;
306                 }
307
308                 ltc_buf_len = 0;
309                 ltc_buf_off = 0;
310
311                 // (6b)
312
313                 if (SIGNUM(ltc_speed) == -1) {
314                         ltc_enc_byte = (ltc_enc_byte + 9)%10;
315                         if (ltc_enc_byte == 9) {
316                                 ltc_encoder_dec_timecode(ltc_encoder);
317 #if 0 // this does not work for fractional or drop-frame TC
318                                 ltc_enc_pos -= frames_per_timecode_frame();
319 #else // TODO make this a function
320                                 SMPTETimecode enctc;
321                                 Timecode::Time a3tc;
322                                 ltc_encoder_get_timecode(ltc_encoder, &enctc);
323
324                                 a3tc.hours   = enctc.hours ;
325                                 a3tc.minutes = enctc.mins  ;
326                                 a3tc.seconds = enctc.secs  ;
327                                 a3tc.frames  = enctc.frame ;
328                                 a3tc.rate = timecode_to_frames_per_second(cur_timecode);
329                                 a3tc.drop = timecode_has_drop_frames(cur_timecode);
330
331                                 Timecode::timecode_to_sample (a3tc, ltc_enc_pos, true, false,
332                                         double(frame_rate()),
333                                         config.get_subframes_per_frame(),
334                                         config.get_timecode_offset_negative(), config.get_timecode_offset()
335                                         );
336 #endif
337                         }
338                 }
339
340                 if (ltc_encoder_encode_byte(ltc_encoder, ltc_enc_byte, (ltc_speed==0)?1.0:(1.0/ltc_speed))) {
341                         DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.3 encoder error byte %1\n", ltc_enc_byte));
342                         ltc_encoder_buffer_flush(ltc_encoder);
343                         ltc_tx_reset();
344                         memset(out, 0, nframes * sizeof(jack_default_audio_sample_t));
345                         return -1;
346                 }
347                 int enc_frames = ltc_encoder_get_buffer(ltc_encoder, &(ltc_enc_buf[ltc_buf_len]));
348 #ifdef LTC_GEN_FRAMEDBUG
349                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.3 encoded %1 bytes LTC-byte %2 at spd %3\n", enc_frames, ltc_enc_byte, ltc_speed));
350 #endif
351                 if (enc_frames <=0) {
352                         DEBUG_TRACE (DEBUG::LTC, "LTC TX6.3 encoder empty buffer.\n");
353                         ltc_encoder_buffer_flush(ltc_encoder);
354                         ltc_tx_reset();
355                         memset(out, 0, nframes * sizeof(jack_default_audio_sample_t));
356                         return -1;
357                 }
358
359                 ltc_buf_len += enc_frames;
360
361                 if (SIGNUM(ltc_speed) == 1) {
362                         ltc_enc_byte = (ltc_enc_byte + 1)%10;
363                         if (ltc_enc_byte == 0 && ltc_speed != 0) {
364                                 ltc_encoder_inc_timecode(ltc_encoder);
365 #if 0 // this does not work for fractional or drop-frame TC
366                                 ltc_enc_pos += frames_per_timecode_frame();
367 #else // TODO make this a function
368                                 SMPTETimecode enctc;
369                                 Timecode::Time a3tc;
370                                 ltc_encoder_get_timecode(ltc_encoder, &enctc);
371
372                                 a3tc.hours   = enctc.hours ;
373                                 a3tc.minutes = enctc.mins  ;
374                                 a3tc.seconds = enctc.secs  ;
375                                 a3tc.frames  = enctc.frame ;
376                                 a3tc.rate = timecode_to_frames_per_second(cur_timecode);
377                                 a3tc.drop = timecode_has_drop_frames(cur_timecode);
378
379                                 Timecode::timecode_to_sample (a3tc, ltc_enc_pos, true, false,
380                                         double(frame_rate()),
381                                         config.get_subframes_per_frame(),
382                                         config.get_timecode_offset_negative(), config.get_timecode_offset()
383                                         );
384 #endif
385                         }
386                 }
387 #ifdef LTC_GEN_FRAMEDBUG
388                 DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX6.4 fno: %1  [ %2 / %3 ] spd %4\n", ltc_enc_pos, ltc_buf_off, ltc_buf_len, ltc_speed));
389 #endif
390         }
391
392         return nframes;
393 }