Implement record with preroll

This commit is contained in:
Robin Gareus 2017-01-18 15:15:48 +01:00
parent cf31233cd1
commit efd10abdfb
8 changed files with 55 additions and 8 deletions

View File

@ -998,6 +998,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void maybe_update_session_range (framepos_t, framepos_t);
void request_preroll_record (framepos_t);
framepos_t preroll_record_in () const { return _preroll_record_in; }
bool preroll_record_enabled () const { return _preroll_record_in >= 0; }
/* temporary hacks to allow selection to be pushed from GUI into backend.
Whenever we move the selection object into libardour, these will go away.
*/
@ -1915,6 +1919,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
Evoral::Range<framepos_t> _range_selection;
Evoral::Range<framepos_t> _object_selection;
void unset_preroll_record ();
framepos_t _preroll_record_in;
/* main outs */
uint32_t main_outs;

View File

@ -47,6 +47,7 @@ public:
SetLoop,
PunchIn,
PunchOut,
RecordStart,
RangeStop,
RangeLocate,
Overwrite,

View File

@ -1923,7 +1923,9 @@ AudioDiskstream::get_state ()
Location* pi;
if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
if (_session.preroll_record_enabled ()) {
snprintf (buf, sizeof (buf), "%" PRId64, _session.preroll_record_in ());
} else if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
} else {
snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());

View File

@ -367,7 +367,7 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
adjust_capture_position = 0;
if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
if (nominally_recording || (re && was_recording && _session.get_record_enabled() && (_session.config.get_punch_in() || _session.preroll_record_enabled()))) {
Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
// XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
@ -1238,7 +1238,9 @@ MidiDiskstream::get_state ()
Location* pi;
if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
if (_session.preroll_record_enabled ()) {
snprintf (buf, sizeof (buf), "%" PRId64, _session.preroll_record_in ());
} else if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
} else {
snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());

View File

@ -304,6 +304,7 @@ Session::Session (AudioEngine &eng,
, _play_range (false)
, _range_selection (-1,-1)
, _object_selection (-1,-1)
, _preroll_record_in (-1)
, main_outs (0)
, first_file_data_format_reset (true)
, first_file_header_format_reset (true)
@ -781,6 +782,7 @@ Session::destroy ()
case SessionEvent::Skip:
case SessionEvent::PunchIn:
case SessionEvent::PunchOut:
case SessionEvent::RecordStart:
case SessionEvent::StopOnce:
case SessionEvent::RangeStop:
case SessionEvent::RangeLocate:
@ -1999,6 +2001,7 @@ Session::disable_record (bool rt_context, bool force)
if (!rt_context) {
remove_pending_capture_state ();
}
unset_preroll_record ();
}
}
@ -2036,7 +2039,7 @@ Session::maybe_enable_record (bool rt_context)
}
if (_transport_speed) {
if (!config.get_punch_in()) {
if (!config.get_punch_in() && !preroll_record_enabled ()) {
enable_record ();
}
} else {

View File

@ -1156,7 +1156,7 @@ Session::process_event (SessionEvent* ev)
case SessionEvent::PunchIn:
// cerr << "PunchIN at " << transport_frame() << endl;
if (config.get_punch_in() && record_status() == Enabled) {
if (config.get_punch_in() && record_status() == Enabled && !preroll_record_enabled()) {
enable_record ();
}
remove = false;
@ -1165,13 +1165,21 @@ Session::process_event (SessionEvent* ev)
case SessionEvent::PunchOut:
// cerr << "PunchOUT at " << transport_frame() << endl;
if (config.get_punch_out()) {
if (config.get_punch_out() && !preroll_record_enabled()) {
step_back_from_record ();
}
remove = false;
del = false;
break;
case SessionEvent::RecordStart:
if (preroll_record_enabled() && record_status() == Enabled) {
enable_record ();
}
remove = false;
del = false;
break;
case SessionEvent::StopOnce:
if (!non_realtime_work_pending()) {
_clear_event_type (SessionEvent::StopOnce);
@ -1271,6 +1279,9 @@ Session::compute_stop_limit () const
return max_framepos;
}
if (preroll_record_enabled ()) {
return max_framepos;
}
bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());

View File

@ -161,6 +161,27 @@ Session::force_locate (framepos_t target_frame, bool with_roll)
queue_event (ev);
}
void
Session::unset_preroll_record ()
{
if (_preroll_record_in >= 0) {
remove_event (_preroll_record_in, SessionEvent::RecordStart);
}
_preroll_record_in = -1;
}
void
Session::request_preroll_record (framepos_t rec_in)
{
unset_preroll_record ();
_preroll_record_in = rec_in;
if (_preroll_record_in >= 0) {
replace_event (SessionEvent::RecordStart, _preroll_record_in);
config.set_punch_in (false);
config.set_punch_out (false);
}
}
void
Session::request_play_loop (bool yn, bool change_transport_roll)
{
@ -1583,7 +1604,7 @@ Session::start_transport ()
switch (record_status()) {
case Enabled:
if (!config.get_punch_in()) {
if (!config.get_punch_in() && !preroll_record_enabled()) {
enable_record ();
}
break;

View File

@ -957,7 +957,7 @@ Track::monitoring_state () const
* enabled and those where it is not.
*/
if (_session.config.get_punch_in() || _session.config.get_punch_out()) {
if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_in () >= 0) {
session_rec = _session.actively_recording ();
} else {
session_rec = _session.get_record_enabled();