diff options
author | Robin Gareus <robin@gareus.org> | 2017-01-17 20:43:55 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-01-17 20:43:55 +0100 |
commit | a6e02c0d71b67f3c571229c932dc20ee476df69b (patch) | |
tree | e92f501814d844e264164bfbb9fb0fbcad1f3a1e /libs/ardour | |
parent | fcbed9c1dcb8490d35eeb274d8ef417c15ee7deb (diff) |
Implement Count-In (before recording), fixed BPM, up to 2 bars
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/session.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session_configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/session.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 41 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 33 |
5 files changed, 77 insertions, 0 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index b62229a03c..f9172c5d6c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1898,6 +1898,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void click (framepos_t start, framecnt_t nframes); void run_click (framepos_t start, framecnt_t nframes); void add_click (framepos_t pos, bool emphasis); + framecnt_t _count_in_samples; std::vector<Route*> master_outs; diff --git a/libs/ardour/ardour/session_configuration_vars.h b/libs/ardour/ardour/session_configuration_vars.h index db789553cb..2f8d52b2b2 100644 --- a/libs/ardour/ardour/session_configuration_vars.h +++ b/libs/ardour/ardour/session_configuration_vars.h @@ -36,6 +36,7 @@ CONFIG_VARIABLE (bool, auto_return, "auto-return", false) CONFIG_VARIABLE (bool, auto_input, "auto-input", true) CONFIG_VARIABLE (bool, punch_in, "punch-in", false) CONFIG_VARIABLE (bool, punch_out, "punch-out", false) +CONFIG_VARIABLE (bool, count_in, "count-in", false) CONFIG_VARIABLE (MonitorChoice, session_monitoring, "session-monitoring", MonitorAuto) CONFIG_VARIABLE (bool, layered_record_mode, "layered-record-mode", false) CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100) diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index f16324dca8..34e4c52e9f 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -300,6 +300,7 @@ Session::Session (AudioEngine &eng, , click_length (0) , click_emphasis_length (0) , _clicks_cleared (0) + , _count_in_samples (0) , _play_range (false) , _range_selection (-1,-1) , _object_selection (-1,-1) diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index ad6ed1c16a..9be7007d19 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -314,6 +314,47 @@ Session::process_with_events (pframes_t nframes) process_event (ev); } + /* count in */ + if (_transport_speed != 1.0 && _count_in_samples > 0) { + _count_in_samples = 0; + } + + if (_count_in_samples > 0) { + framecnt_t ns = std::min ((framecnt_t)nframes, _count_in_samples); + + no_roll (ns); + run_click (_transport_frame - _count_in_samples, ns); + + _count_in_samples -= ns; + nframes -= ns; + + /* process events.. */ + if (!events.empty() && next_event != events.end()) { + SessionEvent* this_event = *next_event; + Events::iterator the_next_one = next_event; + ++the_next_one; + + while (this_event && this_event->action_frame == _transport_frame) { + process_event (this_event); + if (the_next_one == events.end()) { + this_event = 0; + } else { + this_event = *the_next_one; + ++the_next_one; + } + } + set_next_event (); + } + + check_declick_out (); + + if (nframes == 0) { + return; + } else { + _engine.split_cycle (ns); + } + } + /* Decide on what to do with quarter-frame MTC during this cycle */ bool const was_sending_qf_mtc = _send_qf_mtc; diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 5f1384d292..a6d25f05ab 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -45,6 +45,7 @@ #include "ardour/scene_changer.h" #include "ardour/session.h" #include "ardour/slave.h" +#include "ardour/tempo.h" #include "ardour/operations.h" #include "pbd/i18n.h" @@ -1616,6 +1617,38 @@ Session::start_transport () if (!dynamic_cast<MTC_Slave*>(_slave)) { send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay)); } + + if (actively_recording() && click_data && config.get_count_in ()) { + /* 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); + + _count_in_samples = meter.frames_per_bar (tempo, _current_frame_rate); + + double dt = _count_in_samples / div; + if (beats_left == 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; + } + + int clickbeat = 0; + framepos_t cf = _transport_frame - _count_in_samples; + while (cf < _transport_frame) { + add_click (cf - _worst_track_latency, clickbeat == 0); + cf += dt; + clickbeat = fmod (clickbeat + 1, div); + } + } } DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed)); |