X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fevoral%2Fsrc%2FCurve.cpp;h=44fc48f7282c168d7f31f3d70a7fa7234089cea8;hb=b855e5f3220027502a3c88f189d511fe2a5a3c2b;hp=3f2ee361d328de0a53980a40ed34e6749c0571f4;hpb=3cd8138a419cb165f56070ace0b21a1e63ec5a43;p=ardour.git diff --git a/libs/evoral/src/Curve.cpp b/libs/evoral/src/Curve.cpp index 3f2ee361d3..44fc48f728 100644 --- a/libs/evoral/src/Curve.cpp +++ b/libs/evoral/src/Curve.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -56,8 +57,8 @@ Curve::solve () (www.korf.co.uk/spline.pdf) for more details. */ - double x[npoints]; - double y[npoints]; + vector x(npoints); + vector y(npoints); uint32_t i; ControlList::EventList::const_iterator xx; @@ -195,25 +196,47 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) int32_t original_veclen; int32_t npoints; + if (veclen == 0) { + return; + } + if ((npoints = _list.events().size()) == 0) { - for (i = 0; i < veclen; ++i) { + /* no events in list, so just fill the entire array with the default value */ + for (int32_t i = 0; i < veclen; ++i) { vec[i] = _list.default_value(); } return; } + if (npoints == 1) { + for (int32_t i = 0; i < veclen; ++i) { + vec[i] = _list.events().front()->value; + } + return; + } + /* events is now known not to be empty */ max_x = _list.events().back()->when; min_x = _list.events().front()->when; - lx = max (min_x, x0); - - if (x1 < 0) { - x1 = _list.events().back()->when; + if (x0 > max_x) { + /* totally past the end - just fill the entire array with the final value */ + for (int32_t i = 0; i < veclen; ++i) { + vec[i] = _list.events().back()->value; + } + return; } - hx = min (max_x, x1); + if (x1 < min_x) { + /* totally before the first event - fill the entire array with + * the initial value. + */ + for (int32_t i = 0; i < veclen; ++i) { + vec[i] = _list.events().front()->value; + } + return; + } original_veclen = veclen; @@ -224,16 +247,16 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) */ double frac = (min_x - x0) / (x1 - x0); - int32_t subveclen = (int32_t) floor (veclen * frac); + int64_t fill_len = (int64_t) floor (veclen * frac); - subveclen = min (subveclen, veclen); + fill_len = min (fill_len, (int64_t)veclen); - for (i = 0; i < subveclen; ++i) { + for (i = 0; i < fill_len; ++i) { vec[i] = _list.events().front()->value; } - veclen -= subveclen; - vec += subveclen; + veclen -= fill_len; + vec += fill_len; } if (veclen && x1 > max_x) { @@ -241,36 +264,21 @@ Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) /* fill some end section of the array with the default or final value */ double frac = (x1 - max_x) / (x1 - x0); - - int32_t subveclen = (int32_t) floor (original_veclen * frac); - + int64_t fill_len = (int64_t) floor (original_veclen * frac); float val; - subveclen = min (subveclen, veclen); - + fill_len = min (fill_len, (int64_t)veclen); val = _list.events().back()->value; - i = veclen - subveclen; - - for (i = veclen - subveclen; i < veclen; ++i) { + for (i = veclen - fill_len; i < veclen; ++i) { vec[i] = val; } - veclen -= subveclen; - } - - if (veclen == 0) { - return; - } - - if (npoints == 1) { - - for (i = 0; i < veclen; ++i) { - vec[i] = _list.events().front()->value; - } - return; + veclen -= fill_len; } + lx = max (min_x, x0); + hx = min (max_x, x1); if (npoints == 2) { @@ -382,10 +390,28 @@ Curve::multipoint_eval (double x) return _list.events().back()->value; } + ControlEvent* after = (*range.second); + range.second--; + ControlEvent* before = (*range.second); + + double vdelta = after->value - before->value; + + if (vdelta == 0.0) { + return before->value; + } + + double tdelta = x - before->when; + double trange = after->when - before->when; + + return before->value + (vdelta * (tdelta / trange)); + +#if 0 double x2 = x * x; ControlEvent* ev = *range.second; - return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x); + return = ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x); +#endif + } /* x is a control point in the data */