#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
+#include "ardour/automation_watch.h"
#include "ardour/butler.h"
#include "ardour/click.h"
#include "ardour/debug.h"
set_requested_return_frame (rec_in);
}
+void
+Session::request_count_in_record ()
+{
+ if (actively_recording ()) {
+ return;
+ }
+ if (transport_rolling()) {
+ return;
+ }
+ maybe_enable_record ();
+ _count_in_once = true;
+ request_transport_speed (1.0, true);
+}
+
void
Session::request_play_loop (bool yn, bool change_transport_roll)
{
PositionChanged (_transport_frame); /* EMIT SIGNAL */
DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
TransportStateChange (); /* EMIT SIGNAL */
+ AutomationWatch::instance().transport_stop_automation_watches (_transport_frame);
/* and start it up again if relevant */
}
_last_roll_location = _last_roll_or_reversal_location = _transport_frame;
- Located (); /* EMIT SIGNAL */
+ if (!synced_to_engine () || _transport_frame == _engine.transport_frame ()) {
+ Located (); /* EMIT SIGNAL */
+ }
}
/** Set the transport speed.
take care of it.
*/
_play_range = false;
+ _count_in_once = false;
unset_play_loop ();
}
_engine.transport_stop ();
if (synced_to_engine()) {
_engine.transport_start ();
+ _count_in_once = false;
} else {
start_transport ();
}
void
Session::stop_transport (bool abort, bool clear_state)
{
+ _count_in_once = false;
if (_transport_speed == 0.0f) {
return;
}
send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
}
- if (actively_recording() && click_data && config.get_count_in ()) {
+ 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_frame
* - calc duration of 1 bar + time-to-beat before or at transport_frame
const Tempo& tempo = _tempo_map->tempo_at_frame (_transport_frame);
const Meter& meter = _tempo_map->meter_at_frame (_transport_frame);
- double div = meter.divisions_per_bar ();
- double pulses = _tempo_map->exact_qn_at_frame (_transport_frame, 0) * div / 4.0;
- double beats_left = fmod (pulses, div);
+ const double num = meter.divisions_per_bar ();
+ const double den = meter.note_divisor ();
+ const double barbeat = _tempo_map->exact_qn_at_frame (_transport_frame, 0) * den / (4. * num);
+ const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
_count_in_samples = meter.frames_per_bar (tempo, _current_frame_rate);
- double dt = _count_in_samples / div;
- if (beats_left == 0) {
+ 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 += meter.frames_per_grid (tempo, _current_frame_rate) * beats_left;
+ _count_in_samples *= 1. + bar_fract;
}
int clickbeat = 0;
while (cf < _transport_frame) {
add_click (cf - _worst_track_latency, clickbeat == 0);
cf += dt;
- clickbeat = fmod (clickbeat + 1, div);
+ clickbeat = fmod (clickbeat + 1, num);
}
}
}
if (ptw & PostTransportLocate) {
if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
+ _count_in_once = false;
start_transport ();
} else {
transport_sub_state = 0;