process_event (ev);
}
- /* count in */
+ /* only count-in when going to roll at speed 1.0 */
if (_transport_speed != 1.0 && _count_in_samples > 0) {
_count_in_samples = 0;
}
+ if (_transport_speed == 0.0) {
+ _remaining_latency_preroll = 0;
+ }
- if (_count_in_samples > 0) {
- samplecnt_t ns = std::min ((samplecnt_t)nframes, _count_in_samples);
+ assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
- no_roll (ns);
- run_click (_transport_sample - _count_in_samples, ns);
+ while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
+ samplecnt_t ns;
+
+ if (_remaining_latency_preroll > 0) {
+ ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
+ } else {
+ ns = std::min ((samplecnt_t)nframes, _count_in_samples);
+ }
+
+ boost::shared_ptr<RouteList> r = routes.reader ();
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ samplecnt_t route_offset = (*i)->playback_latency ();
+ if (_remaining_latency_preroll > route_offset + ns) {
+ /* route will no-roll for complete pre-roll cycle */
+ continue;
+ }
+ if (_remaining_latency_preroll > route_offset) {
+ /* route may need partial no-roll and partial roll from
+ * (_transport_sample - _remaining_latency_preroll) .. +ns.
+ * shorten and split the cycle.
+ */
+ ns = std::min (ns, (_remaining_latency_preroll - route_offset));
+ }
+ }
+
+ if (_count_in_samples > 0) {
+ run_click (_transport_sample - _count_in_samples, ns);
+ assert (_count_in_samples >= ns);
+ _count_in_samples -= ns;
+ }
+
+ if (_remaining_latency_preroll > 0) {
+ if (_count_in_samples == 0) {
+ click (_transport_sample - _remaining_latency_preroll, ns);
+ }
+ if (process_routes (ns, session_needs_butler)) {
+ fail_roll (ns);
+ }
+ } else {
+ no_roll (ns);
+ }
+
+ if (_remaining_latency_preroll > 0) {
+ assert (_remaining_latency_preroll >= ns);
+ _remaining_latency_preroll -= ns;
+ }
- _count_in_samples -= ns;
nframes -= ns;
/* process events.. */
}
}
- if (_transport_speed == 1.0) {
- samples_moved = (samplecnt_t) nframes;
- } else {
- interpolation.set_target_speed (_target_transport_speed);
- interpolation.set_speed (_transport_speed);
- samples_moved = (samplecnt_t) interpolation.interpolate (0, nframes, 0, 0);
- }
+ assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
+
+ samples_moved = (samplecnt_t) nframes * _transport_speed;
end_sample = _transport_sample + samples_moved;
if (!_exporting && _slave) {
if (!follow_slave (nframes)) {
- cerr << "P-w-E: FS fail\n";
return;
}
}
if (_transport_speed == 0) {
- cerr << "P-w-E: ts = 0\n";
no_roll (nframes);
return;
}
samplepos_t stop_limit = compute_stop_limit ();
if (maybe_stop (stop_limit)) {
- cerr << "P-w-E: mebbe stop\n";
no_roll (nframes);
return;
}
click (_transport_sample, this_nframes);
if (process_routes (this_nframes, session_needs_butler)) {
- cerr << "P-w-E: PR fail\n";
fail_roll (nframes);
return;
}
increment_transport_position (samples_moved);
}
- cerr << "P-w-E: ts now = " << _transport_sample << endl;
-
maybe_stop (stop_limit);
check_declick_out ();
}
/* if an event left our state changing, do the right thing */
if (nframes && non_realtime_work_pending()) {
- cerr << "P-w-E: nrtwp no roll\n";
no_roll (nframes);
break;
}
} /* implicit release of route lock */
- cerr << "P-w-E: final ts = " << _transport_sample << endl;
-
if (session_needs_butler) {
DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
_butler->summon ();
if (_transport_speed == 1.0) {
samples_moved = (samplecnt_t) nframes;
} else {
- interpolation.set_target_speed (_target_transport_speed);
interpolation.set_speed (_transport_speed);
- samples_moved = (samplecnt_t) interpolation.interpolate (0, nframes, 0, 0);
+ samples_moved = interpolation.distance (nframes);
}
if (!_exporting && !timecode_transmission_suspended()) {
case SessionEvent::PunchIn:
// cerr << "PunchIN at " << transport_sample() << endl;
- if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
+ if (config.get_punch_in() && record_status() == Enabled) {
enable_record ();
}
remove = false;
case SessionEvent::PunchOut:
// cerr << "PunchOUT at " << transport_sample() << endl;
- if (config.get_punch_out() && !preroll_record_punch_enabled()) {
+ if (config.get_punch_out()) {
step_back_from_record ();
}
remove = false;
del = false;
break;
- case SessionEvent::RecordStart:
- if (preroll_record_punch_enabled() && record_status() == Enabled) {
- enable_record ();
- }
- remove = false;
- del = false;
- break;
-
case SessionEvent::StopOnce:
if (!non_realtime_work_pending()) {
_clear_event_type (SessionEvent::StopOnce);
return max_samplepos;
}
- if (preroll_record_punch_enabled ()) {
- return max_samplepos;
- }
-
bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());