}
}
-#ifdef XXX_OLD_DESTRUCTIVE_API_XXX
-int
-AudioTrack::set_mode (TrackMode m)
+MonitorState
+AudioTrack::get_auto_monitoring_state () const
{
- if (m != _mode) {
+ /* This is an implementation of the truth table in doc/monitor_modes.pdf;
+ I don't think it's ever going to be too pretty too look at.
+ */
- if (!Profile->get_trx() && _diskstream->set_destructive (m == Destructive)) {
- return -1;
- }
+ bool const roll = _session.transport_rolling ();
+ bool const track_rec = _disk_writer->record_enabled ();
+ bool const auto_input = _session.config.get_auto_input ();
+ bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
+ bool const tape_machine_mode = Config->get_tape_machine_mode ();
+ bool session_rec;
+
+ /* I suspect that just use actively_recording() is good enough all the
+ * time, but just to keep the semantics the same as they were before
+ * sept 26th 2012, we differentiate between the cases where punch is
+ * enabled and those where it is not.
+ *
+ * rg: sept 30 2017: Above is not the case: punch-in/out location is
+ * global session playhead position.
+ * When this method is called from process_output_buffers() we need
+ * to use delay-compensated route's process-position.
+ *
+ * NB. Disk reader/writer may also be offset by a same amount of time.
+ *
+ * Also keep in mind that _session.transport_rolling() is false during
+ * pre-roll but the disk already produces output.
+ *
+ * TODO: FIXME
+ */
+
+ if (_session.config.get_punch_in() || _session.config.get_punch_out()) {
+ session_rec = _session.actively_recording ();
+ } else {
+ session_rec = _session.get_record_enabled();
+ }
- _diskstream->set_non_layered (m == NonLayered);
- _mode = m;
+ if (track_rec) {
- TrackModeChanged (); /* EMIT SIGNAL */
- }
+ if (!session_rec && roll && auto_input) {
+ return MonitoringDisk;
+ } else {
+ return software_monitor ? MonitoringInput : MonitoringSilence;
+ }
- return 0;
-}
+ } else {
-bool
-AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
-{
- switch (m) {
- case NonLayered:
- case Normal:
- bounce_required = false;
- return true;
+ if (tape_machine_mode) {
+
+ return MonitoringDisk;
- case Destructive:
- if (Profile->get_trx()) {
- return false;
} else {
- return _diskstream->can_become_destructive (bounce_required);
- }
- break;
- default:
- return false;
+ if (!roll && auto_input) {
+ return software_monitor ? MonitoringInput : MonitoringSilence;
+ } else {
+ return MonitoringDisk;
+ }
+
+ }
}
+
+ abort(); /* NOTREACHED */
+ return MonitoringSilence;
}
-#endif
int
AudioTrack::set_state (const XMLNode& node, int version)
}
XMLNode&
-AudioTrack::state (bool full_state)
+AudioTrack::state (bool save_template)
{
- XMLNode& root (Track::state(full_state));
+ XMLNode& root (Track::state (save_template));
XMLNode* freeze_node;
if (_freeze_record.playlist) {
}
}
-/** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
- * or set to false.
- */
-int
-AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
-{
- Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
-
- if (!lm.locked()) {
- return 0;
- }
-
- if (n_outputs().n_total() == 0 && _processors.empty()) {
- return 0;
- }
-
- if (!_active) {
- silence (nframes);
- if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
- _meter->reset();
- }
- return 0;
- }
-
- _silent = false;
- _amp->apply_gain_automation(false);
-
- BufferSet& bufs = _session.get_route_buffers (n_process_buffers ());
-
- fill_buffers_with_input (bufs, _input, nframes);
-
- if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
- _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
- }
-
- process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!_disk_writer->record_enabled() && _session.transport_rolling()));
-
- if (_disk_reader->need_butler() || _disk_writer->need_butler()) {
- need_butler = true;
- }
-
- flush_processor_buffers_locked (nframes);
-
- return 0;
-}
-
int
-AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nframes,
+AudioTrack::export_stuff (BufferSet& buffers, samplepos_t start, samplecnt_t nframes,
boost::shared_ptr<Processor> endpoint, bool include_endpoint, bool for_export, bool for_freeze)
{
boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]);
assert(apl);
assert(buffers.count().n_audio() >= 1);
- assert ((framecnt_t) buffers.get_audio(0).capacity() >= nframes);
+ assert ((samplecnt_t) buffers.get_audio(0).capacity() >= nframes);
if (apl->read (buffers.get_audio(0).data(), mix_buffer.get(), gain_buffer.get(), start, nframes) != nframes) {
return -1;
boost::shared_ptr<Region>
AudioTrack::bounce (InterThreadInfo& itt)
{
- return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
+ return bounce_range (_session.current_start_sample(), _session.current_end_sample(), itt, main_outs(), false);
}
boost::shared_ptr<Region>
-AudioTrack::bounce_range (framepos_t start, framepos_t end, InterThreadInfo& itt,
+AudioTrack::bounce_range (samplepos_t start, samplepos_t end, InterThreadInfo& itt,
boost::shared_ptr<Processor> endpoint, bool include_endpoint)
{
vector<boost::shared_ptr<Source> > srcs;
boost::shared_ptr<Region> res;
- if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(),
+ if ((res = _session.write_one_track (*this, _session.current_start_sample(), _session.current_end_sample(),
true, srcs, itt, main_outs(), false, false, true)) == 0) {
return;
}
boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
new_playlist->set_orig_track_id (id());
- new_playlist->add_region (region, _session.current_start_frame());
+ new_playlist->add_region (region, _session.current_start_sample());
new_playlist->set_frozen (true);
region->set_locked (true);