X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftrack.cc;h=2d46c601321857f4b93e3c28e9b72849c34e1638;hb=8367b7cab344e75908744a95fda860c7fadff420;hp=c6a348ddfb1c4d7963b9a29239672f7323d76129;hpb=ec63180ef6c82e25b22a845cc4b99010d81cfc98;p=ardour.git diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index c6a348ddfb..2d46c60132 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -68,8 +68,10 @@ Track::init () /* don't add rec_enable_control to controls because we don't want it to * appear as an automatable parameter */ + track_number_changed.connect_same_thread (*this, boost::bind (&Track::resync_track_name, this)); + _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1)); - return 0; + return 0; } void @@ -176,7 +178,11 @@ Track::freeze_state() const } Track::RecEnableControl::RecEnableControl (boost::shared_ptr t) - : AutomationControl (t->session(), RecEnableAutomation, boost::shared_ptr(), X_("recenable")) + : AutomationControl (t->session(), + RecEnableAutomation, + ParameterDescriptor(Evoral::Parameter(RecEnableAutomation)), + boost::shared_ptr(), + X_("recenable")) , track (t) { boost::shared_ptr gl(new AutomationList(Evoral::Parameter(RecEnableAutomation))); @@ -226,6 +232,10 @@ Track::can_record() void Track::prep_record_enabled (bool yn, void *src) { + if (yn && record_safe ()) { + return; + } + if (!_session.writable()) { return; } @@ -266,6 +276,10 @@ Track::prep_record_enabled (bool yn, void *src) void Track::set_record_enabled (bool yn, void *src) { + if (_diskstream->record_safe ()) { + return; + } + if (!_session.writable()) { return; } @@ -284,6 +298,53 @@ Track::set_record_enabled (bool yn, void *src) _rec_enable_control->Changed (); } +bool +Track::record_safe () const +{ + return _diskstream && _diskstream->record_safe (); +} + +void +Track::set_record_safe (bool yn, void *src) +{ + if (!_session.writable()) { /* REQUIRES REVIEW */ + return; + } + + if (_freeze_record.state == Frozen) { /* REQUIRES REVIEW */ + return; + } + + if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) { + _route_group->apply (&Track::set_record_safe, yn, _route_group); + return; + } + + _diskstream->set_record_safe (yn); +} + +void +Track::parameter_changed (string const & p) +{ + if (p == "track-name-number") { + resync_track_name (); + } + else if (p == "track-name-take") { + resync_track_name (); + } + else if (p == "take-name") { + if (_session.config.get_track_name_take()) { + resync_track_name (); + } + } +} + +void +Track::resync_track_name () +{ + set_name(name()); +} + bool Track::set_name (const string& str) { @@ -294,6 +355,29 @@ Track::set_name (const string& str) return false; } + string diskstream_name = ""; + if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) { + // Note: any text is fine, legalize_for_path() fixes this later + diskstream_name += _session.config.get_take_name (); + diskstream_name += "_"; + } + const int64_t tracknumber = track_number(); + if (tracknumber > 0 && _session.config.get_track_name_number()) { + char num[64], fmt[10]; + snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals()); + snprintf(num, sizeof(num), fmt, tracknumber); + diskstream_name += num; + diskstream_name += "_"; + } + diskstream_name += str; + + if (diskstream_name == _diskstream_name) { + return true; + } + _diskstream_name = diskstream_name; + + _diskstream->set_write_source_name (diskstream_name); + boost::shared_ptr me = boost::dynamic_pointer_cast (shared_from_this ()); if (_diskstream->playlist()->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) { /* Only rename the diskstream (and therefore the playlist) if @@ -372,35 +456,30 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool be_silent; - if (_have_internal_generator) { - /* since the instrument has no input streams, - there is no reason to send any signal - into the route. - */ + 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; - - } else { - - 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: - /* if there is an instrument, be_silent should always - be false - */ - be_silent = (the_instrument_unlocked() == 0); - break; - case MonitoringDisk: - be_silent = true; - break; - case MonitoringInput: - be_silent = false; - break; - } + 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; + } + _amp->apply_gain_automation (false); /* if have_internal_generator, or .. */ @@ -436,7 +515,8 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, } if (no_meter) { - _meter->reset(); + BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); + _meter->run (bufs, 0, 0, nframes, true); _input->process_input (boost::shared_ptr(), start_frame, end_frame, nframes); } else { _input->process_input (_meter, start_frame, end_frame, nframes); @@ -447,7 +527,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, } else { - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -473,6 +553,10 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /* { Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { + framecnt_t playback_distance = _diskstream->calculate_playback_distance(nframes); + if (can_internal_playback_seek(playback_distance)) { + internal_playback_seek(playback_distance); + } return 0; } @@ -492,7 +576,7 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /* framecnt_t playback_distance; - BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); + BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true)); int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false); need_butler = _diskstream->commit (playback_distance); @@ -507,6 +591,7 @@ Track::set_diskstream (boost::shared_ptr ds) ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this)); diskstream_playlist_changed (); ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this)); + ds->RecordSafeChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_safe_changed, this)); ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this)); ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this)); } @@ -523,6 +608,12 @@ Track::diskstream_record_enable_changed () RecordEnableChanged (); /* EMIT SIGNAL */ } +void +Track::diskstream_record_safe_changed () +{ + RecordSafeChanged (); /* EMIT SIGNAL */ +} + void Track::diskstream_speed_changed () { @@ -542,15 +633,15 @@ Track::playlist () } void -Track::request_jack_monitors_input (bool m) +Track::request_input_monitoring (bool m) { - _diskstream->request_jack_monitors_input (m); + _diskstream->request_input_monitoring (m); } void -Track::ensure_jack_monitors_input (bool m) +Track::ensure_input_monitoring (bool m) { - _diskstream->ensure_jack_monitors_input (m); + _diskstream->ensure_input_monitoring (m); } bool @@ -571,10 +662,10 @@ Track::set_capture_offset () _diskstream->set_capture_offset (); } -list > -Track::steal_write_sources() +std::string +Track::steal_write_source_name() { - return _diskstream->steal_write_sources (); + return _diskstream->steal_write_source_name (); } void @@ -711,9 +802,9 @@ Track::speed () const } void -Track::prepare_to_stop (framepos_t p) +Track::prepare_to_stop (framepos_t t, framepos_t a) { - _diskstream->prepare_to_stop (p); + _diskstream->prepare_to_stop (t, a); } void @@ -839,6 +930,65 @@ Track::adjust_capture_buffering () } } +#ifdef USE_TRACKS_CODE_FEATURES + +/* This is the Tracks version of Track::monitoring_state(). + * + * Ardour developers: try to flag or fix issues if parts of the libardour API + * change in ways that invalidate this + */ + +MonitorState +Track::monitoring_state () const +{ + /* Explicit requests */ + + if (_monitoring & MonitorInput) { + return MonitoringInput; + } + + if (_monitoring & MonitorDisk) { + return MonitoringDisk; + } + + /* 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. + */ + + // GZ: NOT USED IN TRACKS + //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 const roll = _session.transport_rolling (); + bool const track_rec = _diskstream->record_enabled (); + bool session_rec = _session.actively_recording (); + + if (track_rec) { + + if (!session_rec && roll) { + return MonitoringDisk; + } else { + return MonitoringInput; + } + + } else { + + if (roll) { + return MonitoringDisk; + } + } + + return MonitoringSilence; +} + +#else + +/* This is the Ardour/Mixbus version of Track::monitoring_state(). + * + * Tracks developers: do NOT modify this method under any circumstances. + */ + MonitorState Track::monitoring_state () const { @@ -900,10 +1050,12 @@ Track::monitoring_state () const } } - /* NOTREACHED */ + abort(); /* NOTREACHED */ return MonitoringSilence; } +#endif + void Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick) {