return fract;
}
-static double direct_pan_to_control (pan_t val) {
- return val;
-}
-StreamPanner::StreamPanner (Panner& p, Parameter param)
+//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;
}
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
-{
- float xpos;
- panner.get_effective_position (xpos);
- return direct_pan_to_control (xpos);
-}
-
-bool
-StreamPanner::PanControllable::can_send_feedback () const
+Panner::PanControllable::get_value (void) const
{
- AutoState astate = panner.get_parent().automation_state ();
-
- if ((astate == Play) || (astate == Touch && !panner.get_parent().touching())) {
- return true;
- }
-
- return false;
+ return AutomationControl::get_value();
}
void
/*---------------------------------------------------------------------- */
-BaseStereoPanner::BaseStereoPanner (Panner& p, Parameter param)
+BaseStereoPanner::BaseStereoPanner (Panner& p, Evoral::Parameter param)
: StreamPanner (p, param)
{
}
/* now that we are done loading */
- _control->list()->StateChanged ();
+ ((AutomationList*)_control->list().get())->StateChanged ();
return 0;
}
/*---------------------------------------------------------------------- */
-EqualPowerStereoPanner::EqualPowerStereoPanner (Panner& p, Parameter param)
+EqualPowerStereoPanner::EqualPowerStereoPanner (Panner& p, Evoral::Parameter param)
: BaseStereoPanner (p, param)
{
update ();
desired_right = panR * (scale * panR + 1.0f - scale);
effective_x = x;
- _control->set_value(x);
+ //_control->set_value(x);
}
void
if (nframes > 0) {
effective_x = buffers[0][nframes-1];
- _control->set_value(effective_x); // signal, update UI
}
if (_muted) {
}
StreamPanner*
-EqualPowerStereoPanner::factory (Panner& parent, Parameter param)
+EqualPowerStereoPanner::factory (Panner& parent, Evoral::Parameter param)
{
return new EqualPowerStereoPanner (parent, param);
}
root->add_property (X_("x"), buf);
root->add_property (X_("type"), EqualPowerStereoPanner::name);
- XMLNode* autonode = new XMLNode (X_("Automation"));
- autonode->add_child_nocopy (_control->list()->state (full_state));
- root->add_child_nocopy (*autonode);
+ // XXX: dont save automation here... its part of the automatable panner now.
StreamPanner::add_state (*root);
} else if ((*iter)->name() == X_("Automation")) {
- _control->list()->set_state (*((*iter)->children().front()));
+ _control->alist()->set_state (*((*iter)->children().front()));
- if (_control->list()->automation_state() != Off) {
+ if (_control->alist()->automation_state() != Off) {
set_position (_control->list()->eval (parent.session().transport_frame()));
}
}
/*----------------------------------------------------------------------*/
-Multi2dPanner::Multi2dPanner (Panner& p, Parameter param)
+Multi2dPanner::Multi2dPanner (Panner& p, Evoral::Parameter param)
: StreamPanner (p, param)
{
update ();
}
effective_x = x;
- _control->set_value(x);
}
void
}
StreamPanner*
-Multi2dPanner::factory (Panner& p, Parameter param)
+Multi2dPanner::factory (Panner& p, Evoral::Parameter param)
{
return new Multi2dPanner (p, param);
}
/*---------------------------------------------------------------------- */
Panner::Panner (string name, Session& s)
- : _session (s)
+ : Processor(s, name, PostFader)
{
+ //set_name_old_auto (name);
set_name (name);
_linked = false;
}
}
+
void
Panner::set_bypassed (bool yn)
{
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;
outputs.push_back (Output (1.0, 0));
for (n = 0; n < npans; ++n) {
- push_back (new EqualPowerStereoPanner (*this, Parameter(PanAutomation, n)));
+ _streampanners.push_back (new EqualPowerStereoPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
outputs.push_back (Output (1.0, 1.0));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
outputs.push_back (Output (0, 1.0));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
outputs.push_back (Output (0.5, 0.75));
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
+ _streampanners.push_back (new Multi2dPanner (*this, Evoral::Parameter(PanAutomation, 0, n)));
}
break;
}
for (n = 0; n < npans; ++n) {
- push_back (new Multi2dPanner (*this, 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 ();
}
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;
}
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) {
- (*i)->pan_control()->list()->set_automation_style (style);
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
+ ((AutomationList*)(*i)->pan_control()->list().get())->set_automation_style (style);
}
_session.set_dirty ();
}
void
Panner::set_automation_state (AutoState state)
{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- (*i)->pan_control()->list()->set_automation_state (state);
+ for (vector<StreamPanner*>::iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
+ ((AutomationList*)(*i)->pan_control()->list().get())->set_automation_state (state);
}
_session.set_dirty ();
}
Panner::automation_state () const
{
if (!empty()) {
- return front()->pan_control()->list()->automation_state ();
+ return ((AutomationList*)_streampanners.front()->pan_control()->list().get())->automation_state ();
} else {
return Off;
}
Panner::automation_style () const
{
if (!empty()) {
- return front()->pan_control()->list()->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) {
- (*i)->pan_control()->list()->reposition_for_rt_add (frame);
- }
-}
-
-void
-Panner::snapshot (nframes_t now)
-{
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- boost::shared_ptr<AutomationList> list = (*i)->pan_control()->list();
- 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;
uint32_t nouts;
- StreamPanner* (*factory)(Panner&, Parameter);
+ StreamPanner* (*factory)(Panner&, Evoral::Parameter);
};
PanPlugins pan_plugins[] = {
XMLNode&
Panner::state (bool full)
{
- XMLNode* root = new XMLNode (X_("Panner"));
- char buf[32];
+ XMLNode& node = Processor::state(full);
- 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 ("type", "panner");
+
+ char buf[32];
- /* add each output */
+ 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"));
for (vector<Panner::Output>::iterator o = outputs.begin(); o != outputs.end(); ++o) {
XMLNode* onode = new XMLNode (X_("Output"));
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
XMLNodeConstIterator niter;
const XMLProperty *prop;
uint32_t i;
+ uint32_t num_panners = 0;
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) {
if ((prop = node.property (X_("bypassed"))) != 0) {
set_bypassed (prop->value() == "yes");
}
-
+
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)));
assumption, but its still an assumption.
*/
- sp = pan_plugins[i].factory (*this, Parameter(PanAutomation, 0));
+ sp = pan_plugins[i].factory (*this, Evoral::Parameter(PanAutomation, 0, num_panners));
+ num_panners++;
if (sp->set_state (**niter) == 0) {
- push_back (sp);
+ _streampanners.push_back (sp);
}
break;
}
}
+ reset(num_panners, outputs.size());
/* don't try to do old-school automation loading if it wasn't marked as existing */
if ((prop = node.property (X_("automation")))) {
return 0;
}
-
-
bool
Panner::touching () const
{
- for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) {
- if ((*i)->pan_control()->list()->touching ()) {
+ for (vector<StreamPanner*>::const_iterator i = _streampanners.begin(); i != _streampanners.end(); ++i) {
+ if (((AutomationList*)(*i)->pan_control()->list().get())->touching ()) {
return true;
}
}
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 {
} 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 {
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 {
} 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 {
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 {
} 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 {
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
}
// 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) {
}
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 ()
char line[128];
uint32_t linecnt = 0;
float version;
- iterator sp;
+ vector<StreamPanner*>::iterator sp;
LocaleGuard lg (X_("POSIX"));
if (automation_path.length() == 0) {
return -1;
}
- sp = begin();
+ sp = _streampanners.begin();
while (in.getline (line, sizeof(line), '\n')) {
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;