Do a topological sort of the route list before passing it to
[ardour.git] / libs / ardour / internal_send.cc
index 3dbc27f45a7eb0394817b38da92bb3ed601ea9bc..cfed48e22367aefa53010e2a03943e50a5160950 100644 (file)
 
 #include "ardour/amp.h"
 #include "ardour/audio_buffer.h"
+#include "ardour/internal_return.h"
 #include "ardour/internal_send.h"
 #include "ardour/meter.h"
 #include "ardour/panner.h"
 #include "ardour/panner_shell.h"
 #include "ardour/route.h"
 #include "ardour/session.h"
+#include "ardour/audioengine.h"
 
 #include "i18n.h"
 
@@ -77,6 +79,11 @@ InternalSend::use_target (boost::shared_ptr<Route> sendto)
 
         _send_to->add_send_to_internal_return (this);
 
+       mixbufs.ensure_buffers (_send_to->internal_return()->input_streams(), _session.get_block_size());
+       mixbufs.set_count (_send_to->internal_return()->input_streams());
+
+       reset_panner ();
+
         set_name (sendto->name());
         _send_to_id = _send_to->id();
 
@@ -107,19 +114,17 @@ InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame
        // we have to copy the input, because we may alter the buffers with the amp
        // in-place, which a send must never do.
 
-       assert(mixbufs.available() >= bufs.count());
-
-       boost::shared_ptr<Panner> panner;
-       
-       if (_panshell) {
-               panner = _panshell->panner();
-       }
-       
-       if (panner && !panner->bypassed()) {
-               mixbufs.set_count (_send_to->n_outputs ());
+       if (_panshell && !_panshell->bypassed()) {
                _panshell->run (bufs, mixbufs, start_frame, end_frame, nframes);
        } else {
-               mixbufs.read_from (bufs, nframes);
+               if (role() == Listen) {
+                       /* We're going to the monitor bus, so discard MIDI data */
+                       assert (mixbufs.available().get (DataType::AUDIO) >= bufs.count().get (DataType::AUDIO));
+                       mixbufs.read_from (bufs, nframes, DataType::AUDIO);
+               } else {
+                       assert (mixbufs.available() >= bufs.count());
+                       mixbufs.read_from (bufs, nframes);
+               }
        }
 
        /* gain control */
@@ -164,20 +169,6 @@ InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame
                }
        }
 
-#if 0
-        if (_session.transport_rolling()) {
-                for (BufferSet::audio_iterator b = mixbufs.audio_begin(); b != mixbufs.audio_end(); ++b) {
-                        Sample* p = b->data ();
-                        for (pframes_t n = 0; n < nframes; ++n) {
-                               if (p[n] != 0.0) {
-                                       cerr << "\tnon-zero data SENT to " << b->data() << endl;
-                                       break;
-                               }
-                        }
-                }
-        }
-#endif
-
        /* target will pick up our output when it is ready */
 
   out:
@@ -187,7 +178,10 @@ InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame
 int
 InternalSend::set_block_size (pframes_t nframes)
 {
-       mixbufs.ensure_buffers (_configured_input, nframes);
+       if (_send_to) {
+               mixbufs.ensure_buffers (_send_to->internal_return()->input_streams(), nframes);
+       }
+
         return 0;
 }
 
@@ -274,6 +268,22 @@ InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out)
        return true;
 }
 
+uint32_t
+InternalSend::pan_outs () const
+{
+       /* the number of targets for our panner is determined by what we are
+          sending to, if anything.
+       */
+
+       if (_send_to) {
+               return _send_to->internal_return()->input_streams().n_audio();
+       }
+
+       return 1; /* zero is more accurate, but 1 is probably safer as a way to
+                  * say "don't pan"
+                  */
+}
+
 bool
 InternalSend::configure_io (ChanCount in, ChanCount out)
 {
@@ -320,14 +330,8 @@ InternalSend::send_to_property_changed (const PropertyChange& what_changed)
 void
 InternalSend::set_can_pan (bool yn)
 {
-       boost::shared_ptr<Panner> panner;
-
        if (_panshell) {
-               panner = _panshell->panner ();
-       }
-
-       if (panner) {
-               panner->set_bypassed (!yn);
+               _panshell->set_bypassed (!yn);
        }
 }