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
This commit is contained in:
parent
612850c41b
commit
ec6ab8a048
@ -352,11 +352,14 @@ AudioTimeAxisView::create_automation_child (const Evoral::Parameter& param, bool
|
||||
void
|
||||
AudioTimeAxisView::update_pans (bool show)
|
||||
{
|
||||
Panner::iterator p;
|
||||
const set<Evoral::Parameter>& params = _route->panner().what_can_be_automated();
|
||||
set<Evoral::Parameter>::iterator p;
|
||||
|
||||
uint32_t i = 0;
|
||||
for (p = _route->panner().begin(); p != _route->panner().end(); ++p) {
|
||||
boost::shared_ptr<AutomationControl> pan_control = (*p)->pan_control();
|
||||
for (p = params.begin(); p != params.end(); ++p) {
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
||||
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
||||
_route->panner().data().control(*p));
|
||||
|
||||
if (pan_control->parameter().type() == NullAutomation) {
|
||||
error << "Pan control has NULL automation type!" << endmsg;
|
||||
@ -370,7 +373,7 @@ AudioTimeAxisView::update_pans (bool show)
|
||||
false,
|
||||
parent_canvas,
|
||||
_route->describe_parameter(pan_control->parameter())));
|
||||
add_automation_child(Evoral::Parameter(PanAutomation, i), pan_track, show);
|
||||
add_automation_child(*p, pan_track, show);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -755,7 +755,7 @@ Editor::register_actions ()
|
||||
act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Import to Region List"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
+ ActionManager::register_action (editor_actions, X_("importFromSession"), _("Import From Session"), mem_fun(*this, &Editor::session_import_dialog));
|
||||
ActionManager::register_action (editor_actions, X_("importFromSession"), _("Import From Session"), mem_fun(*this, &Editor::session_import_dialog));
|
||||
|
||||
act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility));
|
||||
ActionManager::track_selection_sensitive_actions.push_back (act);
|
||||
|
@ -185,7 +185,7 @@ GenericPluginUI::build ()
|
||||
|
||||
/* Don't show latency control ports */
|
||||
|
||||
if (plugin->describe_parameter (Evoral::Parameter(PluginAutomation, i)) == X_("latency")) {
|
||||
if (plugin->describe_parameter (Evoral::Parameter(PluginAutomation, 0, i)) == X_("latency")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ GenericPluginUI::build ()
|
||||
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> c
|
||||
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
||||
insert->data().control(Evoral::Parameter(PluginAutomation, i)));
|
||||
insert->data().control(Evoral::Parameter(PluginAutomation, 0, i)));
|
||||
|
||||
if ((cui = build_control_ui (i, c)) == 0) {
|
||||
error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
|
||||
|
@ -745,11 +745,13 @@ MixerStrip::connect_to_pan ()
|
||||
panstate_connection.disconnect ();
|
||||
panstyle_connection.disconnect ();
|
||||
|
||||
if (!_route->panner().empty()) {
|
||||
StreamPanner* sp = _route->panner().front();
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> pan_control
|
||||
= boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
|
||||
_route->panner().data().control(Evoral::Parameter( PanAutomation ) ));
|
||||
|
||||
panstate_connection = sp->pan_control()->alist()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
||||
panstyle_connection = sp->pan_control()->alist()->automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed));
|
||||
if (pan_control) {
|
||||
panstate_connection = pan_control->alist()->automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
|
||||
panstyle_connection = pan_control->alist()->automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed));
|
||||
}
|
||||
|
||||
panners.pan_changed (this);
|
||||
|
@ -411,7 +411,9 @@ Panner2d::handle_motion (gint evx, gint evy, GdkModifierType state)
|
||||
|
||||
if (drag_is_puck) {
|
||||
|
||||
panner[drag_index]->set_position (drag_target->x, drag_target->y);
|
||||
//panner.streampanner(drag_index).set_position (drag_target->x, drag_target->y);
|
||||
panner.pan_control( drag_index )->set_value( drag_target->x );
|
||||
//panner.control( Evoral::Parameter( PanAutomation, 1, drag_index ) )->set_value( drag_target->y );
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -304,7 +304,7 @@ PannerUI::setup_pan ()
|
||||
} else if (nouts == 2) {
|
||||
|
||||
vector<Adjustment*>::size_type asz;
|
||||
uint32_t npans = _io->panner().size();
|
||||
uint32_t npans = _io->panner().npanners();
|
||||
|
||||
while (!pan_adjustments.empty()) {
|
||||
delete pan_bars.back();
|
||||
@ -321,7 +321,7 @@ PannerUI::setup_pan ()
|
||||
/* initialize adjustment with 0.0 (L) or 1.0 (R) for the first and second panners,
|
||||
which serves as a default, otherwise use current value */
|
||||
|
||||
_io->panner()[asz]->get_position (rx);
|
||||
rx = _io->panner().pan_control( asz)->get_value();
|
||||
|
||||
if (npans == 1) {
|
||||
x = 0.5;
|
||||
@ -334,13 +334,14 @@ PannerUI::setup_pan ()
|
||||
}
|
||||
|
||||
pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
|
||||
bc = new PannerBar (*pan_adjustments[asz], _io->panner()[asz]->pan_control());
|
||||
bc = new PannerBar (*pan_adjustments[asz],
|
||||
boost::static_pointer_cast<PBD::Controllable>( _io->panner().pan_control( asz )) );
|
||||
|
||||
/* now set adjustment with current value of panner, then connect the signals */
|
||||
pan_adjustments.back()->set_value(rx);
|
||||
pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
|
||||
|
||||
_io->panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
|
||||
_io->panner().pan_control( asz )->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
|
||||
|
||||
|
||||
bc->set_name ("PanSlider");
|
||||
@ -425,7 +426,7 @@ PannerUI::build_pan_menu (uint32_t which)
|
||||
|
||||
/* set state first, connect second */
|
||||
|
||||
(dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner()[which]->muted());
|
||||
(dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner().streampanner(which).muted());
|
||||
(dynamic_cast<CheckMenuItem*> (&items.back()))->signal_toggled().connect
|
||||
(bind (mem_fun(*this, &PannerUI::pan_mute), which));
|
||||
|
||||
@ -445,8 +446,8 @@ PannerUI::build_pan_menu (uint32_t which)
|
||||
void
|
||||
PannerUI::pan_mute (uint32_t which)
|
||||
{
|
||||
StreamPanner* sp = _io->panner()[which];
|
||||
sp->set_muted (!sp->muted());
|
||||
StreamPanner& sp = _io->panner().streampanner(which);
|
||||
sp.set_muted (!sp.muted());
|
||||
}
|
||||
|
||||
void
|
||||
@ -492,7 +493,7 @@ PannerUI::pan_changed (void *src)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_io->panner().size()) {
|
||||
switch (_io->panner().npanners()) {
|
||||
case 0:
|
||||
panning_link_direction_button.set_sensitive (false);
|
||||
panning_link_button.set_sensitive (false);
|
||||
@ -527,11 +528,11 @@ PannerUI::pan_changed (void *src)
|
||||
void
|
||||
PannerUI::pan_adjustment_changed (uint32_t which)
|
||||
{
|
||||
if (!in_pan_update && which < _io->panner().size()) {
|
||||
if (!in_pan_update && which < _io->panner().npanners()) {
|
||||
|
||||
float xpos;
|
||||
float val = pan_adjustments[which]->get_value ();
|
||||
_io->panner()[which]->get_position (xpos);
|
||||
xpos = _io->panner().pan_control( which )->get_value();
|
||||
|
||||
/* add a kinda-sorta detent for the middle */
|
||||
|
||||
@ -548,7 +549,7 @@ PannerUI::pan_adjustment_changed (uint32_t which)
|
||||
|
||||
if (!Panner::equivalent (val, xpos)) {
|
||||
|
||||
_io->panner()[which]->set_position (val);
|
||||
_io->panner().streampanner(which).set_position (val);
|
||||
/* XXX
|
||||
the panner objects have no access to the session,
|
||||
so do this here. ick.
|
||||
@ -563,11 +564,11 @@ PannerUI::pan_value_changed (uint32_t which)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which));
|
||||
|
||||
if (_io->n_outputs().n_audio() > 1 && which < _io->panner().size()) {
|
||||
if (_io->n_outputs().n_audio() > 1 && which < _io->panner().npanners()) {
|
||||
float xpos;
|
||||
float val = pan_adjustments[which]->get_value ();
|
||||
|
||||
_io->panner()[which]->get_position (xpos);
|
||||
_io->panner().streampanner(which).get_position (xpos);
|
||||
|
||||
if (!Panner::equivalent (val, xpos)) {
|
||||
in_pan_update = true;
|
||||
@ -593,14 +594,14 @@ PannerUI::update_pan_bars (bool only_if_aplay)
|
||||
float xpos, val;
|
||||
|
||||
if (only_if_aplay) {
|
||||
boost::shared_ptr<AutomationList> alist (_io->panner()[n]->pan_control()->alist());
|
||||
boost::shared_ptr<AutomationList> alist (_io->panner().streampanner(n).pan_control()->alist());
|
||||
|
||||
if (!alist->automation_playback()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
_io->panner()[n]->get_effective_position (xpos);
|
||||
_io->panner().streampanner(n).get_effective_position (xpos);
|
||||
val = (*i)->get_value ();
|
||||
|
||||
if (!Panner::equivalent (val, xpos)) {
|
||||
@ -727,7 +728,7 @@ PannerUI::pan_automation_state_changed ()
|
||||
return;
|
||||
}
|
||||
|
||||
x = (_io->panner().front()->pan_control()->alist()->automation_state() != Off);
|
||||
x = (_io->panner().streampanner(0).pan_control()->alist()->automation_state() != Off);
|
||||
|
||||
if (pan_automation_state_button.get_active() != x) {
|
||||
ignore_toggle = true;
|
||||
|
@ -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 ¶m,
|
||||
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() {
|
||||
|
@ -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);
|
||||
|
||||
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;
|
||||
|
||||
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 reset (uint32_t noutputs, uint32_t npans);
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
@ -267,8 +266,8 @@ IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
@ -1034,6 +1022,15 @@ Panner::set_state (const XMLNode& node)
|
||||
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 */
|
||||
set_link_direction (LinkDirection (string_2_enum (prop->value(), ld)));
|
||||
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1046,8 @@ 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);
|
||||
}
|
||||
|
@ -862,11 +862,10 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
|
||||
{
|
||||
if ( route != 0 )
|
||||
{
|
||||
if ( route->panner().size() == 1 )
|
||||
if ( route->panner().npanners() == 1 )
|
||||
{
|
||||
// assume pan for now
|
||||
float xpos;
|
||||
route->panner()[0]->get_effective_position (xpos);
|
||||
float xpos = route->panner().pan_control(0)->get_value ();
|
||||
|
||||
// calculate new value, and trim
|
||||
xpos += state.delta;
|
||||
@ -875,7 +874,7 @@ void MackieControlProtocol::handle_control_event( SurfacePort & port, Control &
|
||||
else if ( xpos < 0.0 )
|
||||
xpos = 0.0;
|
||||
|
||||
route->panner()[0]->set_position( xpos );
|
||||
route->panner().pan_control(0)->set_value( xpos );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -999,10 +998,9 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal )
|
||||
{
|
||||
Pot & pot = route_signal->strip().vpot();
|
||||
|
||||
if ( route_signal->route().panner().size() == 1 )
|
||||
if ( route_signal->route().panner().npanners() == 1 )
|
||||
{
|
||||
float pos;
|
||||
route_signal->route().panner()[0]->get_effective_position( pos);
|
||||
float pos = route_signal->route().panner().pan_control(0)->get_value();
|
||||
route_signal->port().write( builder.build_led_ring( pot, ControlState( on, pos ) ) );
|
||||
}
|
||||
else
|
||||
|
@ -41,9 +41,9 @@ void RouteSignal::connect()
|
||||
|
||||
_name_changed_connection = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
|
||||
|
||||
if ( _route.panner().size() == 1 )
|
||||
if ( _route.panner().npanners() == 1 )
|
||||
{
|
||||
_panner_changed_connection = _route.panner()[0]->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this ) );
|
||||
_panner_changed_connection = _route.panner().pan_control(0)->Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_panner_changed ), this ) );
|
||||
}
|
||||
|
||||
try
|
||||
|
Loading…
Reference in New Issue
Block a user