Module:MOS gamut: Difference between revisions
Updated to use middle mode, since that's the common convention; as a tiebreaker for an even quantity of modes, use the brighter of the two |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| (15 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local et = require("Module:ET") | |||
local mos = require("Module:MOS") | |||
local mosm = require("Module:MOS modes") | |||
local mosnot = require("Module:MOS notation") | |||
local rat = require("Module:Rational") | |||
local utils = require("Module:Utils") | |||
local yesno = require("Module:Yesno") | |||
-- Helper function for | -- Helper function for the function that has "frame" as a parameter | ||
function | |||
function p.mos_gamut(input_mos, udp, step_ratio, note_symbols, chroma_plus_symbol, chroma_minus_symbol) | function p.mos_gamut(input_mos, udp, step_ratio, note_symbols, chroma_plus_symbol, chroma_minus_symbol) | ||
-- Default parameters for input mos and step ratio (5L 2s and 2:1 step ratio) | -- Default parameters for input mos and step ratio (5L 2s and 2:1 step ratio) | ||
| Line 145: | Line 17: | ||
-- Get the number of mossteps per period and equave | -- Get the number of mossteps per period and equave | ||
local mossteps_per_equave = input_mos.nL + input_mos.ns | local mossteps_per_equave = input_mos.nL + input_mos.ns | ||
local periods_per_equave = | local periods_per_equave = utils._gcd(input_mos.nL, input_mos.ns) | ||
local mossteps_per_period = mossteps_per_equave / periods_per_equave | local mossteps_per_period = mossteps_per_equave / periods_per_equave | ||
| Line 155: | Line 27: | ||
-- two instead. | -- two instead. | ||
-- If it's 5L 2s, default to the second-brightest mode. | -- If it's 5L 2s, default to the second-brightest mode. | ||
local udp_default = { periods_per_equave * math.ceil(mossteps_per_period / 2), periods_per_equave * math.floor(mossteps_per_period / 2) } | local udp_default = { periods_per_equave * math.ceil((mossteps_per_period - 1)/ 2), periods_per_equave * math.floor((mossteps_per_period - 1) / 2) } | ||
if scale_sig == "5L 2s" then | if scale_sig == "5L 2s" then | ||
udp_default = { 5, 1 } | udp_default = { 5, 1 } | ||
end | end | ||
local | local udp = udp or udp_default | ||
local generators_up = | local generators_up = udp[1] | ||
local generators_down = | local generators_down = udp[2] | ||
-- The natural note symbols are those that correspond to diamond-mos | -- The natural note symbols are those that correspond to diamond-mos | ||
| Line 191: | Line 63: | ||
local kp = step_ratio[1] | local kp = step_ratio[1] | ||
local kq = step_ratio[2] | local kq = step_ratio[2] | ||
local k = | local k = utils._gcd(kp, kq) | ||
local num = kp / k | local num = kp / k | ||
local den = kq / k | local den = kq / k | ||
| Line 226: | Line 98: | ||
-- How long are the genchains? Length is per period | -- How long are the genchains? Length is per period | ||
local ascending_genchain_length = gens_up_per_period + genchain_extend | -- Genchain length counts the root, hence the +1 | ||
local descending_genchain_length = gens_down_per_period + genchain_extend | local ascending_genchain_length = gens_up_per_period + genchain_extend + 1 | ||
local descending_genchain_length = gens_down_per_period + genchain_extend + 1 | |||
-- Get the ascending and descending genchains | -- Get the ascending and descending genchains | ||
-- The genchains are notationally agnostic so notation needs to be applied to them | -- The genchains are notationally agnostic so notation needs to be applied to them | ||
local ascending_genchain = | local ascending_genchain = mosnot.mos_nomacc_chain(input_mos, gens_up_per_period, ascending_genchain_length, true) | ||
local descending_genchain = | local descending_genchain = mosnot.mos_nomacc_chain(input_mos, gens_down_per_period, descending_genchain_length, false) | ||
-- Create an empty gamut | -- Create an empty gamut | ||
| Line 242: | Line 115: | ||
-- How many esteps are the bright and dark generators? | -- How many esteps are the bright and dark generators? | ||
local bright_gen = mos.bright_gen(input_mos) | local bright_gen = mos.bright_gen(input_mos) | ||
local esteps_per_bright_gen = bright_gen[ | local esteps_per_bright_gen = bright_gen["L"] * num + bright_gen["s"] * den | ||
local esteps_per_dark_gen = esteps_per_period - esteps_per_bright_gen | local esteps_per_dark_gen = esteps_per_period - esteps_per_bright_gen | ||
| Line 253: | Line 126: | ||
-- Convert the notationally agnostic form into a form that uses given notation | -- Convert the notationally agnostic form into a form that uses given notation | ||
local note = ascending_genchain[j][i] | local note = ascending_genchain[j][i] | ||
local note_symbol = string.sub(note_symbols, note[ | local note_symbol = string.sub(note_symbols, note["Mossteps"] + 1, note["Mossteps"] + 1) | ||
local chroma_count = note[ | local chroma_count = note["Chromas"] | ||
local note_name = note_symbol .. string.rep(chroma_plus_symbol, chroma_count) | local note_name = note_symbol .. string.rep(chroma_plus_symbol, chroma_count) | ||
| Line 266: | Line 139: | ||
-- Convert the notationally agnostic form into a form that uses given notation | -- Convert the notationally agnostic form into a form that uses given notation | ||
local note = descending_genchain[j][i] | local note = descending_genchain[j][i] | ||
local note_symbol = string.sub(note_symbols, note[ | local note_symbol = string.sub(note_symbols, note["Mossteps"] + 1, note["Mossteps"] + 1) | ||
local chroma_count = note[ | local chroma_count = note["Chromas"] * -1 | ||
local note_name = note_symbol .. string.rep(chroma_minus_symbol, chroma_count) | local note_name = note_symbol .. string.rep(chroma_minus_symbol, chroma_count) | ||
| Line 289: | Line 162: | ||
function p.mos_gamut_frame(frame) | function p.mos_gamut_frame(frame) | ||
-- Default parameters for input mos and step ratio (5L 2s and 2:1 step ratio) | -- Default parameters for input mos and step ratio (5L 2s and 2:1 step ratio) | ||
local input_mos_unparsed = frame.args[ | local input_mos_unparsed = frame.args["Scale Signature"] | ||
local input_mos = mos.parse(input_mos_unparsed) or mos.new(2, 5, 2) | local input_mos = mos.parse(input_mos_unparsed) or mos.new(2, 5, 2) | ||
-- Step ratio | -- Step ratio | ||
local step_ratio = { 2, 1 } | local step_ratio = { 2, 1 } | ||
if string.len(frame.args[ | if string.len(frame.args["Step Ratio"]) > 0 then | ||
step_ratio = | step_ratio = mosnot.parse_step_ratio(frame.args["Step Ratio"]) | ||
end | end | ||
-- Get the number of mossteps per period and equave | -- Get the number of mossteps per period and equave | ||
local mossteps_per_equave = input_mos.nL + input_mos.ns | local mossteps_per_equave = input_mos.nL + input_mos.ns | ||
local periods_per_equave = | local periods_per_equave = utils._gcd(input_mos.nL, input_mos.ns) | ||
local mossteps_per_period = mossteps_per_equave / periods_per_equave | local mossteps_per_period = mossteps_per_equave / periods_per_equave | ||
| Line 311: | Line 184: | ||
-- two instead. | -- two instead. | ||
-- If it's 5L 2s, default to the second-brightest mode. | -- If it's 5L 2s, default to the second-brightest mode. | ||
local udp = { periods_per_equave * math.ceil(mossteps_per_period / 2), periods_per_equave * math.floor(mossteps_per_period / 2) } | local udp = { periods_per_equave * math.ceil((mossteps_per_period - 1)/ 2), periods_per_equave * math.floor((mossteps_per_period - 1) / 2) } | ||
if scale_sig == "5L 2s" then | if scale_sig == "5L 2s" then | ||
udp = { 5, 1 } | udp = { 5, 1 } | ||
end | end | ||
if string.len(frame.args[ | if string.len(frame.args["UDP"]) > 0 then | ||
udp = | udp = mosnot.parse_udp(frame.args["UDP"]) | ||
end | end | ||
local generators_up = udp[1] | local generators_up = udp[1] | ||
local generators_down = udp[2] | local generators_down = udp[2] | ||
-- Get notation: naturals (or nominals), sharp symbol, and flat symbol | |||
-- Get | local notation_default = { ["Naturals"] = string.sub("JKLMNOPQRSTUVWXYZ", 1, mossteps_per_equave), ["Sharp"] = "&", ["Flat"] = "@" } | ||
local | |||
if scale_sig == "5L 2s" then | if scale_sig == "5L 2s" then | ||
notation_default["Naturals"] = "CDEFGAB" | |||
notation_default["Sharp"] = "#" | |||
notation_default["Flat"] = "b" | |||
end | end | ||
local notation = mosnot.parse_notation(frame.args["Notation"]) or notation_default | |||
local note_symbols = notation["Naturals"] | |||
local chroma_plus_symbol = notation["Sharp"] | |||
local chroma_minus_symbol = notation["Flat"] | |||
-- Get the gamut | -- Get the gamut | ||
local gamut = p.mos_gamut(input_mos, udp, step_ratio, note_symbols, chroma_plus_symbol, chroma_minus_symbol) | local gamut = p.mos_gamut(input_mos, udp, step_ratio, note_symbols, chroma_plus_symbol, chroma_minus_symbol) | ||
-- Since the gamut on a mos page is just text, so will this | -- Since the gamut on a mos page is just text, so will this | ||
| Line 440: | Line 223: | ||
result = result .. "'''" .. gamut[#gamut] .. "'''" | result = result .. "'''" .. gamut[#gamut] .. "'''" | ||
return result | -- Debugger option | ||
local debugg = yesno(frame.args["debug"]) | |||
if debugg == true then | |||
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>" | |||
end | |||
return frame:preprocess(result) | |||
end | end | ||
return p | return p | ||