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.
This commit is contained in:
Robin Gareus 2017-09-30 16:45:45 +02:00
parent 697d29cdc2
commit 5fa9f8b399
6 changed files with 20 additions and 30 deletions

View File

@ -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*);

View File

@ -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> 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 ();

View File

@ -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; }

View File

@ -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);

View File

@ -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;
}

View File

@ -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()) {