Module:TAMNAMS: Difference between revisions
m Code readability |
Separated some functions, rewrote udp function to accept alterations and made periods an optional arg |
||
| Line 680: | Line 680: | ||
-- If only u is known, then d = p - u - 1. | -- If only u is known, then d = p - u - 1. | ||
-- If only d is known, then u = p - d - 1. (Basically, u + d + 1 = steps/p.) | -- If only d is known, then u = p - d - 1. (Basically, u + d + 1 = steps/p.) | ||
function p. | -- A table of alterations can also be passed in, assuming they are already | ||
-- written out (EG, d3md or, if notation is established, b4). | |||
function p.udp_as_string(gens_up_per_period, gens_down_per_period, periods, alterations) | |||
local periods = periods or 1 | |||
local alterations_as_string = "" | |||
if alterations ~= nil then | |||
for i = 1, #alterations do | |||
alterations_as_string = alterations_as_string .. " " .. alterations[i] | |||
end | |||
end | |||
if periods == 1 then | if periods == 1 then | ||
return string.format("%s|%s", gens_up_per_period, gens_down_per_period) | return string.format("%s|%s", gens_up_per_period, gens_down_per_period) .. alterations_as_string | ||
else | else | ||
return string.format("%s|%s(%s)", gens_up_per_period * periods, gens_down_per_period * periods, periods) | return string.format("%s|%s(%s)", gens_up_per_period * periods, gens_down_per_period * periods, periods) .. alterations_as_string | ||
end | end | ||
end | end | ||
| Line 699: | Line 708: | ||
local gens_down = steps_per_period - gens_up - 1 | local gens_down = steps_per_period - gens_up - 1 | ||
local udp = p. | local udp = p.udp_as_string(gens_up, gens_down, period_count) | ||
table.insert(udps, udp) | table.insert(udps, udp) | ||
end | end | ||
| Line 734: | Line 743: | ||
-- are returned as a string. | -- are returned as a string. | ||
-- NOTES: | -- NOTES: | ||
-- - | -- - A period of repetition will always have as many modes as there are steps | ||
-- in that period. If it were any less, then the true period of repetition | |||
-- is a substring of that. | |||
-- | |||
-- | |||
function p.mode_rotation_udps(input_mode, input_mos, mos_abbrev, use_brightest_mode_search) | function p.mode_rotation_udps(input_mode, input_mos, mos_abbrev, use_brightest_mode_search) | ||
local use_brightest_mode_search = use_brightest_mode_search == nil or use_brightest_mode_search | local use_brightest_mode_search = use_brightest_mode_search == nil or use_brightest_mode_search | ||
| Line 762: | Line 762: | ||
-- by its altered scale degrees. Alterations require a mos abbrev, which is | -- by its altered scale degrees. Alterations require a mos abbrev, which is | ||
-- automatically looked up, defaulting to "m" if no abbrev can be found. | -- automatically looked up, defaulting to "m" if no abbrev can be found. | ||
-- NOTES: | |||
-- - This is inefficient when used on true-mos modes since it's a brute-force | |||
-- search for what mode it's closest to. It is, however, effective on | |||
-- modmosses, which is the primary use for this function. | |||
function p.mode_udp(input_mode, input_mos, mos_abbrev, use_brightest_mode_search) | function p.mode_udp(input_mode, input_mos, mos_abbrev, use_brightest_mode_search) | ||
local use_brightest_mode_search = use_brightest_mode_search == nil or use_brightest_mode_search | local use_brightest_mode_search = use_brightest_mode_search == nil or use_brightest_mode_search | ||
| Line 770: | Line 774: | ||
-- For each mode, count the number of differences between each true mode | -- For each mode, count the number of differences between each true mode | ||
-- and the entered mode and keep track of which mode has the fewest diffs. | -- and the entered mode and keep track of which mode has the fewest diffs. | ||
-- That mode is considered the closest mode, whose UDP will be used for the | |||
-- mode name, followed by which scale degrees are changed. | |||
-- If the number of diffs is ever zero, then the entered mode was a true-mos | -- If the number of diffs is ever zero, then the entered mode was a true-mos | ||
-- mode and has zero alterations. | -- mode and has zero alterations. | ||
local lowest_differences = #input_mode_as_step_matrix | local lowest_differences = #input_mode_as_step_matrix | ||
local bright_gens_down_per_period = 0 | local bright_gens_down_per_period = 0 | ||
local | local differences = {} | ||
for i = 1, #true_modes do | for i = 1, #true_modes do | ||
local current_true_mode = true_modes[i] | local current_true_mode = true_modes[i] | ||
local current_differences = p.differences_between_modes(current_true_mode, input_mode_as_step_matrix) | |||
-- It's possible for more than one mode to be closest. The tiebreaker is | |||
-- whichever mode is brightest (or darkest, which can be toggled). | |||
if use_brightest_mode_search then | if use_brightest_mode_search then | ||
if | if #current_differences < lowest_differences then | ||
-- Brightest-closest match | |||
bright_gens_down_per_period = i - 1 | bright_gens_down_per_period = i - 1 | ||
lowest_differences = | lowest_differences = #current_differences | ||
differences = current_differences | |||
end | end | ||
else | else | ||
if | if #current_differences <= lowest_differences then | ||
-- Darkest-closest match | |||
bright_gens_down_per_period = i - 1 | bright_gens_down_per_period = i - 1 | ||
lowest_differences = | lowest_differences = #current_differences | ||
differences = current_differences | |||
end | end | ||
end | end | ||
end | |||
-- Parse the differences as scale degrees. | |||
-- The differences between the true mode and the input mode are denoted as | |||
-- interval vectors. These should be parsed into a list of altered scale | |||
-- degrees before being passed into udp_as_string. Coding it this way allows | |||
-- for the possibility of adding custom mos notation (EG, diamond-mos). | |||
local alterations = {} | |||
for i = 1, #differences do | |||
table.insert(alterations, p.degree_quality(differences[i], input_mos, "ABBREV", mos_abbrev)) | |||
end | end | ||
| Line 823: | Line 818: | ||
local period_count = mos.period_count(input_mos) | local period_count = mos.period_count(input_mos) | ||
local bright_gens_up_per_period = mos.period_step_count(input_mos) - 1 - bright_gens_down_per_period | local bright_gens_up_per_period = mos.period_step_count(input_mos) - 1 - bright_gens_down_per_period | ||
udp = p. | udp = p.udp_as_string(bright_gens_up_per_period, bright_gens_down_per_period, period_count, alterations) | ||
-- | return udp | ||
local | end | ||
local | |||
-------------------------------------------------------------------------------- | |||
------------------------- MODE COMPARING FUNCTIONS ----------------------------- | |||
-------------------------------------------------------------------------------- | |||
-- Helper function for mode_udp, but can be used standalone. | |||
-- Given two modes as step matrices, produce a list of differences between the | |||
-- base mode and the altered mode. Diffs are listed as an array of mosstep | |||
-- vectors (a table containing the number of L's and s's for that interval). | |||
function p.differences_between_modes(base_step_matrix, altered_step_matrix) | |||
local differences = {} | |||
for i = 1, #altered_step_matrix do | |||
local altered_interval = altered_step_matrix[i] | |||
-- If i is greater than the number of intervals in base_step_matrix, | |||
-- then the interval being accessed is an extra-equave interval. Instead | |||
-- of accessing the ith interval (which would lead to a nil error), | |||
-- access the corresponding equave-reduced interval, then raise it by | |||
-- the necessary number of equaves. | |||
local base_interval = {} | |||
if i > #base_step_matrix then | |||
local current_mossteps = i - 1 | |||
local equave_step_count = #base_step_matrix - 1 | |||
local equave_interval = base_step_matrix[#base_step_matrix] | |||
local equave_reduced_interval = base_step_matrix[current_mossteps % equave_step_count + 1] | |||
local equave_count = math.floor(current_mossteps / equave_step_count) | |||
local equaves = mos.interval_mul(equave_interval, equave_count) | |||
base_interval = mos.interval_add(equave_reduced_interval, equaves) | |||
else | |||
base_interval = base_step_matrix[i] | |||
end | |||
if not mos.interval_eq(base_interval, altered_interval) then | |||
table.insert(differences, altered_interval) | |||
end | end | ||
end | end | ||
return | return differences | ||
end | end | ||
| Line 872: | Line 878: | ||
output_ = output_ .. "LLsLsAs" .. " " .. p.mode_udp("LLsLsAs", mos.new(5,2)) | output_ = output_ .. "LLsLsAs" .. " " .. p.mode_udp("LLsLsAs", mos.new(5,2)) | ||
return p.mode_rotation_udps(" | return p.mode_rotation_udps("LsLLsAs", mos.new(5, 2), "m", true) | ||
--return p.degree_quality({4, -1}, mos.new(5,2), "ABBREV", 'm') | --return p.degree_quality({4, -1}, mos.new(5,2), "ABBREV", 'm') | ||