Remove some aborts that don't really need to be.
[ardour.git] / libs / evoral / src / Curve.cpp
index 3f32340e4d5c71211e385daad4c79b70f59d43ac..20cc5d9ec3a088b9f5ca311621d08f9c1e97e9b0 100644 (file)
@@ -22,6 +22,7 @@
 #include <climits>
 #include <cfloat>
 #include <cmath>
+#include <vector>
 
 #include <glibmm/threads.h>
 
@@ -56,8 +57,8 @@ Curve::solve ()
                   (www.korf.co.uk/spline.pdf) for more details.
                */
 
-               double x[npoints];
-               double y[npoints];
+               vector<double> x(npoints);
+               vector<double> y(npoints);
                uint32_t i;
                ControlList::EventList::const_iterator xx;
 
@@ -249,7 +250,7 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen)
                int64_t fill_len = (int64_t) floor (veclen * frac);
 
                fill_len = min (fill_len, (int64_t)veclen);
-               
+
                for (i = 0; i < fill_len; ++i) {
                        vec[i] = _list.events().front()->value;
                }
@@ -389,10 +390,26 @@ Curve::multipoint_eval (double x)
                        return _list.events().back()->value;
                }
 
-               double x2 = x * x;
-               ControlEvent* ev = *range.second;
+               ControlEvent* after = (*range.second);
+               range.second--;
+               ControlEvent* before = (*range.second);
+
+               double vdelta = after->value - before->value;
+
+               if (vdelta == 0.0) {
+                       return before->value;
+               }
 
-               return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x);
+               double tdelta = x - before->when;
+               double trange = after->when - before->when;
+
+               if (_list.interpolation() == ControlList::Curved && after->coeff) {
+                               ControlEvent* ev = after;
+                               double x2 = x * x;
+                               return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x);
+               } else {
+                       return before->value + (vdelta * (tdelta / trange));
+               }
        }
 
        /* x is a control point in the data */