Module:JI ratios: Difference between revisions
No edit summary |
No edit summary |
||
| Line 7: | Line 7: | ||
p = {} | p = {} | ||
-- | -- TODO | ||
-- - Allow option to search by Tenney height first or int limit first? | |||
-- INT_LIMIT_MAX is hardcoded to limit the size of output. | |||
-- 400 -> ~24000 ratios | -- 400 -> ~24000 ratios | ||
-- 300 -> ~14000 ratios | -- 300 -> ~14000 ratios | ||
| Line 14: | Line 17: | ||
-- 128 -> ~2500 ratios | -- 128 -> ~2500 ratios | ||
-- 100 -> ~1500 ratios | -- 100 -> ~1500 ratios | ||
local | local INT_LIMIT_MAX = 150 | ||
local DEFAULT_INT_LIMIT = 50 | |||
local | -- TENNEY_HEIGHT_MAX is hardcoded to limit size of output. | ||
local TENNEY_HEIGHT_MAX = 16 | |||
local DEFAULT_TENNEY_HEIGHT = 10 | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 29: | Line 35: | ||
local integer_limit = integer_limit or DEFAULT_INT_LIMIT | local integer_limit = integer_limit or DEFAULT_INT_LIMIT | ||
integer_limit = math.max(0, math.min( | integer_limit = math.max(0, math.min(INT_LIMIT_MAX, integer_limit)) | ||
local ratios = {{1,1}, {2,1}} | local ratios = {{1,1}, {2,1}} | ||
| Line 43: | Line 49: | ||
local ratio_2 = ratios[i+1] | local ratio_2 = ratios[i+1] | ||
local mediant = {ratio_1[1]+ratio_2[1], ratio_1[2]+ratio_2[2]} | local mediant = {ratio_1[1]+ratio_2[1], ratio_1[2]+ratio_2[2]} | ||
local | local INT_LIMIT_MAX = math.max(mediant[1], mediant[2]) | ||
table.insert(new_ratios, ratios[i]) | table.insert(new_ratios, ratios[i]) | ||
if | if INT_LIMIT_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 | |||
-- If the max cents is greater than the octave, duplicate all existing | |||
-- ratios and raise them by the required number of octaves. | |||
if max_cents > 1200 then | |||
local new_ratios = {} | |||
local num_octaves_up = math.ceil(max_cents / 1200) | |||
for j = 1, num_octaves_up do | |||
for i = 2, #ratios do | |||
local num = ratios[i][1] * math.pow(2, j) | |||
local den = ratios[i][2] | |||
local gcd = utils._gcd(num, den) | |||
num = num / gcd | |||
den = den / gcd | |||
if math.max(num, den) <= integer_limit then | |||
table.insert(new_ratios, {num, den}) | |||
end | |||
end | |||
end | |||
for i = 1, #new_ratios do | |||
table.insert(ratios, new_ratios[i]) | |||
end | |||
end | |||
-- Remove any ratios that exceed the max cents | |||
-- Convert to ratios that Module:Rational can work with | |||
for i = 1, #ratios do | |||
ratios[i] = rat.new(ratios[i][1], ratios[i][2]) | |||
end | |||
return ratios | |||
end | |||
-- Find JI ratios up to a max Tenney height within the octave by finding mediants. | |||
-- A cent value can be passed in to either exclude ratios that are above an | |||
-- interval below the octave or include ratios above the octave. | |||
function p.search_by_tenney_height(tenney_height, max_cents) | |||
local max_cents = max_cents or 1200 | |||
local tenney_height = tenney_height or DEFAULT_TENNEY_HEIGHT | |||
tenney_height = math.max(0, math.min(TENNEY_HEIGHT_MAX, tenney_height)) | |||
local ratios = {{1,1}, {2,1}} | |||
-- Find ratios by finding the mediants between existing ratios, only adding | |||
-- those that do not exceed the integer limit. | |||
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 curr_height = utils.log2(mediant[1]*mediant[2]) | |||
table.insert(new_ratios, ratios[i]) | |||
if curr_height <= tenney_height then | |||
new_ratios_added = true | new_ratios_added = true | ||
table.insert(new_ratios, mediant) | table.insert(new_ratios, mediant) | ||
| Line 239: | Line 314: | ||
function p.tester() | function p.tester() | ||
local params = p.parse_search_params("Prime Limit: 7; Tenney Height: 11") | --local params = p.parse_search_params("Prime Limit: 7; Tenney Height: 11") | ||
ratios = p.search_by_params(params) | --ratios = p.search_by_params(params) | ||
ratios = p.sort_by_closeness_to_cent_values(ratios, {0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200}, 15) | --ratios = p.sort_by_closeness_to_cent_values(ratios, {0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200}, 15) | ||
--return p.ratios_as_texts(ratios) | |||
local ratios = p.search_by_tenney_height(15) | |||
--local ratios = p.search_by_int_limit(150) | |||
return #ratios | |||
end | end | ||
return p | return p | ||