Module:MOS intervals: Difference between revisions

Ganaram inukshuk (talk | contribs)
add experimental interval region lookup; may move to a different module later
Ganaram inukshuk (talk | contribs)
todo
 
(8 intermediate revisions by the same user not shown)
Line 6: Line 6:
local tamnams = require("Module:TAMNAMS")
local tamnams = require("Module:TAMNAMS")
local yesno = require("Module:Yesno")
local yesno = require("Module:Yesno")
-- -- TODO:
-- - (High priority): Refactor code so instead of string concatenation, lines
--  are appended to a table, where table.concat() is called at the end.


-- EXPERIMENTAL FEATURE: lookup table for intervals
-- EXPERIMENTAL FEATURE: lookup table for intervals
-- Mostly based off Margo Schulter's categories (without large/medium/small),
-- Mostly based off Margo Schulter's categories (without large/medium/small),
-- but other interpretations are possible. Plus, this only goes up to 1200c.
-- but other interpretations are possible. Plus, this only goes up to 1200c.
interval_ranges = {
p.interval_ranges = {
     { name = "Pure Unison (1:1)", range = {0, 0} },
     { name = "Pure unison (1:1)"       , range = {   0,   0} },
     { name = "Commas", range = {0, 30} },
     { name = "Comma/diesis"             , range = {   0,   60} },
    { name = "Dieses", range = {30, 60} },
     { name = "Minor second"             , range = { 60, 125} },
     { name = "Minor Seconds", range = {60, 125} },
     { name = "Neutral second"           , range = { 125, 170} },
     { name = "Neutral Seconds", range = {125, 175} },
     { name = "Major second"             , range = { 180, 240} },
    --{ name = "Equable heptatonic", range = {170, 180} },
     { name = "Interseptimal (Maj2-min3)", range = { 240, 260} },
     { name = "Major Seconds", range = {175, 240} },
     { name = "Minor third"             , range = { 260, 330} },
     { name = "Interseptimal (Maj2-min3)", range = {240, 260} },
     { name = "Neutral third"           , range = { 330, 372} },
     { name = "Minor Thirds", range = {260, 330} },
     { name = "Major third"             , range = { 372, 440} },
     { name = "Neutral Thirds", range = {330, 372} },
     { name = "Interseptimal (Maj3-4)"   , range = { 440, 468} },
     { name = "Major Thirds", range = {372, 440} },
     { name = "Perfect fourth"           , range = { 468, 528} },
     { name = "Interseptimal (Maj3-4)", range = {440, 468} },
     { name = "Superfourth"             , range = { 528, 560} },
     { name = "Perfect Fourths", range = {468, 528} },
     { name = "Tritonic region"         , range = { 560, 640} },
     { name = "Superfourths", range = {528, 560} },
     { name = "Subfifth"                 , range = { 640, 672} },
     { name = "Tritonic Region", range = {560, 640} },
     { name = "Perfect fifth"           , range = { 672, 732} },
     { name = "Subfifths", range = {640, 672} },
     { name = "Interseptimal (5-min6)"   , range = { 732, 760} },
     { name = "Perfect Fifths", range = {672, 732} },
     { name = "Minor sixth"             , range = { 760, 828} },
     { name = "Interseptimal (5-min6)", range = {732, 760} },
     { name = "Neutral sixth"           , range = { 828, 870} },
     { name = "Minor Sixths", range = {760, 828} },
     { name = "Major sixth"             , range = { 870, 940} },
     { name = "Neutral Sixths", range = {828, 870} },
     { name = "Interseptimal (Maj6-min7)", range = { 940, 960} },
     { name = "Major Sixths", range = {870, 940} },
     { name = "Minor seventh"           , range = { 960, 1020} },
     { name = "Interseptimal (Maj6-min7)", range = {940, 960} },
     { name = "Neutral seventh"         , range = {1030, 1075} },
     { name = "Minor Sevenths", range = {960, 1030} },
     { name = "Major seventh"           , range = {1075, 1140} },
    --{ name = "Equable heptatonic", range = {1025, 1030} },
     { name = "Octave less comma/diesis" , range = {1140, 1200} },
     { name = "Neutral Sevenths", range = {1030, 1075} },
     { name = "Pure octave (2:1)"       , range = {1200, 1200} }
     { name = "Major Sevenths", range = {1075, 1140} },
     { name = "Octave less diesis", range = {1140, 1170} },
    { name = "Octave less comma", range = {1170, 1200} },
     { name = "Pure Octave (2:1)", range = {1200, 1200} }
}
}


-- EXPERIMENTAL FEATURE: interval lookup function
-- EXPERIMENTAL FEATURE: interval lookup function
function lookup_interval_range(cents)
function p.lookup_interval_range(cents)
     for _, interval in ipairs(interval_ranges) do
     for _, interval in ipairs(p.interval_ranges) do
         if cents >= interval.range[1] and cents <= interval.range[2] then
         if cents >= interval.range[1] and cents <= interval.range[2] then
             return interval.name
             return interval.name
