Implement Count-In (before recording), fixed BPM, up to 2 bars
This commit is contained in:
parent
fcbed9c1dc
commit
a6e02c0d71
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user