manage Route::_have_internal_generator more accurately and never flush processors...
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 7 Mar 2011 22:13:53 +0000 (22:13 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 7 Mar 2011 22:13:53 +0000 (22:13 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@9100 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/amp.cc
libs/ardour/ardour/route.h
libs/ardour/ardour/track.h
libs/ardour/audio_port.cc
libs/ardour/route.cc
libs/ardour/track.cc

index 5f305182f8c8472a1fbd7160e943b4b93ec7d739..40a1de2047ef7eaa345ec6e7feaad27478c6f058 100644 (file)
@@ -243,7 +243,7 @@ Amp::declick (BufferSet& bufs, framecnt_t nframes, int dir)
                if (declick != nframes) {
 
                        if (target == 0.0) {
-                               memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
+                                memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
                        } else if (target != 1.0) {
                                apply_gain_to_buffer (&buffer[declick], nframes - declick, target);
                        }
index 31b62d5e92148960863c010b9084704e1e1eb415..3b45020727714d7436a8da58d27b537cca103ccd 100644 (file)
@@ -482,6 +482,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
        ChanCount n_process_buffers ();
 
         virtual bool should_monitor () const;
+        virtual void maybe_declick (BufferSet&, framecnt_t, int);
 
        virtual int  _set_state (const XMLNode&, int, bool call_base);
 
index 74dd95ef13c648fa29c6a53d2e54a9822fe7ecc0..8faff74bc3f2765826c735c1fa3f36bbcb69ed44 100644 (file)
@@ -202,6 +202,8 @@ class Track : public Route, public PublicDiskstream
        XMLNode*              pending_state;
        bool                  _destructive;
 
+        void maybe_declick (BufferSet&, framecnt_t, int);
+
        virtual bool send_silence () const;
 
        boost::shared_ptr<RecEnableControllable> _rec_enable_control;
index f8a1018e2950dfc1661df479717b877c0d07fd76..9deda7a861d0dc329156cdd2e73054f211f17449 100644 (file)
@@ -54,7 +54,10 @@ void
 AudioPort::cycle_end (pframes_t nframes)
 {
         if (sends_output() && !_buffer->written()) {
-               _buffer->silence (nframes);
+                /* we can't use nframes here because the current buffer capacity may 
+                   be shorter than the full buffer size if we split the cycle.
+                */
+               _buffer->silence (_buffer->capacity());
        }
 }
 
index 994844a17f6915f96b6e3f6d2a0c742992f39550..be5ba4f80edd0978a4d942cb0d5835595b7042d2 100644 (file)
@@ -379,6 +379,14 @@ Route::set_gain (gain_t val, void *src)
        _amp->set_gain (val, src);
 }
 
+void
+Route::maybe_declick (BufferSet&, framecnt_t, int)
+{
+        /* this is the "bus" implementation and they never declick.
+         */
+        return;
+}
+
 /** Process this route for one (sub) cycle (process thread)
  *
  * @param bufs Scratch buffers to use for the signal path
@@ -399,10 +407,6 @@ Route::process_output_buffers (BufferSet& bufs,
 
        bufs.is_silent (false);
 
-       if (!declick) {
-               declick = _pending_declick;
-       }
-
        /* figure out if we're going to use gain automation */
         if (gain_automation_ok) {
                 _amp->setup_gain_automation (start_frame, end_frame, nframes);
@@ -418,10 +422,7 @@ Route::process_output_buffers (BufferSet& bufs,
           GLOBAL DECLICK (for transport changes etc.)
           ----------------------------------------------------------------------------------------- */
 
-       if (declick != 0) {
-               Amp::declick (bufs, nframes, declick);
-       }
-
+        maybe_declick (bufs, nframes, declick);
        _pending_declick = 0;
 
        /* -------------------------------------------------------------------------------------------
@@ -1057,6 +1058,17 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
 
                        (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
                }
+                
+               for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+                       boost::shared_ptr<PluginInsert> pi;
+
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
+                               if (pi->is_generator()) {
+                                       _have_internal_generator = true;
+                                       break;
+                               }
+                       }
+               }
 
                _output->set_user_latency (0);
        }
@@ -2401,10 +2413,22 @@ Route::set_processor_state (const XMLNode& node)
        {
                Glib::RWLock::WriterLock lm (_processor_lock);
                 _processors = new_order;
+
                 if (must_configure) {
                        Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
                         configure_processors_unlocked (0);
                 }
+
+               for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+                       boost::shared_ptr<PluginInsert> pi;
+
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
+                               if (pi->is_generator()) {
+                                       _have_internal_generator = true;
+                                       break;
+                               }
+                       }
+               }
         }
 
         processors_changed (RouteProcessorChange ());
@@ -2690,7 +2714,7 @@ Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_lo
 
                for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
 
-                       if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
+                       if (!_have_internal_generator && (Config->get_plugins_stop_with_transport() && can_flush_processors)) {
                                 (*i)->flush ();
                        }
                         
index 5767c45e6ed96d5fdebd9a82af40d34582858cf5..44f84ca3dcb7163318ffa78239efe1528d1cbab5 100644 (file)
@@ -690,3 +690,23 @@ Track::send_silence () const
 
         return send_silence;
 }
+
+void
+Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
+{      
+        /* never declick if there is an internal generator - we just want it to 
+           keep generating sound without interruption.
+        */
+
+        if (_have_internal_generator) {
+                return;
+        }
+
+        if (!declick) {
+               declick = _pending_declick;
+       }
+
+       if (declick != 0) {
+               Amp::declick (bufs, nframes, declick);
+       }
+}