Fix crash on out of range MIDI events (though this shouldn't be possible at all....
[ardour.git] / libs / ardour / panner.cc
index e0dcf206345febb2efad2d256edd162382c47c20..ac8e4d05e32b81783cf0178107c5c0b04ed8013b 100644 (file)
@@ -69,10 +69,12 @@ static double direct_pan_to_control (pan_t val) {
        return val;
 }
 
-StreamPanner::StreamPanner (Panner& p)
-       : parent (p),
-         _control (new PanControllable(p.session(), X_("panner"), *this))
+StreamPanner::StreamPanner (Panner& p, Parameter param)
+       : parent (p)
+       , _control (new PanControllable(p.session(), X_("panner"), *this, param))
 {
+       assert(param.type() != NullAutomation);
+
        _muted = false;
 
        parent.session().add_controllable (_control);
@@ -189,8 +191,8 @@ StreamPanner::add_state (XMLNode& node)
 
 /*---------------------------------------------------------------------- */
 
-BaseStereoPanner::BaseStereoPanner (Panner& p)
-       : StreamPanner (p)
+BaseStereoPanner::BaseStereoPanner (Panner& p, Parameter param)
+       : StreamPanner (p, param)
 {
 }
 
@@ -267,7 +269,7 @@ BaseStereoPanner::distribute (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain
                
                pan = left * gain_coeff;
 
-               mix_buffers_with_gain(dst+n,src+n,nframes-n,pan);
+               mix_buffers_with_gain (dst+n,src+n,nframes-n,pan);
                
        } else {
                
@@ -346,8 +348,8 @@ BaseStereoPanner::distribute (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain
 
 /*---------------------------------------------------------------------- */
 
-EqualPowerStereoPanner::EqualPowerStereoPanner (Panner& p)
-       : BaseStereoPanner (p)
+EqualPowerStereoPanner::EqualPowerStereoPanner (Panner& p, Parameter param)
+       : BaseStereoPanner (p, param)
 {
        update ();
 
@@ -386,6 +388,7 @@ EqualPowerStereoPanner::update ()
        desired_right = panR * (scale * panR + 1.0f - scale);
 
        effective_x = x;
+       _control->set_value(x);
 }
 
 void
@@ -411,8 +414,10 @@ EqualPowerStereoPanner::distribute_automated (AudioBuffer& srcbuf, BufferSet& ob
 
        /* store effective pan position. do this even if we are muted */
 
-       if (nframes > 0) 
+       if (nframes > 0) {
                effective_x = buffers[0][nframes-1];
+               _control->set_value(effective_x); // signal, update UI
+       }
 
        if (_muted) {
                return;
@@ -458,9 +463,9 @@ EqualPowerStereoPanner::distribute_automated (AudioBuffer& srcbuf, BufferSet& ob
 }
 
 StreamPanner*
-EqualPowerStereoPanner::factory (Panner& parent)
+EqualPowerStereoPanner::factory (Panner& parent, Parameter param)
 {
-       return new EqualPowerStereoPanner (parent);
+       return new EqualPowerStereoPanner (parent, param);
 }
 
 XMLNode&
@@ -527,8 +532,8 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
 
 /*----------------------------------------------------------------------*/
 
-Multi2dPanner::Multi2dPanner (Panner& p)
-       : StreamPanner (p)
+Multi2dPanner::Multi2dPanner (Panner& p, Parameter param)
+       : StreamPanner (p, param)
 {
        update ();
 }
@@ -567,6 +572,7 @@ Multi2dPanner::update ()
        }
 
        effective_x = x;
+       _control->set_value(x);
 }
 
 void
@@ -644,9 +650,9 @@ Multi2dPanner::distribute_automated (AudioBuffer& src, BufferSet& obufs,
 }
 
 StreamPanner*
-Multi2dPanner::factory (Panner& p)
+Multi2dPanner::factory (Panner& p, Parameter param)
 {
-       return new Multi2dPanner (p);
+       return new Multi2dPanner (p, param);
 }
 
 int
@@ -794,7 +800,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));
+                       push_back (new EqualPowerStereoPanner (*this, Parameter(PanAutomation, n)));
                }
                break;
 
@@ -804,7 +810,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));
+                       push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
                }
 
                break; 
@@ -816,7 +822,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));
+                       push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
                }
 
                break;  
@@ -829,7 +835,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));
+                       push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
                }
 
                break;
@@ -841,7 +847,7 @@ Panner::reset (uint32_t nouts, uint32_t npans)
                }
 
                for (n = 0; n < npans; ++n) {
-                       push_back (new Multi2dPanner (*this));
+                       push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n)));
                }
 
                break;
@@ -975,7 +981,7 @@ Panner::clear_automation ()
 struct PanPlugins {
     string name;
     uint32_t nouts;
-    StreamPanner* (*factory)(Panner&);
+    StreamPanner* (*factory)(Panner&, Parameter);
 };
 
 PanPlugins pan_plugins[] = {
@@ -1077,7 +1083,7 @@ Panner::set_state (const XMLNode& node)
                                                   assumption, but its still an assumption.
                                                */
                                                
-                                               sp = pan_plugins[i].factory (*this);
+                                               sp = pan_plugins[i].factory (*this, Parameter(PanAutomation, 0));
                                                
                                                if (sp->set_state (**niter) == 0) {
                                                        push_back (sp);