+
+ if (actively_recording() && click_data && (config.get_count_in () || _count_in_once)) {
+ _count_in_once = false;
+ /* calculate count-in duration (in audio samples)
+ * - use [fixed] tempo/meter at _transport_sample
+ * - calc duration of 1 bar + time-to-beat before or at transport_sample
+ */
+ const Tempo& tempo = _tempo_map->tempo_at_sample (_transport_sample);
+ const Meter& meter = _tempo_map->meter_at_sample (_transport_sample);
+
+ const double num = meter.divisions_per_bar ();
+ const double den = meter.note_divisor ();
+ const double barbeat = _tempo_map->exact_qn_at_sample (_transport_sample, 0) * den / (4. * num);
+ const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
+
+ _count_in_samples = meter.samples_per_bar (tempo, _current_sample_rate);
+
+ double dt = _count_in_samples / num;
+ if (bar_fract == 0) {
+ /* at bar boundary, count-in 2 bars before start. */
+ _count_in_samples *= 2;
+ } else {
+ /* beats left after full bar until roll position */
+ _count_in_samples *= 1. + bar_fract;
+ }
+
+ if (_count_in_samples > _remaining_latency_preroll) {
+ _remaining_latency_preroll = _count_in_samples;
+ }
+
+ int clickbeat = 0;
+ samplepos_t cf = _transport_sample - _count_in_samples;
+ samplecnt_t offset = _click_io->connected_latency (true);
+ while (cf < _transport_sample + offset) {
+ add_click (cf, clickbeat == 0);
+ cf += dt;
+ clickbeat = fmod (clickbeat + 1, num);
+ }
+
+ if (_count_in_samples < _remaining_latency_preroll) {
+ _count_in_samples = _remaining_latency_preroll;
+ }
+ }