Request: Automation Lines/Curves Equations

Hi @taktik, I was wondering if you could share how the .automation[].points[].scaling variable (-1.0 - 1.0) works to create the interpolation curve. I’m developing a tool and have been trying to figure out how to calculate what values will be between two automation points, but reverse engineering complex math equations is not really my strong suit.

Sure. Here it is in Lua:

-- value must be in [0, 1], scaling must be [0, 1] as well
-- returns a normalized scaled value
function scaled_value(value, scaling)
  if (scaling == 0.0) then -- linear
    return value;
  else -- pow'ed
    local E = 2.7182818284590452353602874713527 
    if (scaling > 0.0) then
      return math.pow(value, 1 + math.pow(scaling, E/2) * 16.0)
    else 
      return 1.0 - math.pow(1.0 - value, 1 + math.pow(-scaling, E/2) * 16.0)
    end
  end
end
  
-- example
function test_scaling(scaling)
  print("Scaling " .. scaling)
  for x = 0, 1, 0.1 do
    print(" " .. x .. ":" .. scaled_value(x, scaling))
  end
end

test_scaling(1.0)
test_scaling(0.75)
test_scaling(0.5)
test_scaling(0.25)
test_scaling(0)
test_scaling(-0.25)
test_scaling(-0.5)
test_scaling(-0.75)
test_scaling(-1.0)
2 Likes

Hi @taktik, sorry to bother you again but could you share the equation for the Curves mode? I narrowed it down to SineInOut easing, which seems really close but not quite right. I know this used to be called ‘Cubic’ mode, but a Cubic easing equation is too severe.

-- t: current time, b: beginning value, c: change in value, d: duration
function sine(t, b, c, d)
  return -c / 2 * (math.cos(math.pi * t / d) - 1) + b
end

All good, I managed to stumble onto it here:

function curve(x)
  return -1 * x^2 * (2 * x - 3)
end

If going with that, I’d probably would’ve just left it as:

function curve(x)
  return -2 * x^3 + 3 * x^2
end

Is it more efficient? Not an issue for my tool, but if so then I guess it’d be good for others to also see that version.

More efficient than multiplying out the powers(?):

function curve(x)
  return -2 * (x * x * x) + 3 * (x * x)
end

Might be slightly quicker internally (I suppose), or maybe just picky for all intent and purpose.

What I mean is, why would you have left the formula as the version you posted?

I see, TBH I just prefer it that way. I like the highest power term on the far left going to lower powers as you read it from left to right.

This equation is almost right but it’s still slightly off, which makes me think the real version uses cos/pi/e in some way that would get rounded up when calculating in Renoise. I can’t figure it out, so are there math people out there that know this?

Here’s the discrepancy when applied to a 0-100% slider:

0% - 0%
2.8% - 2.803%
10.4% - 10.404%
21.6% - 21.603%
35.2% - 35.202%
50% - 50%
64.8% - 64.798%
78.4% - 78.397%
89.6% - 89.596%
97.2% - 97.197%
100% - 100%