|
|
| Line 5: |
Line 5: |
| local yesno = require("Module:Yesno") | | local yesno = require("Module:Yesno") |
| local tip = require("Module:Template input parse") | | local tip = require("Module:Template input parse") |
| | local jira = require("Module:JI ratios") |
| local utils = require("Module:Utils") | | local utils = require("Module:Utils") |
| local p = {} | | local p = {} |
| Line 14: |
Line 15: |
| -- TODO: | | -- TODO: |
| -- - Add option to enter a custom set of ratios; requires sorting | | -- - Add option to enter a custom set of ratios; requires sorting |
| -- - Add option to refine JI ratio search (EG, prime limit, Tenney height, subgroup, etc...)
| |
| -- - Add option to omit JI col altogether | | -- - Add option to omit JI col altogether |
| -- - Diatonic interval category lookup? | | -- - Diatonic interval category lookup? |
| Line 50: |
Line 50: |
| 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, max_cents)
| |
| local SEARCH_MAX = 120
| |
| local max_cents = max_cents or 1200
| |
| 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}}
| |
|
| |
| -- 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 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
| |
|
| |
| -- 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
| |
|
| |
|
| |
| return ratios
| |
| end | | end |
|
| |
|
| Line 189: |
Line 123: |
| end | | end |
| | | |
| -- Sort ratios by closeness to each degree in the modal union
| | local sorted_ratios = jira.sort_by_closeness_to_cent_values(ji_ratios, cent_values, tolerance) |
| 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, string.format("Ratios within %.2f of the averaged scale degrees are shown.", tolerance) | | return sorted_ratios, string.format("Ratios within %.1f of the averaged scale degrees are shown.", tolerance) |
| end | | end |
|
| |
|
| Line 232: |
Line 144: |
| -- Preprocess JI ratios | | -- Preprocess JI ratios |
| local equave_in_cents = mos.equave_to_cents(input_mos) | | local equave_in_cents = mos.equave_to_cents(input_mos) |
| local ji_ratios = ji_ratios or p.ji_ratio_search(30, equave_in_cents) | | local ji_ratios = ji_ratios or jira.search_by_int_limit(32, mos.equave_to_cents(input_mos)) |
| local sorted_ji_ratios, search_info = p.preprocess_ji_ratios(input_mos, modal_union, step_ratios, ji_ratios) | | local sorted_ji_ratios, search_info = p.preprocess_ji_ratios(input_mos, modal_union, step_ratios, ji_ratios) |
| | | |
| Line 294: |
Line 206: |
| | | |
| -- Add cells for JI ratios | | -- Add cells for JI ratios |
| -- TESTING: print only the unison and equave
| | local ratios_as_text = jira.ratios_as_text(sorted_ji_ratios[i]) |
| local ratios = "" | | result = result .. string.format("|| %s", ratios_as_text) |
| 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])
| |
| end
| |
| end
| |
| result = result .. string.format("|| %s", ratios) | |
| | | |
| result = result .. "\n" | | result = result .. "\n" |
| Line 336: |
Line 240: |
| 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(30, 2400)
| |
| local input_mos = mos.parse("9L 4s<7/2>") | | local input_mos = mos.parse("9L 4s<7/2>") |
| | | |
| return p.preprocess_ji_ratios(input_mos, mos.modal_union(input_mos), {{2,1}, {3,2}, {5,3}}, ji_ratios) | | --return p.preprocess_ji_ratios(input_mos, mos.modal_union(input_mos), {{2,1}, {3,2}, {5,3}}, ji_ratios) |
| --return ji_ratios | | --return ji_ratios |
| --return p._mos_tunings(input_mos) | | return p._mos_tunings(input_mos) |
| end | | end |
|
| |
|
| return p | | return p |