diff options
author | Robin Gareus <robin@gareus.org> | 2020-04-14 03:57:26 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2020-04-14 03:57:26 +0200 |
commit | ea2bda666813ed7b8963ee2884f7a496b8284b08 (patch) | |
tree | b6bddc9e65df364163f86e7390c981dc6c6c1d8e /libs | |
parent | d5f25f998bb5a5cb8aefbba8679e63ffa0062d55 (diff) |
Fix playback alignment when adding/removing channels
The disk-reader assumes that all playback ringbuffers are in sync
and have the same fill_level.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/disk_io.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/disk_reader.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/disk_writer.h | 2 | ||||
-rw-r--r-- | libs/ardour/disk_io.cc | 2 | ||||
-rw-r--r-- | libs/ardour/disk_reader.cc | 24 | ||||
-rw-r--r-- | libs/ardour/disk_writer.cc | 8 | ||||
-rw-r--r-- | libs/pbd/pbd/playback_buffer.h | 12 |
7 files changed, 48 insertions, 3 deletions
diff --git a/libs/ardour/ardour/disk_io.h b/libs/ardour/ardour/disk_io.h index 83e5dd3f9b..39c8b16ec4 100644 --- a/libs/ardour/ardour/disk_io.h +++ b/libs/ardour/ardour/disk_io.h @@ -113,6 +113,7 @@ public: protected: friend class Auditioner; virtual int seek (samplepos_t which_sample, bool complete_refill = false) = 0; + virtual void configuration_changed () = 0; protected: Flag _flags; diff --git a/libs/ardour/ardour/disk_reader.h b/libs/ardour/ardour/disk_reader.h index 2e1ab6aec6..9db4266daa 100644 --- a/libs/ardour/ardour/disk_reader.h +++ b/libs/ardour/ardour/disk_reader.h @@ -223,6 +223,8 @@ private: void get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet&, double speed, samplecnt_t distance); void maybe_xfade_loop (Sample*, samplepos_t read_start, samplepos_t read_end, ReaderChannelInfo*); + void configuration_changed (); + bool overwrite_existing_audio (); bool overwrite_existing_midi (); }; diff --git a/libs/ardour/ardour/disk_writer.h b/libs/ardour/ardour/disk_writer.h index 31a64cd0e8..2bd753a006 100644 --- a/libs/ardour/ardour/disk_writer.h +++ b/libs/ardour/ardour/disk_writer.h @@ -145,6 +145,8 @@ protected: int do_flush (RunContext context, bool force = false); + void configuration_changed (); + private: static samplecnt_t _chunk_samples; diff --git a/libs/ardour/disk_io.cc b/libs/ardour/disk_io.cc index 49e0ef1297..b6badf8c0d 100644 --- a/libs/ardour/disk_io.cc +++ b/libs/ardour/disk_io.cc @@ -193,7 +193,7 @@ DiskIOProcessor::configure_io (ChanCount in, ChanCount out) } if (changed) { - seek (_session.transport_sample()); + configuration_changed (); } return Processor::configure_io (in, out); diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index 666f8a1e6a..4e687c7962 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -507,6 +507,12 @@ DiskReader::declick_in_progress () const return (_declick_amp.gain () != 0); // declick-out } +void +DiskReader::configuration_changed () +{ + _session.request_overwrite_buffer (_track, LoopDisabled); +} + bool DiskReader::pending_overwrite () const { @@ -521,6 +527,24 @@ DiskReader::set_pending_overwrite (OverwriteReason why) /* called from audio thread, so we can use the read ptr and playback sample as we wish */ if (!c->empty ()) { + + if (c->size () > 1) { + /* Align newly added buffers. + * + * overwrite_sample and file_sample[] are are maintained + * per DiskReader, not per channel. + * ::refill_audio() and ::overwrite_existing_audio() expect + * that read-pointers and fill_level of all buffers are in sync. + */ + ChannelList::iterator chan = c->begin (); + for (++chan; chan != c->end (); ++chan) { + ReaderChannelInfo* chaninfo = dynamic_cast<ReaderChannelInfo*> (*chan); + if (!chaninfo->initialized) { + (*chan)->rbuf->align_to (*(c->front ()->rbuf)); + } + } + } + const samplecnt_t reserved_size = c->front ()->rbuf->reserved_size (); const samplecnt_t bufsize = c->front ()->rbuf->bufsize (); diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc index d61d0f23f7..51588b844a 100644 --- a/libs/ardour/disk_writer.cc +++ b/libs/ardour/disk_writer.cc @@ -798,8 +798,14 @@ DiskWriter::set_note_mode (NoteMode m) _midi_write_source->model()->set_note_mode(m); } +void +DiskWriter::configuration_changed () +{ + seek (_session.transport_sample(), false); +} + int -DiskWriter::seek (samplepos_t sample, bool complete_refill) +DiskWriter::seek (samplepos_t sample, bool /*complete_refill*/) { uint32_t n; ChannelList::iterator chan; diff --git a/libs/pbd/pbd/playback_buffer.h b/libs/pbd/pbd/playback_buffer.h index 4b0b900217..75a30bc86f 100644 --- a/libs/pbd/pbd/playback_buffer.h +++ b/libs/pbd/pbd/playback_buffer.h @@ -65,10 +65,20 @@ public: /* writer, when seeking, may block */ Glib::Threads::Mutex::Lock lm (_reset_lock); SpinLock sl (_reservation_lock); - g_atomic_int_set (&write_idx, g_atomic_int_get (&read_idx)); + g_atomic_int_set (&read_idx, 0); + g_atomic_int_set (&write_idx, 0); g_atomic_int_set (&reserved, 0); } + /* called from rt (reader) thread for new buffers */ + void align_to (PlaybackBuffer const& other) { + Glib::Threads::Mutex::Lock lm (_reset_lock); + write_idx = other.write_idx; + read_idx = other.read_idx; + reserved = other.reserved; + memset (buf, 0, size * sizeof (T)); + } + /* write-thread */ guint write_space () const { guint w, r; |