summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
commit70b939da4f9d4097160e32f2373a7a5ff8f4957f (patch)
tree5917e5847c75e441c9df550d5101352d18e8286f /libs/ardour
parentee62ee07d39f51ba1b70f390dc2158c57f54a572 (diff)
first pass at internal sends. this is a very tentative work in progress, and it is possible that major changes may follow in the near future. it is certainly not complete, but the fundamental changes to Port/Buffer operation merit a commit at this point
git-svn-id: svn://localhost/ardour2/branches/3.0@4464 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/ardour.h3
-rw-r--r--libs/ardour/ardour/audio_buffer.h23
-rw-r--r--libs/ardour/ardour/audio_port.h6
-rw-r--r--libs/ardour/ardour/audio_track.h4
-rw-r--r--libs/ardour/ardour/automatable.h7
-rw-r--r--libs/ardour/ardour/buffer.h6
-rw-r--r--libs/ardour/ardour/buffer_set.h3
-rw-r--r--libs/ardour/ardour/io.h29
-rw-r--r--libs/ardour/ardour/io_processor.h4
-rw-r--r--libs/ardour/ardour/port.h10
-rw-r--r--libs/ardour/ardour/processor.h7
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/types.h5
-rw-r--r--libs/ardour/audio_buffer.cc34
-rw-r--r--libs/ardour/audio_port.cc126
-rw-r--r--libs/ardour/audio_track.cc40
-rw-r--r--libs/ardour/audioengine.cc9
-rw-r--r--libs/ardour/buffer_set.cc6
-rw-r--r--libs/ardour/io.cc102
-rw-r--r--libs/ardour/io_processor.cc8
-rw-r--r--libs/ardour/port.cc123
-rw-r--r--libs/ardour/processor.cc7
-rw-r--r--libs/ardour/route.cc60
-rw-r--r--libs/ardour/send.cc10
-rw-r--r--libs/ardour/session.cc7
26 files changed, 430 insertions, 211 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index f34dd9b078..59ffd764bc 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -92,6 +92,7 @@ gain.cc
gdither.cc
globals.cc
import.cc
+internal_send.cc
io.cc
io_processor.cc
jack_slave.cc
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
index 635e8a31ca..7321daf097 100644
--- a/libs/ardour/ardour/ardour.h
+++ b/libs/ardour/ardour/ardour.h
@@ -42,9 +42,6 @@ namespace MIDI {
namespace ARDOUR {
class AudioEngine;
- class OSC;
-
- extern OSC* osc;
static const nframes_t max_frames = JACK_MAX_FRAMES;
extern sigc::signal<void,std::string> BootMessage;
diff --git a/libs/ardour/ardour/audio_buffer.h b/libs/ardour/ardour/audio_buffer.h
index 9a41e8e093..829288a7af 100644
--- a/libs/ardour/ardour/audio_buffer.h
+++ b/libs/ardour/ardour/audio_buffer.h
@@ -68,9 +68,14 @@ public:
/** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
* scaling by @a gain_coeff */
void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) {
+
assert(_capacity > 0);
assert(offset + len <= _capacity);
+ if (src.silent()) {
+ return;
+ }
+
Sample* const dst_raw = _data + offset;
const Sample* const src_raw = src.data();
@@ -82,6 +87,7 @@ public:
/** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
* scaling by @a gain_coeff */
void accumulate_with_gain_from(const Sample* src_raw, nframes_t len, nframes_t offset, gain_t gain_coeff) {
+
assert(_capacity > 0);
assert(offset + len <= _capacity);
@@ -123,7 +129,22 @@ public:
Sample* data (nframes_t nframes, nframes_t offset)
{ assert(offset + nframes <= _capacity); return _data + offset; }
-private:
+ void replace_data (size_t nframes);
+
+ void drop_data () {
+ assert (_owns_data);
+ assert (_data);
+
+ free (_data);
+ _data = 0;
+ _size = 0;
+ _capacity = 0;
+ _silent = false;
+ }
+
+ void copy_to_internal (Sample* p, nframes_t cnt, nframes_t offset);
+
+ private:
bool _owns_data;
Sample* _data; ///< Actual buffer contents
};
diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h
index 339165da0f..304902bccb 100644
--- a/libs/ardour/ardour/audio_port.h
+++ b/libs/ardour/ardour/audio_port.h
@@ -51,12 +51,16 @@ class AudioPort : public Port
AudioPort (std::string const &, Flags, bool, nframes_t);
+ bool using_internal_data() const;
+ void use_internal_data ();
+ void use_external_data ();
+
private:
void mixdown (nframes_t, nframes_t, bool);
bool _has_been_mixed_down;
AudioBuffer* _buffer;
- bool _own_buffer;
+ bool _internal_buffer;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index fe7dcb58ff..48609271d7 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -73,6 +73,10 @@ class AudioTrack : public Track
int deprecated_use_diskstream_connections ();
void set_state_part_two ();
void set_state_part_three ();
+
+ void catch_up_on_busses (ARDOUR::RouteList&);
+ void add_internal_send (boost::shared_ptr<ARDOUR::Route>);
+
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h
index fc61e2200d..d99960334d 100644
--- a/libs/ardour/ardour/automatable.h
+++ b/libs/ardour/ardour/automatable.h
@@ -94,15 +94,16 @@ public:
Evoral::ControlSet& data() { return *this; }
const Evoral::ControlSet& data() const { return *this; }
-protected:
+ int set_automation_state (const XMLNode&, Evoral::Parameter default_param);
+ XMLNode& get_automation_state();
+
+ protected:
Session& _a_session;
void can_automate(Evoral::Parameter);
virtual void auto_state_changed (Evoral::Parameter which) {}
- int set_automation_state(const XMLNode&, Evoral::Parameter default_param);
- XMLNode& get_automation_state();
int load_automation (const std::string& path);
int old_set_automation_state(const XMLNode&);
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
index e03489568c..02d6975fad 100644
--- a/libs/ardour/ardour/buffer.h
+++ b/libs/ardour/ardour/buffer.h
@@ -68,7 +68,7 @@ public:
* passed to the constructor must have been non-zero.
*/
virtual void resize(size_t) = 0;
-
+
/** Clear (eg zero, or empty) buffer starting at TIME @a offset */
virtual void silence(nframes_t len, nframes_t offset=0) = 0;
@@ -77,9 +77,9 @@ public:
virtual void read_from(const Buffer& src, nframes_t offset, nframes_t len) = 0;
-protected:
+ protected:
Buffer(DataType type, size_t capacity)
- : _type(type), _capacity(capacity), _size(0), _silent(true)
+ : _type(type), _capacity(capacity), _size(0), _silent(true)
{}
DataType _type;
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index c750615798..3f7a6e7665 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -23,6 +23,7 @@
#include <vector>
#include <ardour/chan_count.h>
#include <ardour/data_type.h>
+#include <ardour/types.h>
namespace ARDOUR {
@@ -53,7 +54,7 @@ public:
void clear();
- void attach_buffers(PortSet& ports);
+ void attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset);
void ensure_buffers(const ChanCount& count, size_t buffer_capacity);
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity);
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 2d5b55c502..32962fef0d 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -109,6 +109,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
void just_meter_input (nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset);
+ BufferSet& output_buffers() { return *_output_buffers; }
+
gain_t gain () const { return _desired_gain; }
virtual gain_t effective_gain () const;
@@ -121,6 +123,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
Panner& panner() { return *_panner; }
PeakMeter& peak_meter() { return *_meter; }
const Panner& panner() const { return *_panner; }
+ void reset_panner ();
int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
@@ -196,15 +199,10 @@ class IO : public SessionObject, public AutomatableControls, public Latent
int set_state (const XMLNode&);
static int disable_connecting (void);
-
static int enable_connecting (void);
-
static int disable_ports (void);
-
static int enable_ports (void);
-
static int disable_panners (void);
-
static int reset_panners (void);
static sigc::signal<int> PortsLegal;
@@ -214,16 +212,16 @@ class IO : public SessionObject, public AutomatableControls, public Latent
static sigc::signal<void,ChanCount> PortCountChanged;
static sigc::signal<int> PortsCreated;
- static void update_meters();
+ static void update_meters();
private:
-
- static sigc::signal<void> Meter;
- static Glib::StaticMutex m_meter_signal_lock;
- sigc::connection m_meter_connection;
+
+ static sigc::signal<void> Meter;
+ static Glib::StaticMutex m_meter_signal_lock;
+ sigc::connection m_meter_connection;
public:
-
+
/* automation */
struct GainControl : public AutomationControl {
@@ -292,8 +290,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
virtual void set_deferred_state() {}
- void reset_panner ();
-
virtual uint32_t pans_required() const
{ return _inputs.count().n_audio(); }
@@ -314,14 +310,11 @@ class IO : public SessionObject, public AutomatableControls, public Latent
static bool connecting_legal;
static bool ports_legal;
- BufferSet& output_buffers() { return *_output_buffers; }
-
private:
+ static bool panners_legal;
- friend class Send;
+ void copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes, nframes_t offset);
- static bool panners_legal;
-
int connecting_became_legal ();
int panners_became_legal ();
sigc::connection connection_legal_c;
diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h
index d2bd210516..3739c496c5 100644
--- a/libs/ardour/ardour/io_processor.h
+++ b/libs/ardour/ardour/io_processor.h
@@ -53,7 +53,9 @@ class IOProcessor : public Processor
{
public:
IOProcessor (Session&, const string& name, Placement,
- int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1);
+ int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1,
+ ARDOUR::DataType default_type = DataType::AUDIO,
+ bool public_ports = true);
IOProcessor (const IOProcessor&);
virtual ~IOProcessor ();
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index 7539aac9d5..759d532e82 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -71,6 +71,7 @@ public:
}
bool connected () const;
+ bool externally_connected () const;
int disconnect_all ();
int get_connections (std::vector<std::string> &) const;
@@ -81,7 +82,7 @@ public:
/* connection by Port* */
bool connected_to (Port *) const;
- int connect (Port *);
+ virtual int connect (Port *);
int disconnect (Port *);
void ensure_monitor_input (bool);
@@ -113,6 +114,12 @@ protected:
std::set<Port*> _connections; ///< internal Ports that we are connected to
static AudioEngine* _engine; ///< the AudioEngine
+
+ virtual bool using_internal_data() const { return false; }
+ virtual void use_internal_data () {}
+ virtual void use_external_data () {}
+
+ void check_buffer_status ();
private:
friend class AudioEngine;
@@ -130,6 +137,7 @@ private:
/// list of JACK ports that we are connected to; we only keep this around
/// so that we can implement ::reconnect ()
std::set<std::string> _named_connections;
+
};
}
diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h
index 4b236d159e..da00c77dab 100644
--- a/libs/ardour/ardour/processor.h
+++ b/libs/ardour/ardour/processor.h
@@ -39,6 +39,7 @@ class XMLNode;
namespace ARDOUR {
class Session;
+class Route;
/* A mixer strip element - plugin, send, meter, etc.
*/
@@ -60,7 +61,6 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
void set_placement (Placement);
bool active () const { return _active; }
- void set_active (bool yn);
bool get_next_ab_is_active () const { return _next_ab_is_active; }
void set_next_ab_is_active (bool yn) { _next_ab_is_active = yn; }
@@ -77,8 +77,8 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
virtual void silence (nframes_t nframes, nframes_t offset) {}
- virtual void activate () { _active = true; ActiveChanged.emit(); }
- virtual void deactivate () { _active = false; ActiveChanged.emit(); }
+ void activate () { _active = true; ActiveChanged(); }
+ void deactivate () { _active = false; ActiveChanged(); }
virtual bool configure_io (ChanCount in, ChanCount out);
@@ -108,6 +108,7 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
sigc::signal<void> PlacementChanged;
protected:
+ int _pending_active;
bool _active;
bool _next_ab_is_active;
bool _configured;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 1a88882eb6..7cdc11a054 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -306,7 +306,6 @@ class Session : public PBD::StatefulDestructible
uint32_t n_diskstreams() const;
typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
- typedef std::list<boost::shared_ptr<Route> > RouteList;
int load_routes (const XMLNode&);
boost::shared_ptr<RouteList> get_routes() const {
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index cb058254bf..125c8569a8 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -51,6 +51,7 @@ namespace ARDOUR {
class Source;
class AudioSource;
+ class Route;
typedef jack_default_audio_sample_t Sample;
typedef float pan_t;
@@ -419,9 +420,11 @@ namespace ARDOUR {
typedef std::list<nframes64_t> AnalysisFeatureList;
+ typedef std::list<boost::shared_ptr<Route> > RouteList;
+
class Bundle;
typedef std::vector<boost::shared_ptr<Bundle> > BundleList;
-
+
} // namespace ARDOUR
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
diff --git a/libs/ardour/audio_buffer.cc b/libs/ardour/audio_buffer.cc
index 915fdeb948..506b34eb04 100644
--- a/libs/ardour/audio_buffer.cc
+++ b/libs/ardour/audio_buffer.cc
@@ -29,9 +29,7 @@ static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it mat
#endif
using namespace PBD;
-
-namespace ARDOUR {
-
+using namespace ARDOUR;
AudioBuffer::AudioBuffer(size_t capacity)
: Buffer(DataType::AUDIO, capacity)
@@ -41,6 +39,7 @@ AudioBuffer::AudioBuffer(size_t capacity)
if (_capacity > 0) {
_owns_data = true; // prevent resize() from gagging
resize (_capacity);
+ _silent = false; // force silence on the intial buffer state
silence (_capacity);
}
}
@@ -51,10 +50,28 @@ AudioBuffer::~AudioBuffer()
free(_data);
}
+/* called to replace a pointer to an external buffer (e.g. JACK) with
+ buffer-owned memory.
+*/
+
+void
+AudioBuffer::replace_data (size_t capacity)
+{
+ _owns_data = true;
+ _data = 0;
+ _capacity = 0; // force reallocation
+ resize (capacity);
+}
+
void
AudioBuffer::resize (size_t size)
{
- if (!_owns_data || (size < _capacity)) {
+ if (!_owns_data) {
+ return;
+ }
+
+ if (size < _capacity) {
+ _size = size;
return;
}
@@ -74,9 +91,12 @@ AudioBuffer::resize (size_t size)
CPU_CACHE_ALIGN, sizeof (Sample) * _capacity, strerror (errno)) << endmsg;
}
#endif
-
- _owns_data = true;
+
}
-} // namespace ARDOUR
+void
+AudioBuffer::copy_to_internal (Sample* p, nframes_t cnt, nframes_t offset)
+{
+ memcpy (_data + offset, p, sizeof(Sample*) * cnt);
+}
diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc
index 55d65d850d..0e48c2a699 100644
--- a/libs/ardour/audio_port.cc
+++ b/libs/ardour/audio_port.cc
@@ -29,9 +29,10 @@ AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t
: Port (name, DataType::AUDIO, flags, ext)
, _has_been_mixed_down (false)
, _buffer (0)
+ , _internal_buffer (false)
{
assert (name.find_first_of (':') == string::npos);
-
+
if (external ()) {
/* external ports use the external port buffer */
@@ -41,8 +42,9 @@ AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t
/* internal ports need their own buffers */
_buffer = new AudioBuffer (capacity);
-
}
+
+ check_buffer_status ();
}
@@ -56,11 +58,22 @@ AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
{
/* caller must hold process lock */
- _has_been_mixed_down = false;
+ /* For external (JACK) ports, get_buffer() must only be run
+ on outputs here in cycle_start().
- if (external ()) {
- /* external ports use JACK's memory */
- _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes), nframes + offset);
+ Inputs must be done in the correct processing order, which
+ requires interleaving with route processing. that will
+ happen when Port::get_buffer() is called.
+ */
+
+ if (!receives_input() && external ()) {
+ _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
+ }
+
+ if (receives_input()) {
+ _has_been_mixed_down = false;
+ } else {
+ _buffer->silence (nframes, offset);
}
}
@@ -69,36 +82,21 @@ AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
{
/* caller must hold process lock */
- if (_has_been_mixed_down) {
- return *_buffer;
- }
-
- if (receives_input ()) {
-
- /* INPUT */
+ if (receives_input () && !_has_been_mixed_down) {
- /* If we're external (), we have some data in our buffer set up by JACK;
- otherwise, we have an undefined buffer. In either case we mix down
- our non-JACK inputs; either accumulating into the JACK data or
- overwriting the undefined data */
-
- mixdown (nframes, offset, !external ());
+ /* external ports use JACK's memory unless otherwise noted */
- } else {
-
- /* OUTPUT */
-
- if (!external ()) {
- /* start internal output buffers with silence */
- _buffer->silence (nframes, offset);
+ if (external()) {
+ if (!using_internal_data()) {
+ _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
+ } else {
+ _buffer->silence (nframes, offset);
+ }
}
-
- }
-
- if (nframes) {
- _has_been_mixed_down = true;
- }
+ mixdown (nframes, offset, !external ());
+ }
+
return *_buffer;
}
@@ -111,22 +109,46 @@ AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
void
AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
{
+ /* note: this is only called for input ports */
+
if (_connections.empty()) {
- if (first_overwrite) {
+
+ /* no internal mixing to do, so for internal ports
+ just make sure the buffer is silent.
+ */
+
+ if (!external()) {
_buffer->silence (cnt, offset);
+ }
+
+ } else {
+
+ set<Port*>::const_iterator p = _connections.begin();
+
+ /* mix in internally-connected ports. if this is an external port
+ then it may already have data present from JACK. in that case, we
+ do not want to overwrite that data, so we skip the initial ::read_from()
+ call and do everything with accumulate_from()
+ */
+
+ if (!external()) {
+ _buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+ ++p;
+
}
- return;
- }
-
- set<Port*>::const_iterator p = _connections.begin();
- if (first_overwrite) {
- _buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
- ++p;
+ for (; p != _connections.end (); ++p) {
+ _buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+
+ }
}
- for (; p != _connections.end (); ++p) {
- _buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+ /* XXX horrible heuristic designed to check that we worked the whole buffer.
+ Needs fixing but its a hard problem.
+ */
+
+ if (cnt && offset == 0) {
+ _has_been_mixed_down = true;
}
}
@@ -140,3 +162,23 @@ AudioPort::reset ()
_buffer->clear ();
}
}
+
+bool
+AudioPort::using_internal_data () const
+{
+ return _internal_buffer;
+}
+
+void
+AudioPort::use_internal_data ()
+{
+ _buffer->replace_data (_buffer->capacity());
+ _internal_buffer = true;
+}
+
+void
+AudioPort::use_external_data ()
+{
+ _internal_buffer = false;
+ _buffer->drop_data ();
+}
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index ada5a183dc..5749afd265 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -40,6 +40,7 @@
#include <ardour/utils.h>
#include <ardour/buffer_set.h>
#include <ardour/audio_buffer.h>
+#include <ardour/internal_send.h>
#include "i18n.h"
using namespace std;
@@ -65,6 +66,8 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
_session.add_diskstream (ds);
+ _session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses));
+
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
}
@@ -72,12 +75,47 @@ AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
: Track (sess, node)
{
_set_state (node, false);
+
+ _session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses));
}
AudioTrack::~AudioTrack ()
{
}
+void
+AudioTrack::catch_up_on_busses (RouteList& added)
+{
+ if (is_hidden()) {
+ return;
+ }
+
+ for (RouteList::iterator x = added.begin(); x != added.end(); ++x) {
+ if (boost::dynamic_pointer_cast<Track>(*x) == 0 && (*x)->default_type() == DataType::AUDIO) {
+ /* Audio bus */
+ if (!(*x)->is_master() && !(*x)->is_control()) {
+ add_internal_send (*x);
+ }
+ }
+ }
+}
+
+void
+AudioTrack::add_internal_send (boost::shared_ptr<Route> r)
+{
+ boost::shared_ptr<InternalSend> is (new InternalSend (_session, PreFader, r));
+
+ cerr << name() << " Adding processor\n";
+
+ add_processor (is, 0);
+
+ cerr << "After add, we have " << _processors.size() << endl;
+
+ /* note: if adding failed, the InternalSend will be cleaned up automatically when
+ the shared_ptr goes out of scope.
+ */
+}
+
int
AudioTrack::set_mode (TrackMode m)
{
@@ -879,7 +917,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
/* now deactivate the processor */
- processor->set_active (false);
+ processor->deactivate ();
_session.set_dirty ();
}
}
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 4d8f18423f..27b5fcc5c5 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -348,13 +348,6 @@ AudioEngine::process_callback (nframes_t nframes)
boost::shared_ptr<Ports> p = ports.reader();
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
-
- /* Only run cycle_start() on output ports, because
- inputs must be done in the correct processing order,
- which requires interleaving with route processing.
- */
-
- /* XXX: we're running this on both inputs and outputs... */
(*i)->cycle_start (nframes, 0);
}
@@ -416,10 +409,8 @@ AudioEngine::process_callback (nframes_t nframes)
// Finalize ports (ie write data if necessary)
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
-
(*i)->cycle_end (nframes, 0);
}
-
_processed_frames = next_processed_frames;
return 0;
}
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index 5b6f071150..09fd880451 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -16,6 +16,7 @@
675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <iostream>
#include <algorithm>
#include <ardour/buffer_set.h>
#include <ardour/buffer.h>
@@ -61,7 +62,7 @@ BufferSet::clear()
/** Make this BufferSet a direct mirror of a PortSet's buffers.
*/
void
-BufferSet::attach_buffers(PortSet& ports)
+BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
{
clear();
@@ -71,9 +72,8 @@ BufferSet::attach_buffers(PortSet& ports)
for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
assert(p->type() == *t);
- v.push_back(&(p->get_buffer(0,0)));
+ v.push_back(&(p->get_buffer(nframes, offset)));
}
-
}
_count = ports.count();
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index a5a330cc36..dbe7b3c526 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -153,9 +153,6 @@ IO::IO (Session& s, const string& name,
m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
}
- // Connect to our own PortCountChanged signal to connect output buffers
- IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
-
_session.add_controllable (_gain_control);
create_bundles_for_inputs_and_outputs ();
@@ -195,9 +192,6 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
}
- // Connect to our own PortCountChanged signal to connect output buffers
- IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers));
-
_session.add_controllable (_gain_control);
create_bundles_for_inputs_and_outputs ();
@@ -222,7 +216,6 @@ IO::~IO ()
delete _meter;
delete _panner;
- delete _output_buffers;
}
void
@@ -266,48 +259,61 @@ IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
_gain = dg;
}
}
+
+ /* do this so that any processing that comes after deliver_outputs()
+ can use the output buffers.
+ */
+
+ output_buffers().attach_buffers (_outputs, nframes, offset);
// Use the panner to distribute audio to output port buffers
- if( _panner && _panner->npanners() && !_panner->bypassed()) {
+
+ if (0 && _panner && _panner->npanners() && !_panner->bypassed()) {
+
+ /* blech .. we shouldn't be creating and tearing this down every process()
+ cycle. XXX fix me to not waste cycles and do memory allocation etc.
+ */
+
_panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
+
} else {
- const DataType type = DataType::AUDIO;
-
- // Copy any audio 1:1 to outputs
-
- BufferSet::iterator o = output_buffers().begin(type);
- BufferSet::iterator i = bufs.begin(type);
- BufferSet::iterator prev = i;
-
- while (i != bufs.end(type) && o != output_buffers().end (type)) {
- o->read_from(*i, nframes, offset);
- prev = i;
- ++i;
- ++o;
- }
- /* extra outputs get a copy of the last buffer */
+ /* do a 1:1 copy of data to output ports */
- while (o != output_buffers().end(type)) {
- o->read_from(*prev, nframes, offset);
- ++o;
+ if (bufs.count().n_audio() > 0 && _outputs.count().n_audio () > 0) {
+ copy_to_outputs (bufs, DataType::AUDIO, nframes, offset);
+ }
+ if (bufs.count().n_midi() > 0 && _outputs.count().n_midi () > 0) {
+ copy_to_outputs (bufs, DataType::MIDI, nframes, offset);
}
}
+}
- /* ********** MIDI ********** */
+void
+IO::copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes, nframes_t offset)
+{
+ // Copy any buffers 1:1 to outputs
+
+ PortSet::iterator o = _outputs.begin(type);
+ BufferSet::iterator i = bufs.begin(type);
+ BufferSet::iterator prev = i;
+
+ while (i != bufs.end(type) && o != _outputs.end (type)) {
+
+ Buffer& port_buffer (o->get_buffer (nframes, offset));
+ port_buffer.read_from (*i, nframes, offset);
- // No MIDI, we're done here
- if (bufs.count().n_midi() == 0 || output_buffers().count().n_midi () == 0) {
- return;
+ prev = i;
+ ++i;
+ ++o;
}
-
- const DataType type = DataType::MIDI;
-
- // Copy any MIDI 1:1 to outputs
- assert(bufs.count().n_midi() == output_buffers().count().n_midi());
- BufferSet::iterator o = output_buffers().begin(type);
- for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) {
- o->read_from(*i, nframes, offset);
+
+ /* extra outputs get a copy of the last buffer */
+
+ while (o != _outputs.end(type)) {
+ Buffer& port_buffer (o->get_buffer (nframes, offset));
+ port_buffer.read_from(*prev, nframes, offset);
+ ++o;
}
}
@@ -324,8 +330,10 @@ IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset)
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
BufferSet::iterator o = outs.begin(*t);
- for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) {
- o->read_from(i->get_buffer(nframes,offset), nframes, offset);
+ PortSet::iterator e = _inputs.end (*t);
+ for (PortSet::iterator i = _inputs.begin(*t); i != e; ++i, ++o) {
+ Buffer& b (i->get_buffer (nframes,offset));
+ o->read_from (b, nframes, offset);
}
}
@@ -879,16 +887,6 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
return changed;
}
-/** Attach output_buffers to port buffers.
- *
- * Connected to IO's own PortCountChanged signal.
- */
-void
-IO::attach_buffers(ChanCount ignored)
-{
- _output_buffers->attach_buffers(_outputs);
-}
-
int
IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
{
@@ -2321,6 +2319,8 @@ IO::set_gain (gain_t val, void *src)
val = 1.99526231f;
}
+ cerr << "set desired gain to " << val << " when curgain = " << _gain_control->get_value () << endl;
+
if (src != _gain_control.get()) {
_gain_control->set_value(val);
// bit twisty, this will come back and call us again
@@ -2741,3 +2741,5 @@ IO::bundle_channel_name (uint32_t c, uint32_t n) const
return "";
}
+
+
diff --git a/libs/ardour/io_processor.cc b/libs/ardour/io_processor.cc
index 08530b924c..fb27ba6f54 100644
--- a/libs/ardour/io_processor.cc
+++ b/libs/ardour/io_processor.cc
@@ -43,10 +43,12 @@ using namespace ARDOUR;
using namespace PBD;
IOProcessor::IOProcessor (Session& s, const string& name, Placement p,
- int input_min, int input_max,
- int output_min, int output_max)
+ int input_min, int input_max,
+ int output_min, int output_max,
+ DataType dtype,
+ bool public_ports)
: Processor(s, name, p)
- , _io(new IO(s, name, input_min, input_max, output_min, output_max))
+ , _io (new IO(s, name, input_min, input_max, output_min, output_max, dtype, public_ports))
{
_active = false;
_sort_key = 0;
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index b200888508..74de1922fe 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -25,19 +25,30 @@
#include "pbd/compose.h"
#include <stdexcept>
-ARDOUR::AudioEngine* ARDOUR::Port::_engine = 0;
+using namespace std;
+using namespace ARDOUR;
+
+AudioEngine* Port::_engine = 0;
/** @param n Port short name */
-ARDOUR::Port::Port (std::string const & n, DataType t, Flags f, bool e) : _jack_port (0), _last_monitor (false), _latency (0), _name (n), _flags (f)
+Port::Port (std::string const & n, DataType t, Flags f, bool e)
+ : _jack_port (0)
+ , _last_monitor (false)
+ , _latency (0)
+ , _name (n)
+ , _flags (f)
{
+
/* Unfortunately we have to pass the DataType into this constructor so that we can
create the right kind of JACK port; aside from this we'll use the virtual function type ()
- to establish type. */
+ to establish type.
+ */
assert (_name.find_first_of (':') == std::string::npos);
if (e) {
try {
+ cerr << "NEW PORT " << _name << " ext = " << e << endl;
do_make_external (t);
}
catch (...) {
@@ -47,7 +58,7 @@ ARDOUR::Port::Port (std::string const & n, DataType t, Flags f, bool e) : _jack_
}
/** Port destructor */
-ARDOUR::Port::~Port ()
+Port::~Port ()
{
if (_jack_port) {
jack_port_unregister (_engine->jack (), _jack_port);
@@ -58,28 +69,27 @@ ARDOUR::Port::~Port ()
* @param t Data type, so that we can call this method from the constructor.
*/
void
-ARDOUR::Port::do_make_external (DataType t)
+Port::do_make_external (DataType t)
{
if (_jack_port) {
/* already external */
return;
}
- _jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0);
- if (_jack_port == 0) {
+ if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
throw std::runtime_error ("Could not register JACK port");
}
}
void
-ARDOUR::Port::make_external ()
+Port::make_external ()
{
do_make_external (type ());
}
/** @return true if this port is connected to anything */
bool
-ARDOUR::Port::connected () const
+Port::connected () const
{
if (!_connections.empty ()) {
/* connected to a Port* */
@@ -94,8 +104,20 @@ ARDOUR::Port::connected () const
return (jack_port_connected (_jack_port) != 0);
}
+/** @return true if this port is connected to anything via an external port */
+bool
+Port::externally_connected () const
+{
+ if (_jack_port == 0) {
+ /* not using a JACK port, so can't be connected to anything else */
+ return false;
+ }
+
+ return (jack_port_connected (_jack_port) != 0);
+}
+
int
-ARDOUR::Port::disconnect_all ()
+Port::disconnect_all ()
{
/* Disconnect from Port* connections */
for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
@@ -108,6 +130,8 @@ ARDOUR::Port::disconnect_all ()
jack_port_disconnect (_engine->jack(), _jack_port);
_named_connections.clear ();
+ check_buffer_status ();
+
return 0;
}
@@ -115,7 +139,7 @@ ARDOUR::Port::disconnect_all ()
* @return true if this port is connected to o, otherwise false.
*/
bool
-ARDOUR::Port::connected_to (std::string const & o) const
+Port::connected_to (std::string const & o) const
{
std::string const full = _engine->make_port_name_non_relative (o);
std::string const shrt = _engine->make_port_name_non_relative (o);
@@ -137,7 +161,7 @@ ARDOUR::Port::connected_to (std::string const & o) const
/** @param o Filled in with port full names of ports that we are connected to */
int
-ARDOUR::Port::get_connections (std::vector<std::string> & c) const
+Port::get_connections (std::vector<std::string> & c) const
{
int n = 0;
@@ -163,7 +187,7 @@ ARDOUR::Port::get_connections (std::vector<std::string> & c) const
}
int
-ARDOUR::Port::connect (std::string const & other)
+Port::connect (std::string const & other)
{
/* caller must hold process lock */
@@ -197,11 +221,13 @@ ARDOUR::Port::connect (std::string const & other)
}
}
+ check_buffer_status ();
+
return r;
}
int
-ARDOUR::Port::disconnect (std::string const & other)
+Port::disconnect (std::string const & other)
{
/* caller must hold process lock */
@@ -227,6 +253,8 @@ ARDOUR::Port::disconnect (std::string const & other)
if (r == 0) {
_named_connections.erase (other);
}
+
+ check_buffer_status ();
}
return r;
@@ -234,13 +262,13 @@ ARDOUR::Port::disconnect (std::string const & other)
bool
-ARDOUR::Port::connected_to (Port* o) const
+Port::connected_to (Port* o) const
{
return connected_to (o->name ());
}
int
-ARDOUR::Port::connect (Port* o)
+Port::connect (Port* o)
{
/* caller must hold process lock */
@@ -253,11 +281,14 @@ ARDOUR::Port::connect (Port* o)
_connections.insert (o);
o->_connections.insert (this);
+ check_buffer_status ();
+ o->check_buffer_status ();
+
return 0;
}
int
-ARDOUR::Port::disconnect (Port* o)
+Port::disconnect (Port* o)
{
if (external () && o->external ()) {
/* we're both external; try disconnecting using name */
@@ -270,17 +301,20 @@ ARDOUR::Port::disconnect (Port* o)
_connections.erase (o);
o->_connections.erase (this);
+ check_buffer_status ();
+ o->check_buffer_status ();
+
return 0;
}
void
-ARDOUR::Port::set_engine (AudioEngine* e)
+Port::set_engine (AudioEngine* e)
{
_engine = e;
}
void
-ARDOUR::Port::ensure_monitor_input (bool yn)
+Port::ensure_monitor_input (bool yn)
{
if (_jack_port) {
jack_port_ensure_monitor (_jack_port, yn);
@@ -288,7 +322,7 @@ ARDOUR::Port::ensure_monitor_input (bool yn)
}
bool
-ARDOUR::Port::monitoring_input () const
+Port::monitoring_input () const
{
if (_jack_port) {
return jack_port_monitoring_input (_jack_port);
@@ -298,7 +332,7 @@ ARDOUR::Port::monitoring_input () const
}
void
-ARDOUR::Port::reset ()
+Port::reset ()
{
_last_monitor = false;
@@ -308,7 +342,7 @@ ARDOUR::Port::reset ()
}
void
-ARDOUR::Port::recompute_total_latency () const
+Port::recompute_total_latency () const
{
#ifdef HAVE_JACK_RECOMPUTE_LATENCY
if (_jack_port) {
@@ -318,7 +352,7 @@ ARDOUR::Port::recompute_total_latency () const
}
nframes_t
-ARDOUR::Port::total_latency () const
+Port::total_latency () const
{
if (_jack_port) {
return jack_port_get_total_latency (_engine->jack (), _jack_port);
@@ -328,7 +362,7 @@ ARDOUR::Port::total_latency () const
}
int
-ARDOUR::Port::reestablish ()
+Port::reestablish ()
{
if (!_jack_port) {
return 0;
@@ -348,7 +382,7 @@ ARDOUR::Port::reestablish ()
int
-ARDOUR::Port::reconnect ()
+Port::reconnect ()
{
/* caller must hold process lock; intended to be used only after reestablish() */
@@ -367,7 +401,7 @@ ARDOUR::Port::reconnect ()
/** @param n Short name */
int
-ARDOUR::Port::set_name (std::string const & n)
+Port::set_name (std::string const & n)
{
assert (_name.find_first_of (':') == std::string::npos);
@@ -386,15 +420,48 @@ ARDOUR::Port::set_name (std::string const & n)
}
void
-ARDOUR::Port::set_latency (nframes_t n)
+Port::set_latency (nframes_t n)
{
_latency = n;
}
void
-ARDOUR::Port::request_monitor_input (bool yn)
+Port::request_monitor_input (bool yn)
{
if (_jack_port) {
jack_port_request_monitor (_jack_port, yn);
}
}
+
+void
+Port::check_buffer_status ()
+{
+ if (external() && receives_input()) {
+ if (!externally_connected()) {
+ if (!_connections.empty()) {
+
+ /* There are no external connections, so the
+ external port buffer will be the silent buffer. We cannot write into it.
+ But we have to write somewhere because there is at least one internal
+ connection that is supplying us with data.
+ */
+
+ if (!using_internal_data()) {
+ use_internal_data ();
+ }
+
+ } else {
+
+ /* There are no external connections and no internal ones
+ either, so we can revert to use the externally supplied
+ buffer which will be silent (whatever the semantics of
+ that are for a particular data type.
+ */
+
+ if (using_internal_data()) {
+ use_external_data ();
+ }
+ }
+ }
+ }
+}
diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc
index a541ae0423..a528a4587c 100644
--- a/libs/ardour/processor.cc
+++ b/libs/ardour/processor.cc
@@ -105,13 +105,6 @@ Processor::set_placement (Placement p)
}
}
-void
-Processor::set_active (bool yn)
-{
- _active = yn;
- ActiveChanged ();
-}
-
XMLNode&
Processor::get_state (void)
{
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index fab3c085db..14a8537068 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -35,6 +35,7 @@
#include <ardour/plugin_insert.h>
#include <ardour/port_insert.h>
#include <ardour/send.h>
+#include <ardour/internal_send.h>
#include <ardour/session.h>
#include <ardour/utils.h>
#include <ardour/configuration.h>
@@ -1229,6 +1230,11 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
int
Route::add_processors (const ProcessorList& others, ProcessorStreams* err)
{
+ /* NOTE: this is intended to be used ONLY when copying
+ processors from another Route. Hence the subtle
+ differences between this and ::add_processor()
+ */
+
ChanCount old_pmo = processor_max_outs;
if (!_session.engine().connected()) {
@@ -1292,7 +1298,7 @@ Route::disable_processors (Placement p)
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((*i)->placement() == p) {
- (*i)->set_active (false);
+ (*i)->deactivate ();
}
}
@@ -1308,7 +1314,7 @@ Route::disable_processors ()
Glib::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
- (*i)->set_active (false);
+ (*i)->deactivate ();
}
_session.set_dirty ();
@@ -1325,7 +1331,7 @@ Route::disable_plugins (Placement p)
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (boost::dynamic_pointer_cast<PluginInsert> (*i) && (*i)->placement() == p) {
- (*i)->set_active (false);
+ (*i)->deactivate ();
}
}
@@ -1342,7 +1348,7 @@ Route::disable_plugins ()
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (boost::dynamic_pointer_cast<PluginInsert> (*i)) {
- (*i)->set_active (false);
+ (*i)->deactivate ();
}
}
@@ -1367,7 +1373,7 @@ Route::ab_plugins (bool forward)
}
if ((*i)->active()) {
- (*i)->set_active (false);
+ (*i)->deactivate ();
(*i)->set_next_ab_is_active (true);
} else {
(*i)->set_next_ab_is_active (false);
@@ -1385,9 +1391,9 @@ Route::ab_plugins (bool forward)
}
if ((*i)->get_next_ab_is_active()) {
- (*i)->set_active (true);
+ (*i)->activate ();
} else {
- (*i)->set_active (false);
+ (*i)->deactivate ();
}
}
}
@@ -1602,9 +1608,11 @@ Route::_reset_processor_counts (ProcessorStreams* err)
} else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
++send_cnt;
+ } else if (boost::dynamic_pointer_cast<InternalSend> (*r) != 0) {
+ ++send_cnt;
}
}
-
+
if (insert_cnt == 0) {
if (send_cnt) {
goto recompute;
@@ -1665,20 +1673,32 @@ Route::_reset_processor_counts (ProcessorStreams* err)
for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
boost::shared_ptr<Send> s;
+ boost::shared_ptr<InternalSend> is;
if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
+
+ /* don't pay any attention to send output configuration, since it doesn't
+ affect the route.
+ */
+
if (r == _processors.begin()) {
s->expect_inputs (n_inputs());
} else {
s->expect_inputs ((*prev)->output_streams());
}
+ } else if ((is = boost::dynamic_pointer_cast<InternalSend> (*r)) != 0) {
+
+ /* XXX ditto, but clean this inheritance pattern up someday soon */
+
+ if (r == _processors.begin()) {
+ is->expect_inputs (n_inputs());
+ } else {
+ is->expect_inputs ((*prev)->output_streams());
+ }
+
} else {
- /* don't pay any attention to send output configuration, since it doesn't
- affect the route.
- */
-
max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
max_midi = max ((*r)->output_streams ().n_midi(), max_midi);
}
@@ -1711,8 +1731,6 @@ Route::apply_some_processor_counts (list<ProcessorCount>& iclist)
ProcessorCount& pc (*i);
- cerr << "now applying for " << (*i).processor->name() << " in = " << pc.in.n_audio() << " out = " << pc.out.n_audio() << endl;
-
if (pc.processor->configure_io (pc.in, pc.out)) {
return -1;
}
@@ -1743,8 +1761,6 @@ Route::check_some_processor_counts (list<ProcessorCount>& iclist, ChanCount requ
for (i = iclist.begin(); i != iclist.end(); ++i, ++index) {
- cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n";
-
if (!(*i).processor->can_support_io_configuration (required_inputs, (*i).out)) {
if (err) {
err->index = index;
@@ -1853,7 +1869,11 @@ Route::all_processors_flip ()
bool first_is_on = _processors.front()->active();
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
- (*i)->set_active (!first_is_on);
+ if (first_is_on) {
+ (*i)->deactivate ();
+ } else {
+ (*i)->activate ();
+ }
}
_session.set_dirty ();
@@ -1874,7 +1894,11 @@ Route::all_processors_active (Placement p, bool state)
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((*i)->placement() == p) {
- (*i)->set_active (state);
+ if (state) {
+ (*i)->activate ();
+ } else {
+ (*i)->deactivate ();
+ }
}
}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 58352a5dfe..d562ddff3f 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -140,7 +140,7 @@ Send::set_state(const XMLNode& node)
if ((*niter)->name() == "IOProcessor") {
insert_node = *niter;
} else if ((*niter)->name() == X_("Automation")) {
- _io->set_automation_state (*(*niter), Evoral::Parameter(GainAutomation));
+ // _io->set_automation_state (*(*niter), Evoral::Parameter(GainAutomation));
}
}
@@ -165,10 +165,10 @@ Send::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
_io->deliver_output (sendbufs, start_frame, end_frame, nframes, offset);
if (_metering) {
- if (_io->_gain == 0) {
- _io->_meter->reset();
+ if (_io->effective_gain() == 0) {
+ _io->peak_meter().reset();
} else {
- _io->_meter->run_in_place(_io->output_buffers(), start_frame, end_frame, nframes, offset);
+ _io->peak_meter().run_in_place(_io->output_buffers(), start_frame, end_frame, nframes, offset);
}
}
@@ -176,7 +176,7 @@ Send::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
_io->silence (nframes, offset);
if (_metering) {
- _io->_meter->reset();
+ _io->peak_meter().reset();
}
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 59b873e87f..6e7fe3a0f6 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -72,6 +72,7 @@
#include <ardour/named_selection.h>
#include <ardour/crossfade.h>
#include <ardour/playlist.h>
+#include <ardour/internal_send.h>
#include <ardour/click.h>
#include <ardour/data_type.h>
#include <ardour/buffer_set.h>
@@ -1822,7 +1823,7 @@ Session::set_remote_control_ids ()
}
-Session::RouteList
+RouteList
Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
{
char bus_name[32];
@@ -3685,6 +3686,8 @@ Session::add_processor (Processor* processor)
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
_sends.insert (_sends.begin(), send);
+ } else if (dynamic_cast<InternalSend *> (processor) != 0) {
+ /* relax */
} else {
fatal << _("programming error: unknown type of Insert created!") << endmsg;
/*NOTREACHED*/
@@ -3710,6 +3713,8 @@ Session::remove_processor (Processor* processor)
}
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
_plugin_inserts.remove (plugin_insert);
+ } else if (dynamic_cast<InternalSend *> (processor) != 0) {
+ /* relax */
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
if (x != _sends.end()) {