Fix playback alignment when adding/removing channels
The disk-reader assumes that all playback ringbuffers are in sync and have the same fill_level.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 ();
|
||||
};
|
||||
|
||||
@@ -145,6 +145,8 @@ protected:
|
||||
|
||||
int do_flush (RunContext context, bool force = false);
|
||||
|
||||
void configuration_changed ();
|
||||
|
||||
private:
|
||||
static samplecnt_t _chunk_samples;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user