X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftrack.cc;h=f56554791506908a663ca9992e0c57460fcf71e5;hb=9775c5c9f1b81340f3177ede038f02faed71c887;hp=57891968b678bbafa7b56a6799d7acdf45daa0a6;hpb=c8a9b28d3bee57604c5f8e4241f6f3ea10402f2c;p=ardour.git diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 57891968b6..f565547915 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -20,6 +20,7 @@ #include "ardour/amp.h" #include "ardour/audioengine.h" #include "ardour/audiofilesource.h" +#include "ardour/audioplaylist.h" #include "ardour/audioregion.h" #include "ardour/debug.h" #include "ardour/delivery.h" @@ -28,6 +29,7 @@ #include "ardour/event_type_map.h" #include "ardour/io_processor.h" #include "ardour/meter.h" +#include "ardour/midi_playlist.h" #include "ardour/midi_region.h" #include "ardour/monitor_control.h" #include "ardour/playlist.h" @@ -54,12 +56,12 @@ using namespace PBD; Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type) : Route (sess, name, flag, default_type) - , _saved_meter_point (_meter_point) - , _mode (mode) + , _saved_meter_point (_meter_point) + , _mode (mode) , _alignment_choice (Automatic) { _freeze_record.state = NoFreeze; - _declickable = true; + _declickable = true; } @@ -81,29 +83,31 @@ Track::~Track () int Track::init () { - if (Route::init ()) { - return -1; - } + if (Route::init ()) { + return -1; + } - DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable; + DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable; - if (_mode == Destructive && !Profile->get_trx()) { - dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive); - } else if (_mode == NonLayered){ - dflags = DiskIOProcessor::Flag(dflags | DiskIOProcessor::NonLayered); - } + if (_mode == Destructive && !Profile->get_trx()) { + dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive); + } + + _disk_reader.reset (new DiskReader (_session, name(), dflags)); + _disk_reader->set_block_size (_session.get_block_size ()); + _disk_reader->set_route (boost::dynamic_pointer_cast (shared_from_this())); + _disk_reader->set_owner (this); - _disk_reader.reset (new DiskReader (_session, name(), dflags)); - _disk_reader->set_block_size (_session.get_block_size ()); - _disk_reader->set_route (boost::dynamic_pointer_cast (shared_from_this())); + _disk_writer.reset (new DiskWriter (_session, name(), dflags)); + _disk_writer->set_block_size (_session.get_block_size ()); + _disk_writer->set_route (boost::dynamic_pointer_cast (shared_from_this())); + _disk_writer->set_owner (this); - _disk_writer.reset (new DiskWriter (_session, name(), dflags)); - _disk_writer->set_block_size (_session.get_block_size ()); - _disk_writer->set_route (boost::dynamic_pointer_cast (shared_from_this())); + set_align_choice_from_io (); - use_new_playlist (data_type()); + use_new_playlist (data_type()); - boost::shared_ptr rp (boost::dynamic_pointer_cast (shared_from_this())); + boost::shared_ptr rp (boost::dynamic_pointer_cast (shared_from_this())); boost::shared_ptr rt = boost::dynamic_pointer_cast (rp); _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this)); @@ -117,13 +121,13 @@ Track::init () _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1)); - _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2)); - _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2)); - _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2)); + _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2)); + _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2)); + _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2)); - _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this)); + _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this)); - return 0; + return 0; } void @@ -170,22 +174,33 @@ Track::set_state (const XMLNode& node, int version) return -1; } - XMLNode* child; + if (version >= 3000 && version < 6000) { + if (XMLNode* ds_node = find_named_node (node, "Diskstream")) { + std::string name; + if (ds_node->get_property ("name", name)) { + + ds_node->set_property ("active", true); + + _disk_writer->set_state (*ds_node, version); + _disk_reader->set_state (*ds_node, version); + + AlignChoice ac; + if (ds_node->get_property (X_("capture-alignment"), ac)) { + set_align_choice (ac, true); + } - if (version >= 3000 && version < 4000) { - if ((child = find_named_node (node, X_("Diskstream"))) != 0) { - /* XXX if we remember anything from stored DiskStream - state (older Ardour versions) that is needed by a - DiskReader or DiskWriter, we should cook up a new - XMLNode here, populate it with that information - (child nodes, properties, etc.) and then call - ::set_state() on the writer/reader. - - But at present (June 2017), there's no such state. - */ + if (boost::shared_ptr pl = boost::dynamic_pointer_cast (_session.playlists->by_name (name))) { + use_playlist (DataType::AUDIO, pl); + } + + if (boost::shared_ptr pl = boost::dynamic_pointer_cast (_session.playlists->by_name (name))) { + use_playlist (DataType::MIDI, pl); + } + } } } + XMLNode* child; std::string playlist_id; if (node.get_property (X_("audio-playlist"), playlist_id)) { @@ -414,146 +429,6 @@ Track::set_name (const string& str) return ret; } -void -Track::set_latency_compensation (samplecnt_t longest_session_latency) -{ - Route::set_latency_compensation (longest_session_latency); - _disk_reader->set_roll_delay (_roll_delay); -} - -int -Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing) -{ - Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); - - if (!lm.locked()) { - return 0; - } - - bool can_record = _session.actively_recording (); - - /* no outputs? nothing to do ... what happens if we have sends etc. ? */ - - if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) { - //Note: Mixbus has its own output mechanism, so we should operate even if no explicit outputs are assigned - return 0; - } - - /* not active ... do the minimum possible by just outputting silence */ - - if (!_active) { - silence (nframes); - if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) { - _meter->reset(); - } - return 0; - } - - if (session_state_changing) { - if (_session.transport_speed() != 0.0f) { - /* we're rolling but some state is changing (e.g. our - disk reader contents) so we cannot use them. Be - silent till this is over. Don't declick. - - XXX note the absurdity of ::no_roll() being called when we ARE rolling! - */ - passthru_silence (start_sample, end_sample, nframes, 0); - return 0; - } - /* we're really not rolling, so we're either delivery silence or actually - monitoring, both of which are safe to do while session_state_changing is true. - */ - } - - _disk_writer->check_record_status (start_sample, can_record); - - bool be_silent; - - MonitorState const s = monitoring_state (); - /* we are not rolling, so be silent even if we are monitoring disk, as there - will be no disk data coming in. - */ - switch (s) { - case MonitoringSilence: - be_silent = true; - break; - case MonitoringDisk: - be_silent = true; - break; - case MonitoringInput: - be_silent = false; - break; - default: - be_silent = false; - break; - } - - //if we have an internal generator, let it play regardless of monitoring state - if (_have_internal_generator) { - be_silent = false; - } - - /* if have_internal_generator, or .. */ - - if (be_silent) { - - if (_meter_point == MeterInput) { - /* still need input monitoring and metering */ - - 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 no_meter = false; - - /* this needs a proper K-map - * and should be separated into a function similar to monitoring_state() - * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc - * - * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf - */ - if (!auto_input && !track_rec) { - no_meter=true; - } - else if (tape_machine_mode && !track_rec && auto_input) { - no_meter=true; - } - else if (!software_monitor && tape_machine_mode && !track_rec) { - no_meter=true; - } - else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) { - no_meter=true; - } - - if (no_meter) { - BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); - _meter->run (bufs, start_sample, end_sample, 1.0, nframes, true); - _input->process_input (boost::shared_ptr(), start_sample, end_sample, _session.transport_speed(), nframes); - } else { - _input->process_input (_meter, start_sample, end_sample, _session.transport_speed(), nframes); - } - } - - passthru_silence (start_sample, end_sample, nframes, 0); - - } else { - - BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); - - fill_buffers_with_input (bufs, _input, nframes); - - if (_meter_point == MeterInput) { - _meter->run (bufs, start_sample, end_sample, _session.transport_speed(), nframes, true); - } - - passthru (bufs, start_sample, end_sample, nframes, false, true); - } - - flush_processor_buffers_locked (nframes); - - return 0; -} - boost::shared_ptr Track::playlist () { @@ -588,18 +463,6 @@ Track::last_capture_sources () return _disk_writer->last_capture_sources (); } -void -Track::update_latency_information () -{ - Glib::Threads::RWLock::ReaderLock lr (_processor_lock); - samplecnt_t chain_latency = _input->latency (); - - for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) { - (*p)->set_input_latency (chain_latency); - chain_latency += (*p)->signal_latency (); - } -} - std::string Track::steal_write_source_name() { @@ -745,12 +608,6 @@ Track::pending_overwrite () const return _disk_reader->pending_overwrite (); } -void -Track::prepare_to_stop (samplepos_t t, samplepos_t a) -{ - _disk_writer->prepare_to_stop (t, a); -} - void Track::set_slaved (bool s) { @@ -779,7 +636,7 @@ Track::alignment_style () const AlignChoice Track::alignment_choice () const { - return _disk_writer->alignment_choice (); + return _alignment_choice; } samplepos_t @@ -832,6 +689,9 @@ Track::use_playlist (DataType dt, boost::shared_ptr p) _playlists[dt] = p; } + _session.set_dirty (); + PlaylistChanged (); /* EMIT SIGNAL */ + return ret; } @@ -883,17 +743,18 @@ Track::use_new_playlist (DataType dt) void Track::set_align_choice (AlignChoice ac, bool force) { + _alignment_choice = ac; switch (ac) { - case Automatic: - _alignment_choice = Automatic; - set_align_choice_from_io (); - return; - default: - break; + case Automatic: + set_align_choice_from_io (); + break; + case UseCaptureTime: + _disk_writer->set_align_style (CaptureTime, force); + break; + case UseExistingMaterial: + _disk_writer->set_align_style (ExistingMaterial, force); + break; } - - _disk_writer->set_align_choice (ac, force); - _alignment_choice = ac; } void @@ -1001,42 +862,6 @@ Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick) } } -samplecnt_t -Track::check_initial_delay (samplecnt_t nframes, samplepos_t& transport_sample) -{ - if (_roll_delay > nframes) { - - _roll_delay -= nframes; - silence_unlocked (nframes); - /* transport sample is not legal for caller to use */ - return 0; - - } else if (_roll_delay > 0) { - - nframes -= _roll_delay; - silence_unlocked (_roll_delay); - transport_sample += _roll_delay; - - /* shuffle all the port buffers for things that lead "out" of this Route - to reflect that we just wrote _roll_delay samples of silence. - */ - - Glib::Threads::RWLock::ReaderLock lm (_processor_lock); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr iop = boost::dynamic_pointer_cast (*i); - if (iop) { - iop->increment_port_buffer_offset (_roll_delay); - } - } - _output->increment_port_buffer_offset (_roll_delay); - - _roll_delay = 0; - - } - - return nframes; -} - void Track::monitoring_changed (bool, Controllable::GroupControlDisposition) { @@ -1210,9 +1035,9 @@ Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture continue; /* XXX is this OK? */ } - // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; + cerr << "add new region, len = " << (*ci)->samples << " @ " << (*ci)->start << endl; - pl->add_region (midi_region, (*ci)->start + preroll_off, _disk_writer->non_layered()); + pl->add_region (midi_region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode ()); } pl->thaw (); @@ -1314,7 +1139,7 @@ Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & captur continue; /* XXX is this OK? */ } - pl->add_region (region, (*ci)->start + preroll_off, 1, _disk_writer->non_layered()); + pl->add_region (region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode()); pl->set_layer (region, DBL_MAX); buffer_position += (*ci)->samples;