diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/disk_reader.h | 26 | ||||
-rw-r--r-- | libs/ardour/audio_track_importer.cc | 2 | ||||
-rw-r--r-- | libs/ardour/disk_reader.cc | 67 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 6 | ||||
-rw-r--r-- | libs/ardour/srcfilesource.cc | 2 |
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))) |