summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/disk_reader.h26
-rw-r--r--libs/ardour/audio_track_importer.cc2
-rw-r--r--libs/ardour/disk_reader.cc67
-rw-r--r--libs/ardour/session_process.cc6
-rw-r--r--libs/ardour/srcfilesource.cc2
5 files changed, 64 insertions, 39 deletions
diff --git a/libs/ardour/ardour/disk_reader.h b/libs/ardour/ardour/disk_reader.h
index c3b7ac0563..b0a6f47607 100644
--- a/libs/ardour/ardour/disk_reader.h
+++ b/libs/ardour/ardour/disk_reader.h
@@ -67,23 +67,17 @@ public:
void move_processor_automation (boost::weak_ptr<Processor>, std::list<Evoral::RangeMove<samplepos_t> > const &);
- /* called by the Butler in a non-realtime context as part of its
- * normal loop (not due to transport-mechanism requests like locate
+ /* called by the Butler in a non-realtime context as part of its normal
+ * buffer refill loop (not due to transport-mechanism requests like
+ * locate)
*/
- int do_refill () {
- return refill (_sum_buffer, _mixdown_buffer, _gain_buffer, 0);
- }
+ int do_refill ();
/** For contexts outside the normal butler refill loop (allocates temporary working buffers)
- *
- * This accessible method has a default argument; derived classes
- * must inherit the virtual method that we call which does NOT
- * have a default argument, to avoid complications with inheritance
*/
- int do_refill_with_alloc (bool partial_fill = true) {
- return _do_refill_with_alloc (partial_fill);
- }
+
+ int do_refill_with_alloc (bool partial_fill, bool reverse);
bool pending_overwrite () const;
@@ -195,9 +189,7 @@ private:
DeclickAmp _declick_amp;
sampleoffset_t _declick_offs;
MidiStateTracker _tracker;
- boost::optional<bool> _last_read_reversed;
-
- int _do_refill_with_alloc (bool partial_fill);
+ boost::optional<bool> _last_read_reversed;
static samplecnt_t _chunk_samples;
static gint _no_disk_output;
@@ -218,8 +210,8 @@ private:
static Sample* _mixdown_buffer;
static gain_t* _gain_buffer;
- int refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level);
- int refill_audio (Sample* sum_buffer, Sample *mixdown_buffer, float *gain_buffer, samplecnt_t fill_level);
+ int refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed);
+ int refill_audio (Sample* sum_buffer, Sample *mixdown_buffer, float *gain_buffer, samplecnt_t fill_level, bool reversed);
sampleoffset_t calculate_playback_distance (pframes_t);
diff --git a/libs/ardour/audio_track_importer.cc b/libs/ardour/audio_track_importer.cc
index 5e9d8e565c..2e15cb3cb8 100644
--- a/libs/ardour/audio_track_importer.cc
+++ b/libs/ardour/audio_track_importer.cc
@@ -299,7 +299,7 @@ AudioTrackImporter::_move ()
boost::shared_ptr<DiskReader> new_ds (new DiskReader (session, *ds_node));
new_ds->set_name (name);
- new_ds->do_refill_with_alloc ();
+ new_ds->do_refill_with_alloc (true, false);
new_ds->set_block_size (session.get_block_size ());
/* Import playlists */
diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc
index e1a46ae0ee..9d730e1a74 100644
--- a/libs/ardour/disk_reader.cc
+++ b/libs/ardour/disk_reader.cc
@@ -774,6 +774,7 @@ DiskReader::seek (samplepos_t sample, bool complete_refill)
for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
(*chan)->rbuf->reset ();
+ assert ((*chan)->rbuf->reserved_size() == 0);
}
/* move the intended read target, so that after the refill is done,
@@ -783,7 +784,18 @@ DiskReader::seek (samplepos_t sample, bool complete_refill)
samples.
*/
- const samplecnt_t shift = sample > c->front()->rbuf->reservation_size() ? c->front()->rbuf->reservation_size() : sample;
+ samplecnt_t shift = sample > c->front()->rbuf->reservation_size() ? c->front()->rbuf->reservation_size() : sample;
+
+ // shift = 0;
+
+ if (read_reversed) {
+ /* reading in reverse, so start at a later sample, and read
+ "backwards" from there.
+ */
+ shift = -shift;
+ }
+
+ /* start the read at an earlier position (or later if reversed) */
sample -= shift;
@@ -795,22 +807,37 @@ DiskReader::seek (samplepos_t sample, bool complete_refill)
/* call _do_refill() to refill the entire buffer, using
the largest reads possible.
*/
- while ((ret = do_refill_with_alloc (false)) > 0) ;
+ while ((ret = do_refill_with_alloc (false, read_reversed)) > 0) ;
} else {
/* call _do_refill() to refill just one chunk, and then
return.
*/
- ret = do_refill_with_alloc (true);
+ ret = do_refill_with_alloc (true, read_reversed);
}
- sample += shift;
+ if (shift) {
- playback_sample = sample;
- file_sample[DataType::AUDIO] = sample;
- file_sample[DataType::MIDI] = sample;
+ /* now tell everyone where we really are, leaving the
+ * "reserved" data represented by "shift" available in the
+ * buffer for backwards-internal-seek
+ */
- for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
- (*chan)->rbuf->increment_read_ptr (shift);
+ sample += shift;
+
+ playback_sample = sample;
+ file_sample[DataType::AUDIO] = sample;
+ file_sample[DataType::MIDI] = sample;
+
+ /* we always move the read-ptr forwards, since even when in
+ * reverse, the data is placed in the buffer in normal read
+ * (increment) order.
+ */
+
+ shift = abs (shift);
+
+ for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
+ (*chan)->rbuf->increment_read_ptr (shift);
+ }
}
return ret;
@@ -1001,7 +1028,14 @@ DiskReader::audio_read (Sample* sum_buffer,
}
int
-DiskReader::_do_refill_with_alloc (bool partial_fill)
+DiskReader::do_refill ()
+{
+ const bool reversed = !_session.transport_will_roll_forwards ();
+ return refill (_sum_buffer, _mixdown_buffer, _gain_buffer, 0, reversed);
+}
+
+int
+DiskReader::do_refill_with_alloc (bool partial_fill, bool reversed)
{
/* We limit disk reads to at most 4MB chunks, which with floating point
samples would be 1M samples. But we might use 16 or 14 bit samples,
@@ -1013,21 +1047,21 @@ DiskReader::_do_refill_with_alloc (bool partial_fill)
boost::scoped_array<Sample> mix_buf (new Sample[2*1048576]);
boost::scoped_array<float> gain_buf (new float[2*1048576]);
- return refill_audio (sum_buf.get(), mix_buf.get(), gain_buf.get(), (partial_fill ? _chunk_samples : 0));
+ return refill_audio (sum_buf.get(), mix_buf.get(), gain_buf.get(), (partial_fill ? _chunk_samples : 0), reversed);
}
int
-DiskReader::refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level)
+DiskReader::refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed)
{
/* NOTE: Audio refill MUST come first so that in contexts where ONLY it
is called, _last_read_reversed is set correctly.
*/
- if (refill_audio (sum_buffer, mixdown_buffer, gain_buffer, fill_level)) {
+ if (refill_audio (sum_buffer, mixdown_buffer, gain_buffer, fill_level, reversed)) {
return -1;
}
- if (rt_midibuffer() && (_session.transport_speed() < 0.0f) != rt_midibuffer()->reversed()) {
+ if (rt_midibuffer() && (reversed != rt_midibuffer()->reversed())) {
rt_midibuffer()->reverse ();
}
@@ -1045,7 +1079,7 @@ DiskReader::refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buff
*/
int
-DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level)
+DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level, bool reversed)
{
/* do not read from disk while session is marked as Loading, to avoid
useless redundant I/O.
@@ -1056,13 +1090,12 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai
}
int32_t ret = 0;
- bool const reversed = !_session.transport_will_roll_forwards ();
samplecnt_t zero_fill;
uint32_t chan_n;
ChannelList::iterator i;
boost::shared_ptr<ChannelList> c = channels.reader();
- _last_read_reversed = !_session.transport_will_roll_forwards ();
+ _last_read_reversed = reversed;
if (c->empty()) {
return 0;
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 9d55e8cc97..fef23107ca 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -481,7 +481,7 @@ Session::process_with_events (pframes_t nframes)
assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
samples_moved = (samplecnt_t) nframes * _transport_speed;
- DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
+ // DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
end_sample = _transport_sample + samples_moved;
@@ -642,12 +642,12 @@ Session::process_without_events (pframes_t nframes)
assert (_transport_speed == 0 || _transport_speed == 1.0 || _transport_speed == -1.0);
if (_transport_speed == 0) {
- DEBUG_TRACE (DEBUG::Transport, string_compose ("transport not moving @ %1\n", _transport_sample));
+ // DEBUG_TRACE (DEBUG::Transport, string_compose ("transport not moving @ %1\n", _transport_sample));
no_roll (nframes);
return;
} else {
samples_moved = (samplecnt_t) nframes * _transport_speed;
- DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
+ // DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed));
}
if (!_exporting && !timecode_transmission_suspended()) {
diff --git a/libs/ardour/srcfilesource.cc b/libs/ardour/srcfilesource.cc
index c466e09e48..ab7d3376d4 100644
--- a/libs/ardour/srcfilesource.cc
+++ b/libs/ardour/srcfilesource.cc
@@ -29,7 +29,7 @@
using namespace ARDOUR;
using namespace PBD;
-const uint32_t SrcFileSource::max_blocksize = 2097152U; /* see AudioDiskstream::_do_refill_with_alloc, max */
+const uint32_t SrcFileSource::max_blocksize = 2097152U; /* see AudioDiskstream::do_refill_with_alloc, max */
SrcFileSource::SrcFileSource (Session& s, boost::shared_ptr<AudioFileSource> src, SrcQuality srcq)
: Source(s, DataType::AUDIO, src->name(), Flag (src->flags() & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))