Move Loop Location to Processors
authorRobin Gareus <robin@gareus.org>
Tue, 31 Oct 2017 17:32:26 +0000 (18:32 +0100)
committerRobin Gareus <robin@gareus.org>
Tue, 31 Oct 2017 17:32:26 +0000 (18:32 +0100)
The processors will becomes responsible to know about loop-positions
and map latency-compensated start_sample, end_sample into the loop-range
as needed.

libs/ardour/ardour/disk_io.h
libs/ardour/ardour/processor.h
libs/ardour/ardour/route.h
libs/ardour/ardour/track.h
libs/ardour/disk_io.cc
libs/ardour/disk_reader.cc
libs/ardour/disk_writer.cc
libs/ardour/processor.cc
libs/ardour/route.cc
libs/ardour/session_transport.cc
libs/ardour/track.cc

index 74eede7644d03d4ac37b66f5aba8f357137abf39..3fae063c1ed7253c6696241fd35354217d7d073b 100644 (file)
@@ -89,9 +89,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
        bool slaved() const      { return _slaved; }
        void set_slaved(bool yn) { _slaved = yn; }
 
-       int set_loop (Location *loc);
-
-       PBD::Signal1<void,Location *> LoopSet;
        PBD::Signal0<void>            SpeedChanged;
        PBD::Signal0<void>            ReverseChanged;
 
@@ -122,7 +119,6 @@ class LIBARDOUR_API DiskIOProcessor : public Processor
        double       _target_speed;
        bool         _seek_required;
        bool         _slaved;
-       Location*     loop_location;
        bool          in_set_state;
        samplepos_t   playback_sample;
        bool         _need_butler;
index f3325a11944c9c01bdf13aed662d6200ffe260a4..139a5cf5922b6f290423b3f1d020e3efb3dd2e77 100644 (file)
@@ -40,6 +40,7 @@ class PluginPinWindowProxy;
 
 namespace ARDOUR {
 
+class Location;
 class Session;
 class Route;
 
@@ -108,6 +109,8 @@ class LIBARDOUR_API Processor : public SessionObject, public Automatable, public
        virtual void realtime_handle_transport_stopped () {}
        virtual void realtime_locate () {}
 
+       virtual void set_loop (Location *loc) { _loop_location = loc; }
+
        /* most processors won't care about this, but plugins that
           receive MIDI or similar data from an input source that
           may suddenly go "quiet" because of monitoring changes
@@ -167,6 +170,7 @@ protected:
        // absolute alignment to session i/o
        samplecnt_t _capture_offset;
        samplecnt_t _playback_offset;
+       Location*   _loop_location;
 };
 
 } // namespace ARDOUR
index f903a49bacae4c8d5cccc7318bb24e8a0cd9f1fc..ba262d61e810aa48e42fd30b4cbec4af6f2a74d9 100644 (file)
@@ -78,6 +78,7 @@ class PluginInsert;
 class RouteGroup;
 class Send;
 class InternalReturn;
+class Location;
 class MonitorControl;
 class MonitorProcessor;
 class Pannable;
@@ -152,6 +153,7 @@ public:
        virtual void realtime_locate () {}
        virtual void non_realtime_locate (samplepos_t);
        virtual void set_pending_declick (int);
+       int set_loop (ARDOUR::Location *);
 
        /* end of vfunc-based API */
 
@@ -672,6 +674,7 @@ protected:
        FedBy          _fed_by;
 
        InstrumentInfo _instrument_info;
+       Location*      _loop_location;
 
        virtual ChanCount input_streams () const;
 
index 6b024274f0fe1f258f429f2ffffb04f19ae23ecb..7703221bd44d785b94bb74f4726781baa2490511 100644 (file)
@@ -37,7 +37,6 @@ class Region;
 class DiskReader;
 class DiskWriter;
 class IO;
-class Location;
 class RecordEnableControl;
 class RecordSafeControl;
 
@@ -144,7 +143,6 @@ public:
        void non_realtime_speed_change ();
        int overwrite_existing_buffers ();
        samplecnt_t get_captured_samples (uint32_t n = 0) const;
-       int set_loop (ARDOUR::Location *);
        void transport_looped (samplepos_t);
        void transport_stopped_wallclock (struct tm &, time_t, bool);
        bool pending_overwrite () const;
index 1872c81ea9f3a67096534d09eca578b99be201cd..c43e42c315d3478d241ce7c7cc2189396001fcf1 100644 (file)
@@ -52,7 +52,6 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
        , i_am_the_modifier (false)
        , _seek_required (false)
        , _slaved (false)
-       , loop_location (0)
        , in_set_state (false)
        , playback_sample (0)
        , _need_butler (false)
@@ -182,22 +181,6 @@ DiskIOProcessor::set_block_size (pframes_t nframes)
        return 0;
 }
 
