diff --git a/libs/ardour/ardour/disk_reader.h b/libs/ardour/ardour/disk_reader.h index 7ccfa0b3d9..a170fba766 100644 --- a/libs/ardour/ardour/disk_reader.h +++ b/libs/ardour/ardour/disk_reader.h @@ -84,8 +84,8 @@ public: void adjust_buffering (); - int can_internal_playback_seek (samplecnt_t distance); - int internal_playback_seek (samplecnt_t distance); + bool can_internal_playback_seek (sampleoffset_t distance); + void internal_playback_seek (sampleoffset_t distance); int seek (samplepos_t sample, bool complete_refill = false); static PBD::Signal0 Underrun; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index b6abece1f0..e9d9a60380 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -137,8 +137,8 @@ public: int do_flush (RunContext, bool force = false); void set_pending_overwrite (bool); int seek (samplepos_t, bool complete_refill = false); - int can_internal_playback_seek (samplecnt_t); - int internal_playback_seek (samplecnt_t); + bool can_internal_playback_seek (samplecnt_t); + void internal_playback_seek (samplecnt_t); void non_realtime_locate (samplepos_t); void realtime_handle_transport_stopped (); int overwrite_existing_buffers (); diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index c87f04daf2..973cd33e3c 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -623,8 +623,8 @@ DiskReader::seek (samplepos_t sample, bool complete_refill) return ret; } -int -DiskReader::can_internal_playback_seek (samplecnt_t distance) +bool +DiskReader::can_internal_playback_seek (sampleoffset_t distance) { /* 1. Audio */ @@ -632,11 +632,15 @@ DiskReader::can_internal_playback_seek (samplecnt_t distance) boost::shared_ptr c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->rbuf->read_space() < (size_t) distance) { + if (!(*chan)->rbuf->can_seek (distance)) { return false; } } + if (distance < 0) { + return true; // XXX TODO un-seek MIDI + } + /* 2. MIDI */ uint32_t samples_read = g_atomic_int_get(&_samples_read_from_ringbuffer); @@ -645,19 +649,26 @@ DiskReader::can_internal_playback_seek (samplecnt_t distance) return ((samples_written - samples_read) < distance); } -int -DiskReader::internal_playback_seek (samplecnt_t distance) +void +DiskReader::internal_playback_seek (sampleoffset_t distance) { - ChannelList::iterator chan; - boost::shared_ptr c = channels.reader(); - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->rbuf->increment_read_ptr (::llabs(distance)); + if (distance == 0) { + return; } - playback_sample += distance; + sampleoffset_t off = distance; - return 0; + ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); + for (chan = c->begin(); chan != c->end(); ++chan) { + if (distance < 0) { + off = 0 - (sampleoffset_t) (*chan)->rbuf->decrement_read_ptr (llabs (distance)); + } else { + off = (*chan)->rbuf->increment_read_ptr (distance); + } + } + + playback_sample += off; } static diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index d5902be50e..f4161ebb06 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -506,13 +506,13 @@ Track::seek (samplepos_t p, bool complete_refill) return _disk_writer->seek (p, complete_refill); } -int +bool Track::can_internal_playback_seek (samplecnt_t p) { return _disk_reader->can_internal_playback_seek (p); } -int +void Track::internal_playback_seek (samplecnt_t p) { return _disk_reader->internal_playback_seek (p);