From 5fa9f8b399726e248412ebcfdeb8ed751f5a48d4 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 30 Sep 2017 16:45:45 +0200 Subject: Towards fixing no_roll() Currently ::roll() may actually be a ::no_roll() under some circumstances. This can also happen during count-in: transport_stopped () == transport_rolling() and during latency-preroll: Global session-transport speed != 0, some tracks already roll, read data from disk and feed latent plugins. but other non-latent tracks or busses don't roll and still have to behave like the switch from no_roll() to roll() has not yet happened. This changes the game WRT to monitoring as well, previously, Route:roll() called Route::no_roll_unlocked () for conditions outlined above. Now Track::no_roll_unlocked is called and in some cases wrongly clears the buffers before the signal hits the disk-writer. (more work is needed related to 61f8e53b) On the upside this also fixes an issue with MidiTrack::no_roll not keeping a lock while pushing data into the step-edit-ringbuffer. This is also a step towards consolidating all entry points: ::roll(), ::no_roll(), ::silent_roll() in the Route class. --- libs/ardour/ardour/midi_track.h | 2 +- libs/ardour/ardour/route.h | 16 +++++++--------- libs/ardour/ardour/track.h | 3 +-- libs/ardour/midi_track.cc | 4 ++-- libs/ardour/route.cc | 17 ++++++++--------- libs/ardour/track.cc | 8 +------- 6 files changed, 20 insertions(+), 30 deletions(-) diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 8ed4dfc7b1..dfd5a42d13 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -150,7 +150,7 @@ private: void set_state_part_two (); void set_state_part_three (); - int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing); + int no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing); void push_midi_input_to_step_edit_ringbuffer (samplecnt_t nframes); void track_input_active (IOChange, void*); diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index c0f2048a18..5376635076 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -138,14 +138,11 @@ public: virtual void filter_input (BufferSet &) {} - virtual int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, - int declick, bool& need_butler); + int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler); - virtual int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, - bool state_changing); + int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing); - virtual int silent_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, - bool& need_butler); + int silent_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler); virtual bool can_record() { return false; } @@ -589,8 +586,8 @@ public: virtual void use_captured_sources (SourceList& srcs, CaptureInfos const &) {} - protected: - friend class Session; +protected: + friend class Session; void catch_up_on_solo_mute_override (); void set_listen (bool); @@ -598,6 +595,8 @@ public: void curve_reallocate (); virtual void set_block_size (pframes_t nframes); + virtual int no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing); + void fill_buffers_with_input (BufferSet& bufs, boost::shared_ptr io, pframes_t nframes); void passthru (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick, bool gain_automation_ok, bool run_disk_reader); @@ -747,7 +746,6 @@ private: void setup_invisible_processors (); - void no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample); pframes_t latency_preroll (pframes_t nframes, samplepos_t& start_sample, samplepos_t& end_sample); void reset_instrument_info (); diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index df40ac092f..c468f26035 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -65,8 +65,7 @@ class LIBARDOUR_API Track : public Route, public Recordable bool set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure); - virtual int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, - bool state_changing); + virtual int no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing); bool needs_butler() const { return _needs_butler; } diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index dc5f3f0a80..2e5fd2a0b4 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -318,9 +318,9 @@ MidiTrack::update_controls(const BufferSet& bufs) } int -MidiTrack::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing) +MidiTrack::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing) { - int ret = Track::no_roll (nframes, start_sample, end_sample, state_changing); + int ret = Track::no_roll_unlocked (nframes, start_sample, end_sample, state_changing); if (ret == 0 && _step_editing) { push_midi_input_to_step_edit_ringbuffer (nframes); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index f411631e9e..389809190a 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3656,6 +3656,12 @@ Route::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sam return 0; } + return no_roll_unlocked (nframes, start_sample, end_sample, session_state_changing); +} + +int +Route::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing) +{ if (!_active) { silence_unlocked (nframes); return 0; @@ -3676,14 +3682,6 @@ Route::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sam */ } - no_roll_unlocked (nframes, start_sample, end_sample); - - return 0; -} - -void -Route::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample) -{ BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -3698,6 +3696,7 @@ Route::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_ passthru (bufs, start_sample, end_sample, nframes, 0, true, false); flush_processor_buffers_locked (nframes); + return 0; } samplecnt_t @@ -3731,7 +3730,7 @@ Route::latency_preroll (pframes_t nframes, samplepos_t& start_sample, samplepos_ } if (latency_preroll > playback_latency ()) { - no_roll_unlocked (nframes, start_sample - latency_preroll, end_sample - latency_preroll); + no_roll_unlocked (nframes, start_sample - latency_preroll, end_sample - latency_preroll, false); return 0; } diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index f201abcb12..5aad8b9bcf 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -430,14 +430,8 @@ Track::set_name (const string& str) } int -Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing) +Track::no_roll_unlocked (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; - } - /* no outputs? nothing to do ... what happens if we have sends etc. ? */ if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) { -- cgit v1.2.3