Module:Interval edo approximation: Difference between revisions
Jump to navigation
Jump to search
trying to automate table generation (im learning how to wiki dont yell at me) |
m bug fixing |
||
| Line 1: | Line 1: | ||
-- EDO Approximations Module | -- EDO Approximations Module | ||
-- Calculates EDO approximations for just intervals | -- Calculates EDO approximations for just intervals | ||
-- Usage: {{#invoke: | -- Usage: {{#invoke:EDO_Approximation|main|interval=3/2|tolerance=9|min_edo=10|max_edo=60}} | ||
local p = {} | local p = {} | ||
| Line 7: | Line 7: | ||
-- Convert a frequency ratio to cents | -- Convert a frequency ratio to cents | ||
local function cents(ratio) | local function cents(ratio) | ||
return 1200 * math.log( | return 1200 * math.log(2) | ||
end | end | ||
| Line 31: | Line 31: | ||
end | end | ||
-- Calculate all EDO | -- Calculate all EDO approximation within tolerance for a given ratio | ||
local function calculate_edo_approximations(ratio, tolerance, min_edo, max_edo) | local function calculate_edo_approximations(ratio, tolerance, min_edo, max_edo) | ||
local ratio_cents = cents(ratio) | local ratio_cents = cents(ratio) | ||
Revision as of 05:21, 3 November 2025
- This module should not be invoked directly; use its corresponding template instead: Template:Interval edo approximation.
| Introspection summary for Module:Interval edo approximation | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
No function descriptions were provided. The Lua code may have further information.
-- EDO Approximations Module
-- Calculates EDO approximations for just intervals
-- Usage: {{#invoke:EDO_Approximation|main|interval=3/2|tolerance=9|min_edo=10|max_edo=60}}
local p = {}
-- Convert a frequency ratio to cents
local function cents(ratio)
return 1200 * math.log(2)
end
-- Parse a ratio string like '3/2' into a number
local function parse_ratio(ratio_str)
local num, denom = ratio_str:match("^(%d+)/(%d+)$")
if not num or not denom then
return nil
end
return tonumber(num) / tonumber(denom)
end
-- Find the best approximation of an interval in a given EDO
local function find_best_approximation(ratio_cents, edo)
local edostep = 1200 / edo
-- Find the nearest step
local best_step = math.floor(ratio_cents / edostep + 0.5)
local approximation_cents = best_step * edostep
local absolute_error = approximation_cents - ratio_cents
local relative_error = (absolute_error / edostep) * 100
return best_step, absolute_error, relative_error
end
-- Calculate all EDO approximation within tolerance for a given ratio
local function calculate_edo_approximations(ratio, tolerance, min_edo, max_edo)
local ratio_cents = cents(ratio)
local results = {}
for edo = min_edo, max_edo do
local steps, abs_error, rel_error = find_best_approximation(ratio_cents, edo)
if math.abs(rel_error) <= tolerance then
table.insert(results, {
edo = edo,
steps = steps,
abs_error = abs_error,
rel_error = rel_error
})
end
end
return results
end
-- Format a number with sign and 2 decimal places
local function format_error(value)
if value >= 0 then
return string.format("+%.2f", value)
else
return string.format("%.2f", value)
end
end
-- Main function to generate the wikitable
function p.main(frame)
-- Get parameters from template invocation
local args = frame.args
local interval_str = args.interval or args[1]
local tolerance = tonumber(args.tolerance) or 9.0
local min_edo = tonumber(args.min_edo) or 10
local max_edo = tonumber(args.max_edo) or 60
-- Validate and parse interval
if not interval_str then
return "Error: No interval specified"
end
local ratio = parse_ratio(interval_str)
if not ratio then
return "Error: Invalid interval format (use format like '3/2')"
end
-- Calculate approximations
local results = calculate_edo_approximations(ratio, tolerance, min_edo, max_edo)
if #results == 0 then
return "No EDOs found within tolerance of " .. tolerance .. "%"
end
-- Build the wikitable
local output = {}
table.insert(output, '{| class="wikitable"')
table.insert(output, '|+ EDO Approximations for ' .. interval_str)
table.insert(output, '|-')
table.insert(output, '! EDO !! Step size !! Absolute Error ([[Cent|¢]]) !! [[Relative_interval_error|Relative Error]] ([[Relative_cent|%]])')
for _, result in ipairs(results) do
local edo_link = string.format("[[%dedo|%d]]", result.edo, result.edo)
local step_size = string.format("%d\\%d", result.steps, result.edo)
local abs_err = format_error(result.abs_error)
local rel_err = format_error(result.rel_error)
table.insert(output, '|-')
table.insert(output, string.format('| %s || %s || %s || %s', edo_link, step_size, abs_err, rel_err))
end
table.insert(output, '|}')
return table.concat(output, '\n')
end
return p