Line 59: Line 59:
local mos_abbrev  = args["MOS Abbrev"  ] or "m"
local mos_abbrev  = args["MOS Abbrev"  ] or "m"
local is_collapsed = args["Is Collapsed"] == true
local is_collapsed = args["Is Collapsed"] == true
local show_inregs  = false
-- Get the scale sig
-- Get the scale sig
Line 92: Line 93:
.. '! Specific\n'
.. '! Specific\n'
.. '! Abbrev.\n'
.. '! Abbrev.\n'
.. (show_inregs and '! Interval Regions\n' or '')


-- Write each row
-- Write each row
Line 104: Line 106:
-- Otherwise, there are two rows to write, one for each size.
-- Otherwise, there are two rows to write, one for each size.
if is_period then
if is_period then
local cents = string.format("%.1f{{c}}", mos.interval_to_cents(current_bright_interval, input_mos, {1, 1}))
local cents = mos.interval_to_cents(current_bright_interval, input_mos, {1, 1})
local cents_formatted = string.format("%.1f{{c}}", cents)
result = result
result = result
Line 112: Line 115:
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_bright_interval) .. "</span>\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_bright_interval) .. "</span>\n"
.. "| " .. cents .. "\n"
.. "| " .. cents_formatted .. "\n"
.. (show_inregs and string.format("| %s\n", p.lookup_interval_range(cents)) or "")
else
else
-- Calculate the cent values min and max for the current intervals
-- Calculate the cent values min and max for the current intervals
Line 122: Line 126:
-- Then sort, as the min and max may be swapped  
-- Then sort, as the min and max may be swapped  
-- This happens if the dark interval has more small steps than large steps
-- This happens if the dark interval has more small steps than large steps
local dark_interval_range  = string.format("%.1f{{c}} to %.1f{{c}}", math.min(sm_min_cents, sm_max_cents), math.max(sm_min_cents, sm_max_cents))
local sm_min_sorted = math.min(sm_min_cents, sm_max_cents)
local bright_interval_range = string.format("%.1f{{c}} to %.1f{{c}}", math.min(lg_min_cents, lg_max_cents), math.max(lg_min_cents, lg_max_cents))
local sm_max_sorted = math.max(sm_min_cents, sm_max_cents)
local lg_min_sorted = math.min(lg_min_cents, lg_max_cents)
local lg_max_sorted = math.max(lg_min_cents, lg_max_cents)
-- Produce text ranges for intervals
local dark_interval_range  = string.format("%.1f{{c}} to %.1f{{c}}", sm_min_sorted, sm_max_sorted)
local bright_interval_range = string.format("%.1f{{c}} to %.1f{{c}}", lg_min_sorted, lg_max_sorted)
result = result
result = result
.. "|-\n"
.. "|-\n"
.. '| rowspan="2" | ' .. i-1 .. '-' .. mos_prefix .. 'step\n'
.. '| rowspan="2" | ' .. i-1 .. '-' .. mos_prefix .. 'step\n'
.. "| " .. tamnams.interval_quality(current_dark_interval, input_mos, "sentence-case", mos_prefix) .. "\n"
.. "| " .. tamnams.interval_quality(current_dark_interval, input_mos, "sentence-case", mos_prefix) .. "\n"
.. "| " .. tamnams.interval_quality(current_dark_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| " .. tamnams.interval_quality(current_dark_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_dark_interval) .. "</span>\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_dark_interval) .. "</span>\n"
.. "| " .. dark_interval_range .. "\n"
.. "| " .. dark_interval_range .. "\n"
.. "|-\n"
.. (show_inregs and string.format("| %s to %s\n", p.lookup_interval_range(sm_min_sorted), p.lookup_interval_range(sm_max_sorted)) or "")
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "sentence-case", mos_prefix) .. "\n"
.. "|-\n"
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "sentence-case", mos_prefix) .. "\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_bright_interval) .. "</span>\n"
.. "| " .. tamnams.interval_quality(current_bright_interval, input_mos, "abbrev"      , mos_abbrev) .. "\n"
.. "| " .. bright_interval_range .. "\n"
.. "| <span style=\"white-space: nowrap;\">" .. mos.interval_as_string(current_bright_interval) .. "</span>\n"
.. "| " .. bright_interval_range .. "\n"
.. (show_inregs and string.format("| %s to %s\n", p.lookup_interval_range(lg_min_sorted), p.lookup_interval_range(lg_max_sorted)) or "")
end
end
end
end
result = result .. "|}"
result = result .. "|}"
Line 155: Line 168:
-- Preprocess collapse option
-- Preprocess collapse option
args["Collapsed"] = yesno(args["Collapsed"], false)
args["Collapsed"] = yesno(args["Collapsed"], false)
-- EXPERIMENTAL: option to show interval regions
args["Show Interval Regions"] = yesno(args["Show Interval Regions"], false)
-- Preprocess (verify) prefix/abbrev
-- Preprocess (verify) prefix/abbrev