mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-05 05:05:43 +01:00
fix error when continuing to refill audio playback buffers after a buffer switch
The file_sample[AUDIO] member was not updated to reflect the last-read sample in the switched-to buffer. Also move several methods and members from DiskIO to DiskReader where they belong.
This commit is contained in:
parent
b1b29a6317
commit
cf7bfae926
4 changed files with 50 additions and 49 deletions
|
|
@ -111,10 +111,6 @@ public:
|
|||
|
||||
virtual void adjust_buffering() = 0;
|
||||
|
||||
Glib::Threads::Mutex rbuf_lock;
|
||||
void queue_switch_rbuf ();
|
||||
void switch_rbufs ();
|
||||
|
||||
protected:
|
||||
friend class Auditioner;
|
||||
virtual int seek (samplepos_t which_sample, bool complete_refill = false) = 0;
|
||||
|
|
@ -147,10 +143,6 @@ protected:
|
|||
samplepos_t capture_val; ///< The start or end file sample position
|
||||
};
|
||||
|
||||
bool _switch_rbuf;
|
||||
int process_rbuf;
|
||||
int other_rbuf;
|
||||
|
||||
/** Information about one audio channel, playback or capture
|
||||
* (depending on the derived class)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ public:
|
|||
static void reset_loop_declick (Location*, samplecnt_t sample_rate);
|
||||
static void alloc_loop_declick (samplecnt_t sample_rate);
|
||||
|
||||
Glib::Threads::Mutex rbuf_lock;
|
||||
void queue_switch_rbuf ();
|
||||
void switch_rbufs ();
|
||||
|
||||
protected:
|
||||
friend class Track;
|
||||
friend class MidiTrack;
|
||||
|
|
@ -182,10 +186,11 @@ protected:
|
|||
};
|
||||
|
||||
private:
|
||||
/** The number of samples by which this diskstream's output should be delayed
|
||||
with respect to the transport sample. This is used for latency compensation.
|
||||
*/
|
||||
bool _switch_rbuf;
|
||||
int process_rbuf;
|
||||
int other_rbuf;
|
||||
samplepos_t overwrite_sample;
|
||||
samplepos_t new_file_sample;
|
||||
mutable gint _pending_overwrite;
|
||||
bool overwrite_queued;
|
||||
bool run_must_resolve;
|
||||
|
|
@ -228,6 +233,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*);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -55,9 +55,6 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
|
|||
, in_set_state (false)
|
||||
, playback_sample (0)
|
||||
, _need_butler (false)
|
||||
, _switch_rbuf (false)
|
||||
, process_rbuf (0)
|
||||
, other_rbuf (1)
|
||||
, channels (new ChannelList)
|
||||
, _midi_buf (0)
|
||||
, _samples_written_to_ringbuffer (0)
|
||||
|
|
@ -347,32 +344,6 @@ DiskIOProcessor::ChannelInfo::~ChannelInfo ()
|
|||
capture_transition_buf = 0;
|
||||
}
|
||||
|
||||
void
|
||||
DiskIOProcessor::queue_switch_rbuf ()
|
||||
{
|
||||
/* must hold _rbuf_lock */
|
||||
_switch_rbuf = true;
|
||||
}
|
||||
|
||||
void
|
||||
DiskIOProcessor::switch_rbufs ()
|
||||
{
|
||||
/* must hold _rbuf_lock */
|
||||
assert (_switch_rbuf);
|
||||
|
||||
std::swap (process_rbuf, other_rbuf);
|
||||
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
|
||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
||||
(*chan)->rbuf[other_rbuf]->reset ();
|
||||
cerr << name() << " after switch/reset, other has " << (*chan)->rbuf[other_rbuf]->write_space() << " of " << (*chan)->rbuf[other_rbuf]->bufsize() << endl;
|
||||
}
|
||||
|
||||
_switch_rbuf = false;
|
||||
cerr << "switched, pbuf now " << process_rbuf << " size " << c->front()->rbuf[process_rbuf]->bufsize() << " other " << other_rbuf << " size " << c->front()->rbuf[other_rbuf]->bufsize() << endl;
|
||||
}
|
||||
|
||||
void
|
||||
DiskIOProcessor::drop_track ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ samplecnt_t DiskReader::loop_fade_length (0);
|
|||
|
||||
DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
|
||||
: DiskIOProcessor (s, str, f)
|
||||
, _switch_rbuf (false)
|
||||
, process_rbuf (0)
|
||||
, other_rbuf (1)
|
||||
, overwrite_sample (0)
|
||||
, overwrite_queued (false)
|
||||
, run_must_resolve (false)
|
||||
|
|
@ -349,6 +352,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||
|
||||
if (!still_locating || _no_disk_output) {
|
||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
||||
assert ((*chan)->rbuf[process_rbuf]);
|
||||
(*chan)->rbuf[process_rbuf]->increment_read_ptr (disk_samples_to_consume);
|
||||
}
|
||||
}
|
||||
|
|
@ -573,29 +577,27 @@ DiskReader::overwrite_existing_buffers ()
|
|||
boost::scoped_array<Sample> mixdown_buffer (new Sample[size]);
|
||||
boost::scoped_array<float> gain_buffer (new float[size]);
|
||||
|
||||
/* reduce size so that we can fill the buffer correctly (ringbuffers
|
||||
* can only handle size-1, otherwise they appear to be empty)
|
||||
*/
|
||||
size--;
|
||||
|
||||
uint32_t n=0;
|
||||
samplecnt_t to_read = c->front()->rbuf[other_rbuf]->write_space();
|
||||
uint32_t n = 0;
|
||||
|
||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) {
|
||||
|
||||
samplepos_t start = overwrite_sample;
|
||||
samplecnt_t to_read = size;
|
||||
|
||||
ReaderChannelInfo* rci = dynamic_cast<ReaderChannelInfo*> (*chan);
|
||||
|
||||
PlaybackBuffer<Sample>* rbuf = (*chan)->rbuf[other_rbuf];
|
||||
|
||||
cerr << name() << ' ' << n << " overwrite read into " << other_rbuf << " @ " << overwrite_sample << " tr " << to_read << " ws " << (*chan)->rbuf[other_rbuf]->write_space() << endl;
|
||||
|
||||
if (audio_read (rbuf, sum_buffer.get(), mixdown_buffer.get(), gain_buffer.get(), start, to_read, rci, n, reversed)) {
|
||||
error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), size, overwrite_sample) << endmsg;
|
||||
goto midi;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new_file_sample = overwrite_sample + to_read;
|
||||
|
||||
queue_switch_rbuf ();
|
||||
}
|
||||
|
||||
|
|
@ -850,7 +852,7 @@ DiskReader::audio_read (PBD::PlaybackBuffer<Sample>*rb,
|
|||
samplecnt_t written;
|
||||
|
||||
if ((written = rb->write (sum_buffer, this_read)) != this_read) {
|
||||
cerr << owner()->name() << " Ringbuffer Write overrun (tried " << this_read << " wrote " << written << ')' << endl;
|
||||
cerr << owner()->name() << " Ringbuffer Write overrun on (tried " << this_read << " wrote " << written << ')' << endl;
|
||||
}
|
||||
|
||||
cnt -= this_read;
|
||||
|
|
@ -1040,6 +1042,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai
|
|||
|
||||
if (to_read) {
|
||||
ReaderChannelInfo* rci = dynamic_cast<ReaderChannelInfo*> (chan);
|
||||
cerr << name() << ' ' << chan_n << " refill read into " << process_rbuf << " @ " << file_sample_tmp << " tr " << to_read << " ts was " << ts << "scnt " << samples_to_read << " ws " << chan->rbuf[process_rbuf]->write_space() << endl;
|
||||
if (audio_read (chan->rbuf[process_rbuf], sum_buffer, mixdown_buffer, gain_buffer, file_sample_tmp, to_read, rci, chan_n, reversed)) {
|
||||
error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), to_read, ffa) << endmsg;
|
||||
ret = -1;
|
||||
|
|
@ -1658,3 +1661,31 @@ DiskReader::reload_loop ()
|
|||
|
||||
}
|
||||
}
|
||||
void
|
||||
DiskReader::queue_switch_rbuf ()
|
||||
{
|
||||
/* must hold _rbuf_lock */
|
||||
_switch_rbuf = true;
|
||||
}
|
||||
|
||||
void
|
||||
DiskReader::switch_rbufs ()
|
||||
{
|
||||
/* must hold _rbuf_lock */
|
||||
assert (_switch_rbuf);
|
||||
|
||||
std::swap (process_rbuf, other_rbuf);
|
||||
|
||||
boost::shared_ptr<ChannelList> c = channels.reader();
|
||||
|
||||
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
|
||||
(*chan)->rbuf[other_rbuf]->reset ();
|
||||
cerr << name() << " after switch/reset, other has " << (*chan)->rbuf[other_rbuf]->write_space() << " of " << (*chan)->rbuf[other_rbuf]->bufsize() << endl;
|
||||
}
|
||||
|
||||
_switch_rbuf = false;
|
||||
file_sample[DataType::AUDIO] = new_file_sample;
|
||||
|
||||
cerr << "switched, pbuf now " << process_rbuf << " size " << c->front()->rbuf[process_rbuf]->bufsize() << " other " << other_rbuf << " size " << c->front()->rbuf[other_rbuf]->bufsize() << endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue