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