+
+bool
+Route::has_external_redirects () const
+{
+ for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+
+ /* ignore inactive processors and obviously ignore the main
+ * outs since everything has them and we don't care.
+ */
+
+ if ((*i)->active() && (*i) != _main_outs && (*i)->does_routing()) {
+ return true;;
+ }
+ }
+
+ return false;
+}
+
+boost::shared_ptr<Processor>
+Route::the_instrument () const
+{
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+ return the_instrument_unlocked ();
+}
+
+boost::shared_ptr<Processor>
+Route::the_instrument_unlocked () const
+{
+ for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ if (boost::dynamic_pointer_cast<PluginInsert>(*i)) {
+ if ((*i)->input_streams().n_midi() > 0 &&
+ (*i)->output_streams().n_audio() > 0) {
+ return (*i);
+ }
+ }
+ }
+ return boost::shared_ptr<Processor>();
+}
+
+
+
+void
+Route::non_realtime_locate (framepos_t pos)
+{
+ if (_pannable) {
+ _pannable->transport_located (pos);
+ }
+
+ {
+ //Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
+ Glib::Threads::RWLock::WriterLock lm (_processor_lock);
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ (*i)->transport_located (pos);
+ }
+ }
+}
+
+void
+Route::fill_buffers_with_input (BufferSet& bufs, boost::shared_ptr<IO> io, pframes_t nframes)
+{
+ size_t n_buffers;
+ size_t i;
+
+ /* MIDI
+ *
+ * We don't currently mix MIDI input together, so we don't need the
+ * complex logic of the audio case.
+ */
+
+ n_buffers = bufs.count().n_midi ();
+
+ for (i = 0; i < n_buffers; ++i) {
+
+ boost::shared_ptr<MidiPort> source_port = io->midi (i);
+ MidiBuffer& buf (bufs.get_midi (i));
+
+ if (source_port) {
+ buf.copy (source_port->get_midi_buffer(nframes));
+ } else {
+ buf.silence (nframes);
+ }
+ }
+
+ /* AUDIO */
+
+ n_buffers = bufs.count().n_audio();
+
+ size_t n_ports = io->n_ports().n_audio();
+ float scaling = 1.0f;
+
+ if (n_ports > n_buffers) {
+ scaling = ((float) n_buffers) / n_ports;
+ }
+
+ for (i = 0; i < n_ports; ++i) {
+
+ /* if there are more ports than buffers, map them onto buffers
+ * in a round-robin fashion
+ */
+
+ boost::shared_ptr<AudioPort> source_port = io->audio (i);
+ AudioBuffer& buf (bufs.get_audio (i%n_buffers));
+
+
+ if (i < n_buffers) {
+
+ /* first time through just copy a channel into
+ the output buffer.
+ */
+
+ buf.read_from (source_port->get_audio_buffer (nframes), nframes);
+
+ if (scaling != 1.0f) {
+ buf.apply_gain (scaling, nframes);
+ }
+
+ } else {
+
+ /* on subsequent times around, merge data from
+ * the port with what is already there
+ */
+
+ if (scaling != 1.0f) {
+ buf.accumulate_with_gain_from (source_port->get_audio_buffer (nframes), nframes, 0, scaling);
+ } else {
+ buf.accumulate_from (source_port->get_audio_buffer (nframes), nframes);
+ }
+ }
+ }
+
+ /* silence any remaining buffers */
+
+ for (; i < n_buffers; ++i) {
+ AudioBuffer& buf (bufs.get_audio (i));
+ buf.silence (nframes);
+ }
+
+ /* establish the initial setup of the buffer set, reflecting what was
+ copied into it. unless, of course, we are the auditioner, in which
+ case nothing was fed into it from the inputs at all.
+ */
+
+ if (!is_auditioner()) {
+ bufs.set_count (io->n_ports());
+ }
+}