Module:MOS tunings: Difference between revisions

Ganaram inukshuk (talk | contribs)
Added default params for central spectrum of ratios
Ganaram inukshuk (talk | contribs)
Added JI ratio lookup
Line 12: Line 12:


-- TODO:
-- TODO:
-- - Transfer round functions and range lookup to tamnams module
-- - 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
if i == 1 then
local ratios = ""
result = result
for j = 1, #sorted_ji_ratios[i] do
.. " || [[1/1]]"
if j ~= #sorted_ji_ratios[i] then
elseif i == #modal_union then
ratios = ratios .. string.format("%s/%s, ", sorted_ji_ratios[i][j][1], sorted_ji_ratios[i][j][2])
result = result
else
.. " "
ratios = ratios .. string.format("%s/%s", sorted_ji_ratios[i][j][1], sorted_ji_ratios[i][j][2])
.. string.format("|| [[%s]]", rat.as_ratio(input_mos.equave))
end
else
result = result .. " || "
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 range
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