summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-10-03 03:16:19 +0000
committerDavid Robillard <d@drobilla.net>2008-10-03 03:16:19 +0000
commitec6ab8a04811acd1b548a23ab8f95c27797267fe (patch)
tree4b4106dd6cb9a10f56eb423f3e8291f99a7ce2d1 /libs/ardour
parent612850c41b880ef2971a87cd1afa50c077b32c8d (diff)
Apply panners/automation patch from torbenh (Panner is-a Processor).
git-svn-id: svn://localhost/ardour2/branches/3.0@3848 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/io.h7
-rw-r--r--libs/ardour/ardour/panner.h83
-rw-r--r--libs/ardour/automatable.cc19
-rw-r--r--libs/ardour/io.cc49
-rw-r--r--libs/ardour/ladspa_plugin.cc4
-rw-r--r--libs/ardour/lv2_plugin.cc2
-rw-r--r--libs/ardour/panner.cc190
-rw-r--r--libs/ardour/plugin_insert.cc13
-rw-r--r--libs/ardour/processor.cc2
-rw-r--r--libs/ardour/route.cc7
10 files changed, 213 insertions, 163 deletions
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 34ffad94ce..af26319e82 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -228,15 +228,16 @@ class IO : public SessionObject, public AutomatableControls, public Latent
/* automation */
struct GainControl : public AutomationControl {
- GainControl (std::string name, IO& i, boost::shared_ptr<AutomationList> al)
- : AutomationControl (i._session, al->parameter(), al, name)
+ GainControl (std::string name, IO* i, const Evoral::Parameter &param,
+ boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>() )
+ : AutomationControl (i->_session, param, al, name )
, _io (i)
{}
void set_value (float val);
float get_value (void) const;
- IO& _io;
+ IO* _io;
};
boost::shared_ptr<GainControl> gain_control() {
diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h
index 7b4f2d1039..7019f5e5ac 100644
--- a/libs/ardour/ardour/panner.h
+++ b/libs/ardour/ardour/panner.h
@@ -32,12 +32,15 @@
#include <ardour/types.h>
#include <ardour/automation_control.h>
+#include <ardour/processor.h>
+#include <ardour/session.h>
using std::istream;
using std::ostream;
namespace ARDOUR {
+class Route;
class Session;
class Panner;
class BufferSet;
@@ -102,21 +105,7 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful
bool _muted;
- struct PanControllable : public AutomationControl {
- PanControllable (Session& s, std::string name, StreamPanner& p, Evoral::Parameter param)
- : AutomationControl (s, param,
- boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
- , panner (p)
- { assert(param.type() != NullAutomation); }
-
- AutomationList* alist() { return (AutomationList*)_list.get(); }
- StreamPanner& panner;
-
- void set_value (float);
- float get_value (void) const;
- };
-
- boost::shared_ptr<PanControllable> _control;
+ boost::shared_ptr<AutomationControl> _control;
void add_state (XMLNode&);
virtual void update () = 0;
@@ -197,7 +186,8 @@ class Multi2dPanner : public StreamPanner
void update ();
};
-class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public sigc::trackable
+
+class Panner : public Processor
{
public:
struct Output {
@@ -211,37 +201,43 @@ class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public s
};
+ //Panner (std::string name, Session&, int _num_bufs);
Panner (string name, Session&);
virtual ~Panner ();
+ void clear_panners ();
+
+
/// The fundamental Panner function
- void distribute(BufferSet& src, BufferSet& dest, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset);
+ void set_automation_state (AutoState);
+ AutoState automation_state() const;
+ void set_automation_style (AutoStyle);
+ AutoStyle automation_style() const;
+ bool touching() const;
+
+ bool is_in_place () const { return false; }
+ bool is_out_of_place () const { return true; }
+ bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; };
+
+ void run_out_of_place(BufferSet& src, BufferSet& dest, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset);
+
+ //void* get_inline_gui() const = 0;
+ //void* get_full_gui() const = 0;
bool bypassed() const { return _bypassed; }
void set_bypassed (bool yn);
StreamPanner* add ();
void remove (uint32_t which);
- void clear ();
void reset (uint32_t noutputs, uint32_t npans);
- void snapshot (nframes_t now);
- void transport_stopped (nframes_t frame);
- void clear_automation ();
- void set_automation_state (AutoState);
- AutoState automation_state() const;
- void set_automation_style (AutoStyle);
- AutoStyle automation_style() const;
- bool touching() const;
XMLNode& get_state (void);
XMLNode& state (bool full);
int set_state (const XMLNode&);
- sigc::signal<void> Changed;
-
static bool equivalent (pan_t a, pan_t b) {
return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner
}
@@ -251,7 +247,6 @@ class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public s
Output& output (uint32_t n) { return outputs[n]; }
std::vector<Output> outputs;
- Session& session() const { return _session; }
enum LinkDirection {
SameDirection,
@@ -264,6 +259,10 @@ class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public s
bool linked() const { return _linked; }
void set_linked (bool yn);
+ StreamPanner &streampanner( uint32_t n ) const { assert( n < _streampanners.size() ); return *_streampanners[n]; }
+ uint32_t npanners() const { return _streampanners.size(); }
+
+ sigc::signal<void> Changed;
sigc::signal<void> LinkStateChanged;
sigc::signal<void> StateChanged; /* for bypass */
@@ -277,10 +276,31 @@ class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public s
int load ();
+ struct PanControllable : public AutomationControl {
+ PanControllable (Session& s, std::string name, Panner& p, Evoral::Parameter param)
+ : AutomationControl (s, param,
+ boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
+ , panner (p)
+ { assert(param.type() != NullAutomation); }
+
+ AutomationList* alist() { return (AutomationList*)_list.get(); }
+ Panner& panner;
+
+ void set_value (float);
+ float get_value (void) const;
+ };
+
+ boost::shared_ptr<AutomationControl> pan_control ( int id, int chan=0 ) {
+ return boost::dynamic_pointer_cast<AutomationControl>( control( Evoral::Parameter (PanAutomation, chan, id) ));
+ }
+
+ boost::shared_ptr<const AutomationControl> pan_control ( int id, int chan=0 ) const {
+ return boost::dynamic_pointer_cast<const AutomationControl>( control( Evoral::Parameter (PanAutomation, chan, id) ));
+ }
+
private:
void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, nframes_t offset, gain_t gain_coeff);
-
- Session& _session;
+ std::vector<StreamPanner*> _streampanners;
uint32_t current_outs;
bool _linked;
bool _bypassed;
@@ -291,7 +311,6 @@ class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public s
/* old school automation handling */
std::string automation_path;
- void set_name (std::string);
};
} // namespace ARDOUR
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc
index a4d0de0958..c145c3c501 100644
--- a/libs/ardour/automatable.cc
+++ b/libs/ardour/automatable.cc
@@ -29,6 +29,7 @@
#include <ardour/automatable.h>
#include <ardour/midi_track.h>
#include <ardour/plugin_insert.h>
+#include <ardour/panner.h>
#include "i18n.h"
@@ -67,7 +68,7 @@ Automatable::old_set_automation_state (const XMLNode& node)
if (sstr.fail()) {
break;
}
- mark_automation_visible (Evoral::Parameter(PluginAutomation, what), true);
+ mark_automation_visible (Evoral::Parameter(PluginAutomation, 0, what), true);
}
}
@@ -110,7 +111,7 @@ Automatable::load_automation (const string& path)
in >> when; if (!in) goto bad;
in >> value; if (!in) goto bad;
- Evoral::Parameter param(PluginAutomation, port);
+ Evoral::Parameter param(PluginAutomation, 0, port);
/* FIXME: this is legacy and only used for plugin inserts? I think? */
boost::shared_ptr<Evoral::Control> c = control (param, true);
c->list()->add (when, value);
@@ -234,10 +235,14 @@ Automatable::set_automation_state (const XMLNode& node, Evoral::Parameter legacy
}
boost::shared_ptr<Evoral::Control> existing = control(param);
- if (existing)
+ if (existing) {
existing->set_list(al);
- else
- add_control(control_factory(param));
+ } else {
+ boost::shared_ptr<Evoral::Control> newcontrol = control_factory(param);
+ add_control(newcontrol);
+ newcontrol->set_list(al);
+ warning << "Control did not exist";
+ }
} else {
error << "Expected AutomationList node, got '" << (*niter)->name() << endmsg;
@@ -401,6 +406,10 @@ Automatable::control_factory(const Evoral::Parameter& param)
control = new MidiTrack::MidiControl((MidiTrack*)this, param);
} else if (param.type() == PluginAutomation) {
control = new PluginInsert::PluginControl((PluginInsert*)this, param);
+ } else if (param.type() == GainAutomation) {
+ control = new IO::GainControl( X_("gaincontrol"), (IO*)this, param);
+ } else if (param.type() == PanAutomation) {
+ control = new Panner::PanControllable( ((Panner *)this)->session(), X_("panner"), *(Panner *)this, param);
} else {
control = new AutomationControl(_a_session, param);
}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 0343545936..b994b17358 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -140,8 +140,7 @@ IO::IO (Session& s, const string& name,
boost::shared_ptr<AutomationList> gl(
new AutomationList(Evoral::Parameter(GainAutomation)));
- _gain_control = boost::shared_ptr<GainControl>(
- new GainControl(X_("gaincontrol"), *this, gl));
+ _gain_control = boost::shared_ptr<GainControl>( new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl ));
add_control(_gain_control);
@@ -183,7 +182,7 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
new AutomationList(Evoral::Parameter(GainAutomation)));
_gain_control = boost::shared_ptr<GainControl>(
- new GainControl(X_("gaincontrol"), *this, gl));
+ new GainControl( X_("gaincontrol"), this, Evoral::Parameter(GainAutomation), gl));
add_control(_gain_control);
@@ -265,10 +264,10 @@ IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
if (dg != _gain || dg != 1.0)
Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert);
}
-
+
// Use the panner to distribute audio to output port buffers
- if (_panner && !_panner->empty() && !_panner->bypassed()) {
- _panner->distribute (bufs, output_buffers(), start_frame, end_frame, nframes, offset);
+ if( _panner && _panner->npanners() && !_panner->bypassed()) {
+ _panner->run_out_of_place(bufs, output_buffers(), start_frame, end_frame, nframes, offset);
} else {
const DataType type = DataType::AUDIO;
@@ -1402,6 +1401,7 @@ IO::set_state (const XMLNode& node)
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
+ // Old school Panner.
if ((*iter)->name() == "Panner") {
if (_panner == 0) {
_panner = new Panner (_name, _session);
@@ -1409,6 +1409,15 @@ IO::set_state (const XMLNode& node)
_panner->set_state (**iter);
}
+ if ((*iter)->name() == "Processor") {
+ if ((*iter)->property ("type") && ((*iter)->property ("type")->value() == "panner" ) ) {
+ if (_panner == 0) {
+ _panner = new Panner (_name, _session);
+ }
+ _panner->set_state (**iter);
+ }
+ }
+
if ((*iter)->name() == X_("Automation")) {
set_automation_state (*(*iter), Evoral::Parameter(GainAutomation));
@@ -1432,6 +1441,8 @@ IO::set_state (const XMLNode& node)
port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal));
}
+ if( !_panner )
+ _panner = new Panner( _name, _session );
if (panners_legal) {
reset_panner ();
} else {
@@ -2223,10 +2234,9 @@ IO::GainControl::set_value (float val)
if (val > 1.99526231f)
val = 1.99526231f;
- _user_value = val;
- _io.set_gain (val, this);
+ _io->set_gain (val, this);
- Changed(); /* EMIT SIGNAL */
+ AutomationControl::set_value(val);
}
float
@@ -2270,7 +2280,7 @@ void
IO::clear_automation ()
{
data().clear (); // clears gain automation
- _panner->clear_automation ();
+ _panner->data().clear();
}
void
@@ -2341,10 +2351,12 @@ IO::set_gain (gain_t val, void *src)
_gain = val;
}
+ /*
if (_session.transport_stopped() && src != 0 && src != this && _gain_control->automation_write()) {
_gain_control->list()->add (_session.transport_frame(), val);
}
+ */
_session.set_dirty();
}
@@ -2352,16 +2364,16 @@ IO::set_gain (gain_t val, void *src)
void
IO::start_pan_touch (uint32_t which)
{
- if (which < _panner->size()) {
- (*_panner)[which]->pan_control()->start_touch();
+ if (which < _panner->npanners()) {
+ (*_panner).pan_control(which)->start_touch();
}
}
void
IO::end_pan_touch (uint32_t which)
{
- if (which < _panner->size()) {
- (*_panner)[which]->pan_control()->stop_touch();
+ if (which < _panner->npanners()) {
+ (*_panner).pan_control(which)->stop_touch();
}
}
@@ -2370,12 +2382,17 @@ void
IO::automation_snapshot (nframes_t now, bool force)
{
AutomatableControls::automation_snapshot (now, force);
+ // XXX: This seems to be wrong.
+ // drobilla: shouldnt automation_snapshot for panner be called
+ // "automagically" because its an Automatable now ?
+ //
+ // we could dump this whole method then. <3
if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
- _panner->snapshot (now);
+ _panner->automation_snapshot (now, force);
}
- _panner->snapshot (now);
+ _panner->automation_snapshot (now, force);
_last_automation_snapshot = now;
}
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index d756bbfcbe..66c6be871b 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -297,7 +297,7 @@ LadspaPlugin::set_parameter (uint32_t which, float val)
if (which < _descriptor->PortCount) {
_shadow_data[which] = (LADSPA_Data) val;
#if 0
- ParameterChanged (Parameter(PluginAutomation, which), val); /* EMIT SIGNAL */
+ ParameterChanged (Parameter(PluginAutomation, 0, which), val); /* EMIT SIGNAL */
if (which < parameter_count() && controls[which]) {
controls[which]->Changed ();
@@ -503,7 +503,7 @@ LadspaPlugin::automatable () const
if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
LADSPA_IS_PORT_CONTROL(port_descriptor (i))){
- ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, i));
+ ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
}
}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 231d267468..0260e02560 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -390,7 +390,7 @@ LV2Plugin::automatable () const
for (uint32_t i = 0; i < parameter_count(); ++i){
if (parameter_is_input(i) && parameter_is_control(i)) {
- ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, i));
+ ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
}
}
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index 3ff4caf4f3..c616a6fe00 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -65,19 +65,19 @@ static pan_t direct_control_to_pan (double fract) {
return fract;
}
-static double direct_pan_to_control (pan_t val) {
- return val;
-}
+
+//static double direct_pan_to_control (pan_t val) {
+// return val;
+//}
StreamPanner::StreamPanner (Panner& p, Evoral::Parameter param)
: parent (p)
- , _control (new PanControllable(p.session(), X_("panner"), *this, param))
{
assert(param.type() != NullAutomation);
_muted = false;
- parent.session().add_controllable (_control);
+ _control = boost::dynamic_pointer_cast<AutomationControl>( parent.control( param, true ) );
x = 0.5;
y = 0.5;
@@ -89,17 +89,16 @@ StreamPanner::~StreamPanner ()
}
void
-StreamPanner::PanControllable::set_value (float val)
+Panner::PanControllable::set_value (float val)
{
- panner.set_position (direct_control_to_pan (val));
+ panner.streampanner(parameter().id()).set_position (direct_control_to_pan (val));
+ AutomationControl::set_value(val);
}
float
-StreamPanner::PanControllable::get_value (void) const
+Panner::PanControllable::get_value (void) const
{
- float xpos;
- panner.get_effective_position (xpos);
- return direct_pan_to_control (xpos);
+ return AutomationControl::get_value();
}
void
@@ -376,7 +375,7 @@ EqualPowerStereoPanner::update ()
desired_right = panR * (scale * panR + 1.0f - scale);
effective_x = x;
- _control->set_value(x);
+ //_control->set_value(x);
}
void
@@ -404,7 +403,6 @@ EqualPowerStereoPanner::distribute_automated (AudioBuffer& srcbuf, BufferSet& ob
if (nframes > 0) {
effective_x = buffers[0][nframes-1];
- _control->set_value(effective_x); // signal, update UI
}
if (_muted) {
@@ -473,9 +471,7 @@ EqualPowerStereoPanner::state (bool full_state)
root->add_property (X_("x"), buf);
root->add_property (X_("type"), EqualPowerStereoPanner::name);
- XMLNode* autonode = new XMLNode (X_("Automation"));
- autonode->add_child_nocopy (((AutomationList*)_control->list().get())->state (full_state));
- root->add_child_nocopy (*autonode);
+ // XXX: dont save automation here... its part of the automatable panner now.
StreamPanner::add_state (*root);
@@ -560,7 +556,6 @@ Multi2dPanner::update ()
}
effective_x = x;
- _control->set_value(x);
}
void
@@ -704,8 +699,9 @@ Multi2dPanner::set_state (const XMLNode& node)
/*---------------------------------------------------------------------- */
Panner::Panner (string name, Session& s)
- : _session (s)
+ : Processor(s, name, PostFader)
{
+ //set_name_old_auto (name);
set_name (name);
_linked = false;
@@ -737,6 +733,7 @@ Panner::set_link_direction (LinkDirection ld)
}
}
+
void
Panner::set_bypassed (bool yn)
{
@@ -753,12 +750,14 @@ Panner::reset (uint32_t nouts, uint32_t npans)
uint32_t n;
bool changed = false;
- if (nouts < 2 || (nouts == outputs.size() && npans == size())) {
+ //configure_io( ChanCount( DataType::AUDIO, nout ), ChanCount( DataType::AUDIO, nin ) )
+
+ if (nouts < 2 || (nouts == outputs.size() && npans == _streampanners.size())) {
return;
}
- n = size();
- clear ();
+ n = _streampanners.size();
+ clear_panners ();
if (n != npans) {
changed = true;
@@ -788,7 +787,7 @@ Panner::reset (uint32_t nouts, uint32_t npans)
outputs.push_back (Output (1.0, 0));
for (n = 0; n < npans; ++n) {
- push_back (new EqualPowerStereoPanner (*this, Evoral::Parameter(PanAutomation, n)));
+ _streampanners.push_back (new EqualPowerStereoPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
@@ -798,7 +797,7 @@ Panner::reset (uint32_t nouts, uint32_t npans)
outputs.push_back (Output (1.0, 1.0));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
@@ -810,7 +809,7 @@ Panner::reset (uint32_t nouts, uint32_t npans)
outputs.push_back (Output (0, 1.0));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
@@ -823,7 +822,7 @@ Panner::reset (uint32_t nouts, uint32_t npans)
outputs.push_back (Output (0.5, 0.75));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
@@ -835,13 +834,13 @@ Panner::reset (uint32_t nouts, uint32_t npans)
}
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
}
- for (iterator x = begin(); x != end(); ++x) {
+ for (std::vector<StreamPanner*>::iterator x = _streampanners.begin(); x != _streampanners.end(); ++x) {
(*x)->update ();
}
@@ -857,16 +856,16 @@ Panner::reset (uint32_t nouts, uint32_t npans)
float left;
float right;
- front()->get_position (left);
- back()->get_position (right);
+ _streampanners.front()->get_position (left);
+ _streampanners.back()->get_position (right);
if (changed || ((left == 0.5) && (right == 0.5))) {
- front()->set_position (0.0);
- front()->pan_control()->list()->reset_default (0.0);
+ _streampanners.front()->set_position (0.0);
+ _streampanners.front()->pan_control()->list()->reset_default (0.0);
- back()->set_position (1.0);
- back()->pan_control()->list()->reset_default (1.0);
+ _streampanners.back()->set_position (1.0);
+ _streampanners.back()->pan_control()->list()->reset_default (1.0);
changed = true;
}
@@ -883,28 +882,28 @@ void
Panner::remove (uint32_t which)
{
vector<StreamPanner*>::iterator i;
- for (i = begin(); i != end() && which; ++i, --which);
+ for (i = _streampanners.begin(); i != _streampanners.end() && which; ++i, --which);
- if (i != end()) {
+ if (i != _streampanners.end()) {
delete *i;
- erase (i);
+ _streampanners.erase (i);
}
}
void
-Panner::clear ()
+Panner::clear_panners ()
{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
delete *i;
}
- vector<StreamPanner*>::clear ();
+ _streampanners.clear ();
}
void
Panner::set_automation_style (AutoStyle style)
{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
((AutomationList*)(*i)->pan_control()->list().get())->set_automation_style (style);
}
_session.set_dirty ();
@@ -913,7 +912,7 @@ Panner::set_automation_style (AutoStyle style)
void
Panner::set_automation_state (AutoState state)
{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
((AutomationList*)(*i)->pan_control()->list().get())->set_automation_state (state);
}
_session.set_dirty ();
@@ -923,7 +922,7 @@ AutoState
Panner::automation_state () const
{
if (!empty()) {
- return ((AutomationList*)front()->pan_control()->list().get())->automation_state ();
+ return ((AutomationList*)_streampanners.front()->pan_control()->list().get())->automation_state ();
} else {
return Off;
}
@@ -933,38 +932,12 @@ AutoStyle
Panner::automation_style () const
{
if (!empty()) {
- return ((AutomationList*)front()->pan_control()->list().get())->automation_style ();
+ return ((AutomationList*)_streampanners.front()->pan_control()->list().get())->automation_style ();
} else {
return Absolute;
}
}
-void
-Panner::transport_stopped (nframes_t frame)
-{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- ((AutomationList*)(*i)->pan_control()->list().get())->reposition_for_rt_add (frame);
- }
-}
-
-void
-Panner::snapshot (nframes_t now)
-{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- AutomationList* list = ((AutomationList*)(*i)->pan_control()->list().get());
- if (list->automation_write())
- list->rt_add(now, (*i)->pan_control()->get_value());
- }
-}
-
-void
-Panner::clear_automation ()
-{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- (*i)->pan_control()->list()->clear ();
- }
- _session.set_dirty ();
-}
struct PanPlugins {
string name;
@@ -987,13 +960,20 @@ Panner::get_state (void)
XMLNode&
Panner::state (bool full)
{
- XMLNode* root = new XMLNode (X_("Panner"));
+ XMLNode& node = Processor::state(full);
+
+ node.add_property ("type", "panner");
+
char buf[32];
- root->add_property (X_("linked"), (_linked ? "yes" : "no"));
- root->add_property (X_("link_direction"), enum_2_string (_link_direction));
- root->add_property (X_("bypassed"), (bypassed() ? "yes" : "no"));
+ node.add_property (X_("linked"), (_linked ? "yes" : "no"));
+ node.add_property (X_("link_direction"), enum_2_string (_link_direction));
+ node.add_property (X_("bypassed"), (bypassed() ? "yes" : "no"));
+ snprintf (buf, sizeof (buf), "%d", _streampanners.size());
+ node.add_property (X_("ins"), buf);
+ snprintf (buf, sizeof (buf), "%d", outputs.size());
+ node.add_property (X_("outs"), buf);
/* add each output */
for (vector<Panner::Output>::iterator o = outputs.begin(); o != outputs.end(); ++o) {
@@ -1002,14 +982,15 @@ Panner::state (bool full)
onode->add_property (X_("x"), buf);
snprintf (buf, sizeof (buf), "%.12g", (*o).y);
onode->add_property (X_("y"), buf);
- root->add_child_nocopy (*onode);
+ node.add_child_nocopy (*onode);
}
- for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) {
- root->add_child_nocopy ((*i)->state (full));
+ for (vector<StreamPanner*>::const_iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
+ node.add_child_nocopy ((*i)->state (full));
}
- return *root;
+
+ return node;
}
int
@@ -1022,7 +1003,14 @@ Panner::set_state (const XMLNode& node)
StreamPanner* sp;
LocaleGuard lg (X_("POSIX"));
- clear ();
+ clear_panners ();
+
+ Processor::set_state(node);
+
+ ChanCount ins = ChanCount::ZERO;
+ ChanCount outs = ChanCount::ZERO;
+
+ // XXX: this might not be necessary anymore
outputs.clear ();
if ((prop = node.property (X_("linked"))) != 0) {
@@ -1033,6 +1021,15 @@ Panner::set_state (const XMLNode& node)
if ((prop = node.property (X_("bypassed"))) != 0) {
set_bypassed (prop->value() == "yes");
}
+
+ if ((prop = node.property (X_("ins"))) != 0) {
+ ins.set_audio(atoi(prop->value().c_str()));
+ }
+
+ if ((prop = node.property (X_("outs"))) != 0) {
+ outs.set_audio(atoi(prop->value().c_str()));
+ }
+
if ((prop = node.property (X_("link_direction"))) != 0) {
LinkDirection ld; /* here to provide type information */
@@ -1071,10 +1068,10 @@ Panner::set_state (const XMLNode& node)
assumption, but its still an assumption.
*/
- sp = pan_plugins[i].factory (*this, Evoral::Parameter(PanAutomation, 0));
+ sp = pan_plugins[i].factory (*this, Evoral::Parameter(PanAutomation, 0, i));
if (sp->set_state (**niter) == 0) {
- push_back (sp);
+ _streampanners.push_back (sp);
}
break;
@@ -1097,6 +1094,7 @@ Panner::set_state (const XMLNode& node)
}
}
+ reset(ins.n_audio(), outs.n_audio());
/* don't try to do old-school automation loading if it wasn't marked as existing */
if ((prop = node.property (X_("automation")))) {
@@ -1109,12 +1107,10 @@ Panner::set_state (const XMLNode& node)
return 0;
}
-
-
bool
Panner::touching () const
{
- for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::const_iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (((AutomationList*)(*i)->pan_control()->list().get())->touching ()) {
return true;
}
@@ -1135,7 +1131,7 @@ Panner::set_position (float xpos, StreamPanner& orig)
if (_link_direction == SameDirection) {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, true);
} else {
@@ -1148,7 +1144,7 @@ Panner::set_position (float xpos, StreamPanner& orig)
} else {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, true);
} else {
@@ -1174,7 +1170,7 @@ Panner::set_position (float xpos, float ypos, StreamPanner& orig)
if (_link_direction == SameDirection) {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, ypos, true);
} else {
@@ -1192,7 +1188,7 @@ Panner::set_position (float xpos, float ypos, StreamPanner& orig)
} else {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, ypos, true);
} else {
@@ -1224,7 +1220,7 @@ Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig)
if (_link_direction == SameDirection) {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, ypos, zpos, true);
} else {
@@ -1245,7 +1241,7 @@ Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig)
} else {
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
if (*i == &orig) {
(*i)->set_position (xpos, ypos, true);
} else {
@@ -1332,13 +1328,13 @@ Panner::distribute_no_automation (BufferSet& inbufs, BufferSet& outbufs, nframes
BufferSet::audio_iterator i = inbufs.audio_begin();
- for (iterator pan = begin(); pan != end() && i != inbufs.audio_end(); ++pan, ++i) {
+ for (vector<StreamPanner*>::iterator pan = _streampanners.begin(); pan != _streampanners.end() && i != inbufs.audio_end(); ++pan, ++i) {
(*pan)->distribute (*i, outbufs, gain_coeff, nframes);
}
}
void
-Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
+Panner::run_out_of_place (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
{
if (outbufs.count().n_audio() == 0) {
// Failing to deliver audio we were asked to deliver is a bug
@@ -1385,7 +1381,7 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame
}
// More than 1 output, we should have 1 panner for each input
- assert(size() == inbufs.count().n_audio());
+ //assert(_streampanners.size() == inbufs.count().n_audio());
/* the terrible silence ... */
for (BufferSet::audio_iterator i = outbufs.audio_begin(); i != outbufs.audio_end(); ++i) {
@@ -1393,19 +1389,21 @@ Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame
}
BufferSet::audio_iterator i = inbufs.audio_begin();
- for (iterator pan = begin(); pan != end(); ++pan, ++i) {
+ for (vector<StreamPanner*>::iterator pan = _streampanners.begin(); pan != _streampanners.end(); ++pan, ++i) {
(*pan)->distribute_automated (*i, outbufs, start_frame, end_frame, nframes, _session.pan_automation_buffer());
}
}
/* old school automation handling */
+/*
void
Panner::set_name (string str)
{
automation_path = Glib::build_filename(_session.automation_dir(),
_session.snap_name() + "-pan-" + legalize_for_path (str) + ".automation");
}
+*/
int
Panner::load ()
@@ -1413,7 +1411,7 @@ Panner::load ()
char line[128];
uint32_t linecnt = 0;
float version;
- iterator sp;
+ vector<StreamPanner*>::iterator sp;
LocaleGuard lg (X_("POSIX"));
if (automation_path.length() == 0) {
@@ -1433,7 +1431,7 @@ Panner::load ()
return -1;
}
- sp = begin();
+ sp = _streampanners.begin();
while (in.getline (line, sizeof(line), '\n')) {
@@ -1458,7 +1456,7 @@ Panner::load ()
if (strcmp (line, "begin") == 0) {
- if (sp == end()) {
+ if (sp == _streampanners.end()) {
error << string_compose (_("too many panner states found in pan automation file %1"),
automation_path)
<< endmsg;
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 97ce2d7c01..eede6b3388 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -80,7 +80,10 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node)
throw failed_constructor();
}
- set_automatable ();
+ // XXX: This would dump all automation, which has already been loaded by
+ // Processor. But this could also have been related to the Parameter change..
+ // will look into this later.
+ //set_automatable ();
{
Glib::Mutex::Lock em (_session.engine().process_lock());
@@ -630,7 +633,7 @@ PluginInsert::state (bool full)
node.add_child_nocopy (_plugins[0]->get_state());
/* add port automation state */
- XMLNode *autonode = new XMLNode(port_automation_node_name);
+ //XMLNode *autonode = new XMLNode(port_automation_node_name);
set<Evoral::Parameter> automatable = _plugins[0]->automatable();
for (set<Evoral::Parameter>::iterator x = automatable.begin(); x != automatable.end(); ++x) {
@@ -642,10 +645,10 @@ PluginInsert::state (bool full)
child->add_child_nocopy (automation_list (*x).state (full));
autonode->add_child_nocopy (*child);
*/
- autonode->add_child_nocopy (((AutomationList*)data().control(*x)->list().get())->state (full));
+ //autonode->add_child_nocopy (((AutomationList*)data().control(*x)->list().get())->state (full));
}
- node.add_child_nocopy (*autonode);
+ //node.add_child_nocopy (*autonode);
return node;
}
@@ -766,7 +769,7 @@ PluginInsert::set_state(const XMLNode& node)
}
boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
- data().control(Evoral::Parameter(PluginAutomation, port_id), true));
+ data().control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
if (!child->children().empty()) {
c->alist()->set_state (*child->children().front());
diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc
index 5fbb30810d..a541ae0423 100644
--- a/libs/ardour/processor.cc
+++ b/libs/ardour/processor.cc
@@ -214,7 +214,7 @@ Processor::set_state (const XMLNode& node)
break;
}
// FIXME: other automation types?
- mark_automation_visible (Evoral::Parameter(PluginAutomation, what), true);
+ mark_automation_visible (Evoral::Parameter(PluginAutomation, 0, what), true);
}
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 740e5949b4..78d4a85e61 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -1046,7 +1046,9 @@ Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes,
if (meter_first) {
_meter->run_in_place(bufs, start_frame, end_frame, nframes, offset);
meter_first = false;
- }
+ } else {
+ meter_first = true;
+ }
process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_first);
}
@@ -1163,6 +1165,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
_meter->configure_io (potential_max_streams, potential_max_streams);
+ // XXX: do we want to emit the signal here ? change call order.
processor->activate ();
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
@@ -2830,7 +2833,7 @@ Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nfra
if (am.locked() && _session.transport_rolling()) {
- if (_gain_control->alist()->automation_playback()) {
+ if (_gain_control->automation_playback()) {
apply_gain_automation = _gain_control->list()->curve().rt_safe_get_vector (
start_frame, end_frame, _session.gain_automation_buffer(), nframes);
}