SoundFont uses some interesting units in its spec - I’ve done some math and written a couple of functions to deal with translating between these and Renoise.
local log = math.log
local exp = math.exp
local min = math.min
local max = math.max
local E = exp(1)
local LOG_TIMECENT = log(2) / 1200
function timecents_to_seconds(tc)
return exp(LOG_TIMECENT * tc)
end
-- 10th of a decibel, can convert to decibels by dividing by 10
local LOG_CENTIBEL = log(10) / 200
function centibels_to_amp(cb)
return exp(LOG_CENTIBEL * cb)
end
-- useful for exponential dropoffs - Renoise AHDSR etc operate in
-- amplitude-linear scale, but many tools need dB-linear fades.
local function exerp(a, b, q)
return exp((1-q)*log(a) + q*log(b))
end
local function revlerp(a, b, x)
if x == a then return 0 end
if x == b then return 1 end
if a == b then error("impossible revlerp") end
return (x - a) / (b - a)
end
local LOG2 = log(2)
local function log2(x)
return log(x)/LOG2
end
local function clip(lo, hi, x)
return min(max(x, lo), hi)
end
-- here's the coup de grace - returns an "optimal" renoise smoothing
-- parameter that mimics an exponential dropoff or increase between
-- values y1 and y2. it does this by ensuring that the midpoint of
-- Renoise's curve equals the midpoint of what the exponential curve
-- would be. There is almost certainly a more optimal number, but the
-- math to get that number is very complicated and I couldn't find a
-- performant way to do it.
--
-- it is based on taktik's example code here:
-- https://forum.renoise.com/t/request-automation-lines-curves-equations/65599/2
-- by setting this evaluated at 0.5 to exerp at 0.5 and solving for the
-- smoothing parameter.
local function optimal_smoothing_between(y1, y2)
if y1 == y2 then return 0 end
if y1 < y2 then return -optimal_smoothing_between(y2, y1) end
local out = exerp(y1, y2, 0.5)
out = revlerp(y1, y2, out)
out = log2(1 - out) + 1
out = - out / 16
out = out ^ (2/E)
return -clip(-1, 1, out)
end
Also, according to the FluidSynth implementation, the attack phase of a SoundFont AHDSR is amplitude-linear, but the decay and release phases are dB-linear and must be smoothed.