Module:MOS tunings: Difference between revisions
Added default params for central spectrum of ratios |
Added JI ratio lookup |
||
| Line 12: | Line 12: | ||
-- TODO: | -- TODO: | ||
-- - JI ratio search and input | |||
-- - JI ratio input | |||
-- - Diatonic interval category lookup?!! | -- - Diatonic interval category lookup?!! | ||
| Line 48: | Line 47: | ||
end | end | ||
return step_ratios | return step_ratios | ||
end | |||
-- Find JI ratios up to an integer limit via mediants | |||
function p.ji_ratio_search(integer_limit) | |||
local SEARCH_MAX = 120 | |||
local integer_limit = integer_limit or SEARCH_MAX | |||
integer_limit = math.max(0, math.min(SEARCH_MAX, integer_limit)) | |||
local ratios = {{1,1}, {2,1}} | |||
local new_ratios_added = true | |||
while new_ratios_added do | |||
new_ratios_added = false | |||
local new_ratios = {} | |||
for i = 1, #ratios-1 do | |||
local ratio_1 = ratios[i] | |||
local ratio_2 = ratios[i+1] | |||
local mediant = {ratio_1[1]+ratio_2[1], ratio_1[2]+ratio_2[2]} | |||
local int_max = math.max(mediant[1], mediant[2]) | |||
table.insert(new_ratios, ratios[i]) | |||
if int_max <= integer_limit then | |||
new_ratios_added = true | |||
table.insert(new_ratios, mediant) | |||
end | |||
end | |||
table.insert(new_ratios, ratios[#ratios]) | |||
ratios = new_ratios | |||
end | |||
return ratios | |||
end | end | ||
| Line 93: | Line 124: | ||
return step_ratio_range, step_ratios | return step_ratio_range, step_ratios | ||
end | |||
-- Preprocess step ratios | |||
function p.preprocess_ji_ratios(input_mos, modal_union, step_ratios, ji_ratios) | |||
local avg_step_ratio = {0, 0} | |||
for i = 1, #step_ratios do | |||
avg_step_ratio[1] = avg_step_ratio[1] + step_ratios[i][1] | |||
avg_step_ratio[2] = avg_step_ratio[2] + step_ratios[i][2] | |||
end | |||
avg_step_ratio[1] = avg_step_ratio[1] / #step_ratios | |||
avg_step_ratio[2] = avg_step_ratio[2] / #step_ratios | |||
avg_step_ratio[1] = avg_step_ratio[1] / avg_step_ratio[2] | |||
avg_step_ratio[2] = avg_step_ratio[2] / avg_step_ratio[2] | |||
local cent_values = {} | |||
for i = 1, #modal_union do | |||
table.insert(cent_values, mos.interval_to_cents(modal_union[i], input_mos, avg_step_ratio)) | |||
end | |||
local tolerance = (rat.cents(input_mos.equave) / (input_mos.nL * avg_step_ratio[1] + input_mos.ns * avg_step_ratio[2])) * 0.35 | |||
local sorted_ratios = {} | |||
local curr_index = 1 -- Index of current_ratio | |||
for i = 1, #cent_values do | |||
local lower_bound = cent_values[i] - tolerance | |||
local upper_bound = cent_values[i] + tolerance | |||
local cents_within_range = true | |||
local curr_ratios = {} | |||
for j = curr_index, #ji_ratios do | |||
local curr_ratio = ji_ratios[j] | |||
local curr_cents = math.log(curr_ratio[1]/curr_ratio[2])/math.log(2) * 1200 | |||
if lower_bound < curr_cents and curr_cents < upper_bound then | |||
table.insert(curr_ratios, curr_ratio) | |||
--elseif curr_cents > upper_bound then | |||
-- curr_index = j | |||
-- break | |||
end | |||
end | |||
table.insert(sorted_ratios, curr_ratios) | |||
end | |||
return sorted_ratios | |||
end | end | ||
-- Main function | -- Main function | ||
function p._mos_tunings(input_mos, mos_prefix, mos_abbrev, step_ratios) | function p._mos_tunings(input_mos, mos_prefix, mos_abbrev, step_ratios, ji_ratios) | ||
local input_mos = input_mos or mos.new(5,2) | local input_mos = input_mos or mos.new(5,2) | ||
local mos_prefix = mos_prefix or "mos" | local mos_prefix = mos_prefix or "mos" | ||
local mos_abbrev = mos_abbrev or "m" | local mos_abbrev = mos_abbrev or "m" | ||
local step_ratios = step_ratios or { {2,1}, {3,1}, {3,2} } | local step_ratios = step_ratios or { {2,1}, {3,1}, {3,2} } | ||
local ji_ratios = ji_ratios or p.ji_ratio_search(40) | |||
local modal_union = mos.modal_union(input_mos) | local modal_union = mos.modal_union(input_mos) | ||
| Line 108: | Line 185: | ||
local step_ratio_range = "" | local step_ratio_range = "" | ||
step_ratio_range, step_ratios = p.preprocess_step_ratios(step_ratios) | step_ratio_range, step_ratios = p.preprocess_step_ratios(step_ratios) | ||
-- Preprocess JI ratios | |||
local sorted_ji_ratios = p.preprocess_ji_ratios(input_mos, modal_union, step_ratios, ji_ratios) | |||
-- Create table | -- Create table | ||
| Line 169: | Line 249: | ||
-- Add cells for JI ratios | -- Add cells for JI ratios | ||
-- TESTING: print only the unison and equave | -- TESTING: print only the unison and equave | ||
local ratios = "" | |||
for j = 1, #sorted_ji_ratios[i] do | |||
.. " | if j ~= #sorted_ji_ratios[i] then | ||
ratios = ratios .. string.format("%s/%s, ", sorted_ji_ratios[i][j][1], sorted_ji_ratios[i][j][2]) | |||
else | |||
ratios = ratios .. string.format("%s/%s", sorted_ji_ratios[i][j][1], sorted_ji_ratios[i][j][2]) | |||
.. string.format(" | end | ||
end | end | ||
result = result .. string.format("|| %s", ratios) | |||
result = result .. "\n" | result = result .. "\n" | ||
| Line 212: | Line 290: | ||
function p.tester() | function p.tester() | ||
local range, ratios = p.preprocess_step_ratios({ {7,1}, {3,1}, {2,1} }) | local range, ratios = p.preprocess_step_ratios({ {7,1}, {3,1}, {2,1} }) | ||
local ji_ratios = p.ji_ratio_search(50) | |||
return | return p.preprocess_ji_ratios(mos.new(5,2), mos.modal_union(mos.new(5,2)), {{3,2}}, ji_ratios) | ||
end | end | ||
return p | return p | ||