-int
-DiskIOProcessor::set_loop (Location *location)
-{
-       if (location) {
-               if (location->start() >= location->end()) {
-                       error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
-                       return -1;
-               }
-       }
-
-       loop_location = location;
-
-       LoopSet (location); /* EMIT SIGNAL */
-       return 0;
-}
-
 void
 DiskIOProcessor::non_realtime_locate (samplepos_t location)
 {
index 55180ad1bdd546aeee3049306b75ae9e32080bba..4896a95af2af8943a2d271e8507035f5583d0fb7 100644 (file)
@@ -756,7 +756,7 @@ DiskReader::audio_read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
                   just once.
                */
 
-               if ((loc = loop_location) != 0) {
+               if ((loc = _loop_location) != 0) {
                        loop_start = loc->start();
                        loop_end = loc->end();
                        loop_length = loop_end - loop_start;
@@ -1254,7 +1254,7 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
        if (ms & MonitoringDisk) {
                /* disk data needed */
 
-               Location* loc = loop_location;
+               Location* loc = _loop_location;
 
                DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
                                     "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
@@ -1379,7 +1379,7 @@ DiskReader::midi_read (samplepos_t& start, samplecnt_t dur, bool reversed)
        samplepos_t loop_end    = 0;
        samplepos_t loop_start  = 0;
        samplecnt_t loop_length = 0;
-       Location*  loc         = loop_location;
+       Location*  loc         = _loop_location;
        samplepos_t effective_start = start;
        Evoral::Range<samplepos_t>*  loop_range (0);
 
index 0efc2e28114769baad804ddc30e157520c3ac0ac..c5c9beca36f222d515dd5c95162d1a7fad5150a0 100644 (file)
@@ -384,7 +384,7 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
                last_recordable_sample = max_samplepos;
        }
 
-       const Location* const loop_loc    = loop_location;
+       const Location* const loop_loc    = _loop_location;
        samplepos_t           loop_start  = 0;
        samplepos_t           loop_end    = 0;
        samplepos_t           loop_length = 0;
index c6e6c2136044084c637f5013a8c0e3d72a86387b..19b6f303672abc013dd7ac728b09642a486bd54e 100644 (file)
@@ -72,6 +72,7 @@ Processor::Processor(Session& session, const string& name)
        , _output_latency (0)
        , _capture_offset (0)
        , _playback_offset (0)
+       , _loop_location (0)
 {
 }
 
@@ -91,6 +92,10 @@ Processor::Processor (const Processor& other)
        , _pinmgr_proxy (0)
        , _owner (0)
        , _input_latency (0)
+       , _output_latency (0)
+       , _capture_offset (0)
+       , _playback_offset (0)
+       , _loop_location (other._loop_location)
 {
 }
 
index 29225404d95a47dcdadcced09f6d1f1b7fecf029..6b1a73c088e588ba0b6e9c82e333b9c4e5af41f8 100644 (file)
@@ -108,6 +108,7 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
        , _declickable (false)
        , _have_internal_generator (false)
        , _default_type (default_type)
+       , _loop_location (NULL)
        , _track_number (0)
        , _strict_io (false)
        , _in_configure_processors (false)
@@ -5881,6 +5882,16 @@ Route::set_disk_io_point (DiskIOPoint diop)
        processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
 }
 
+int
+Route::set_loop (Location* l)
+{
+       _loop_location = l;
+       Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+       for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+               (*i)->set_loop (l);
+       }
+}
+
 #ifdef USE_TRACKS_CODE_FEATURES
 
 /* This is the Tracks version of Track::monitoring_state().
@@ -6039,5 +6050,4 @@ Route::monitoring_state () const
        abort(); /* NOTREACHED */
        return MonitoringSilence;
 }
-
 #endif
index b777097e98274df53a9577a5f723f92cedc607a4..10eea5d3bfffa16f0b65e829b15f33c03316a676 100644 (file)
@@ -1000,9 +1000,8 @@ Session::set_track_loop (bool yn)
        boost::shared_ptr<RouteList> rl = routes.reader ();
 
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
-               boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
-               if (tr && !tr->is_private_route()) {
-                       tr->set_loop (yn ? loc : 0);
+               if (*i && !(*i)->is_private_route()) {
+                       (*i)->set_loop (yn ? loc : 0);
                }
        }
 }
index b3c8088033540167efdcbca79f86556806621afb..d58faf1e8318a2db3c4b97c5b2c2bb6abb948117 100644 (file)
@@ -538,15 +538,6 @@ Track::get_captured_samples (uint32_t n) const
        return _disk_writer->get_captured_samples (n);
 }
 
-int
-Track::set_loop (Location* l)
-{
-       if (_disk_reader->set_loop (l)) {
-               return -1;
-       }
-       return _disk_writer->set_loop (l);
-}
-
 void
 Track::transport_looped (samplepos_t p)
 {