Skip to content

Commit

Permalink
Update WTSE Prelude (surge-synthesizer#7915)
Browse files Browse the repository at this point in the history
- Adds math.offset() and math.zeros()
- Adds surge.mod.peak_normalize()
- Copies math.gcd() and math.lcm() from Formula Prelude
- Fixes case num_points = 1 in math.linspace() and logspace()
  • Loading branch information
nuoun authored Dec 10, 2024
1 parent c771703 commit 81c7e68
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions src/lua/wtse_prelude.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


local surge = {}
local mod = {}


--- MATH FUNCTIONS ---
Expand Down Expand Up @@ -43,6 +44,34 @@ function math.range(a, b)
return math.abs(a - b)
end

-- returns greatest common denominator between a and b
-- use with integers only!
function math.gcd(a, b)
local x = a
local y = b
local t

while y ~= 0 do
t = y
y = x % y
x = t
end

return x
end

-- returns least common multiple between a and b
-- use with integers only!
function math.lcm(a, b)
local t = a

while t % b ~= 0 do
t = t + a
end

return t
end


--- WTSE SPECIFIC MATH FUNCTIONS ---

Expand All @@ -69,6 +98,9 @@ end

-- returns a table containing num_points linearly spaced numbers from start_point to end_point
function math.linspace(start_point, end_point, num_points)
if num_points < 2 then
return {start_point}
end
local t = {}
local step = (end_point - start_point) / (num_points - 1)
for i = 1, num_points do
Expand All @@ -79,6 +111,9 @@ end

-- returns a table containing num_points logarithmically spaced numbers from 10^start_point to 10^end_point
function math.logspace(start_point, end_point, num_points)
if num_points < 2 then
return {start_point}
end
local t = {}
local step = (end_point - start_point) / (num_points - 1)
for i = 1, num_points do
Expand All @@ -88,6 +123,43 @@ function math.logspace(start_point, end_point, num_points)
return t
end

-- returns a table of length n, or a multidimensional table with {n, n, ..} dimensions all initialized with zeros
function math.zeros(dimensions)
if type(dimensions) == "number" then
dimensions = {dimensions}
elseif type(dimensions) ~= "table" or #dimensions == 0 then
return {0}
end
local function create_array(dimensions, depth)
local size = dimensions[depth]
local t = {}
for i = 1, size do
if depth < #dimensions then
t[i] = create_array(dimensions, depth + 1)
else
t[i] = 0
end
end
return t
end
return create_array(dimensions, 1)
end

-- returns a table or multidimensional table with every numerical value in the input table offset by x
function math.offset(t, x)
local o = {}
for k, v in pairs(t) do
if type(v) == "table" then
o[k] = math.offset(v, x)
elseif type(v) == "number" then
o[k] = v + x
else
o[k] = v
end
end
return o
end

-- returns the maximum absolute value found in the input table
function math.max_abs(t)
local o = 0
Expand Down Expand Up @@ -122,7 +194,50 @@ function math.sinc(t)
end


--- BUILT-IN MODULATORS ---


-- returns a table or multidimensional table with values from the input table,
-- peak-normalized such that the maximum absolute value equals 1 (default) or the specified norm_factor
function mod.normalize_peaks(t, norm_factor)
norm_factor = norm_factor or 1
local max_val = 0
local o = {}
if type(t[1]) == "table" then
for _, frame in ipairs(t) do
max_val = math.max_abs(frame)
end
else
max_val = math.max_abs(t)
end
if max_val > 0 then
local scale_factor = norm_factor / max_val
if type(t[1]) == "table" then
for i, frame in ipairs(t) do
o[i] = {}
for j, value in ipairs(frame) do
o[i][j] = value * scale_factor
end
end
else
for i, value in ipairs(t) do
o[i] = value * scale_factor
end
end
else
if type(t[1]) == "table" then
o = math.zeros({#t, #t[1]})
else
o = math.zeros(#t)
end
end
return o
end


--- END ---


surge.mod = mod

return surge

0 comments on commit 81c7e68

Please sign in to comment.