Module:MOS genchain: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
m wording
ArrowHead294 (talk | contribs)
mNo edit summary
 
(23 intermediate revisions by 3 users not shown)
Line 20: Line 20:
p.cell_color_small_size      = "#FCE4D6"
p.cell_color_small_size      = "#FCE4D6"
p.cell_color_sm_altered_size = "#F8CBAD"
p.cell_color_sm_altered_size = "#F8CBAD"


function p.preprocess_genchain(input_mos)
function p.preprocess_genchain(input_mos)
Line 37: Line 36:
end
end


function p._mos_genchain(input_mos)
function p._mos_genchain(input_mos, mos_prefix, mos_abbrev, is_collapsed)
local input_mos = input_mos or mos.new(5,2)
local input_mos = input_mos or mos.new(5,2)
local mos_prefix = mos_prefix or "mos"
local mos_abbrev = mos_abbrev or "m"
local is_collapsed = is_collapsed == true
local num_gens = mos.period_step_count(input_mos)
local num_gens = mos.period_step_count(input_mos)
Line 44: Line 46:
local genchain = p.preprocess_genchain(input_mos)
local genchain = p.preprocess_genchain(input_mos)
local period_count = mos.period_count(input_mos)
local period_count = mos.period_count(input_mos)
local scale_sig = mos.as_string(input_mos)
-- Begin table
-- Begin table
local result = "{| class=\"wikitable center-all\"\n"
local result = "{| class=\"wikitable center-1 center-3 mw-collapsible" .. (is_collapsed and " mw-collapsed\"\n" or "\"\n")
.. "|-\n"
-- Generators header rows
-- Table caption
result = result .. "! Bright gens"
result = result .. "|+ style=\"font-size: 105%; white-space: nowrap;\" | " .. string.format("Generator chain of %s\n", scale_sig)
 
-- Headers for each period
result = result .. "|-\n"
    .. "! Bright gens"
for i = 1, period_count do
for i = 1, period_count do
result = result
result = result
.. " !! Scale Degree"
.. " !! Scale degree"
.. " !! Abbrev"
.. " !! Abbrev."
end
end
local result = result
result = result .. "\n"
.. "\n"
.. "|-\n"
-- Add a row for each scale degree, plus their period-shifted counterparts
-- Add a row for each scale degree, plus their period-shifted counterparts
for i = 1, #genchain do
for i = 1, #genchain do
result = result .. "|-\n"
-- Number of generators
-- Number of generators
local num_gens = math.ceil(#genchain/2) - i
local num_gens = math.ceil(#genchain / 2) - i
result = result .. string.format("| %s", num_gens)
result = result .. string.format("| %s", string.gsub(num_gens, "-", "−"))
-- Scale degree (full name) and abbrev
-- Scale degree (full name) and abbrev
Line 77: Line 84:
if num_gens == 0 then
if num_gens == 0 then
result = result  
result = result  
.. string.format(" || %s<br>%s", tamnams.degree_quality(current_interval, input_mos, "sentence-case"), tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case"))
.. string.format(" || %s<br />%s || %s<br />%s",
.. string.format(" || %s<br>%s", tamnams.degree_quality(current_interval, input_mos, "abbrev")       , tamnams.degree_quality(period_raised_interval, input_mos, "abbrev")       )
tamnams.degree_quality(current_interval, input_mos, "sentence-case", mos_prefix),
tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case", mos_prefix),
tamnams.degree_quality(current_interval, input_mos, "abbrev" , mos_abbrev),
tamnams.degree_quality(period_raised_interval, input_mos, "abbrev", mos_abbrev))
elseif num_gens < 0 and mos.interval_step_count(current_interval) % mos.period_step_count(input_mos) == 0 then
elseif num_gens < 0 and mos.interval_step_count(current_interval) % mos.period_step_count(input_mos) == 0 then
result = result  
result = result  
.. string.format(" || %s", tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case"))
.. string.format(" || %s || %s",
.. string.format(" || %s", tamnams.degree_quality(period_raised_interval, input_mos, "abbrev"))
tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case", mos_prefix),
    tamnams.degree_quality(period_raised_interval, input_mos, "abbrev", mos_abbrev))
else
else
result = result  
result = result  
.. string.format(" || %s", tamnams.degree_quality(current_interval, input_mos, "sentence-case"))
.. string.format(" || %s || %s",
.. string.format(" || %s", tamnams.degree_quality(current_interval, input_mos, "abbrev"))
tamnams.degree_quality(current_interval, input_mos, "sentence-case", mos_prefix),
tamnams.degree_quality(current_interval, input_mos, "abbrev", mos_abbrev))
end
end
end
end
Line 93: Line 105:
result = result  
result = result  
.. "\n"
.. "\n"
.. "|-\n"
end
end
result = result .. "|}"
result = result .. "|}"
Line 100: Line 111:
end
end


function p.mos_genchain_description(input_mos)
function p.mos_genchain(frame)
local input_mos = input_mos or mos.new(6,2)
local scalesig = frame.args["Scale Signature"]
local mos_prefix = frame.args["MOS Prefix"]
local mos_abbrev = frame.args["MOS Abbrev"]
local collapsed  = yesno(frame.args["Collapsed"])
local debugg = yesno(frame.args["debug"])
 
-- Parse scalesig
local input_mos = mos.parse(scalesig)
-- How many periods?
-- Verify name/prefix/abbrev
local period_count = mos.period_count(input_mos)
mos_prefix = tamnams.verify_prefix(input_mos, mos_prefix)
local period_interval = mos.period(input_mos)
mos_abbrev = tamnams.verify_abbrev(input_mos, mos_abbrev)
-- What are the period intervals?
local result = p._mos_genchain(input_mos, mos_prefix, mos_abbrev, collapsed)
local period_intervals = {}
for i = 1, period_count + 1 do
local interval = mos.interval_mul(period_interval, i-1)
table.insert(period_intervals, interval)
end
-- As a sentence piece
-- Debugger option
local period_intervals_as_text = ""
if debugg == true then
if #period_intervals == 2 then
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
period_intervals_as_text = string.format("%s and %s", tamnams.degree_quality(period_intervals[1], input_mos), tamnams.degree_quality(period_intervals[2], input_mos))
else
for i = 1, period_count do
period_intervals_as_text = period_intervals_as_text
.. string.format("%s, ", tamnams.degree_quality(period_intervals[i], input_mos))
end
period_intervals_as_text = period_intervals_as_text
.. string.format("and %s", tamnams.degree_quality(period_intervals[period_count + 1], input_mos))
end
end
-- What is the bright gen and at what scale degrees do you stack from?
return frame:preprocess(result)
local bright_gen_as_text = tamnams.interval_quality(mos.bright_gen(input_mos), input_mos)
local result = string.format("A chain of bright generators, each a %s, produces the following scale degrees.", bright_gen_as_text)
-- How long is the chain?
local period_step_count = mos.period_step_count(input_mos)
local scalesig = mos.as_string(input_mos)
result = result
.. " "
.. string.format("A chain of %s bright generators %scontains the scale degrees of one of the modes of %s.", period_step_count, (period_count == 1 and "" or "from each period "), scalesig)
-- What scales are produced when the chain is extended further?
local child_scale_chain_length = input_mos.nL + input_mos.nL + input_mos.ns
local child_scale_1, child_scale_2 = mos.child_mosses(input_mos)
result = result
.. " "
.. string.format("Expanding %s chain to %s scale degrees produces the modes of either %s (for soft-of-basic tunings) or %s (for hard-of-basic tunings).",
(period_count == 1 and "the" or "each"),
child_scale_chain_length / period_count,
mos.as_string(child_scale_1),
mos.as_string(child_scale_2)
)
return result
end
 
function p.mos_genchain(frame)
local scalesig = frame.args["Scale Signature"]
local input_mos = mos.parse(scalesig) or mos.new(5,2)
return p.mos_genchain_description(input_mos) .. "\n" .. p._mos_genchain(input_mos)
end
end


return p
return p

Latest revision as of 12:30, 1 June 2025

Module documentation[view] [edit] [history] [purge]
This module should not be invoked directly; use its corresponding template instead: Template:MOS genchain.

This module produces a table illustrating the generator chain for a MOS scale.

Introspection summary for Module:MOS genchain 
Functions provided (3)
Line Function Params
23 preprocess_genchain (input_mos)
38 _mos_genchain (main) (input_mos, mos_prefix, mos_abbrev, is_collapsed)
113 mos_genchain (invokable) (frame)
Lua modules required (3)
Variable Module Functions used
mos Module:MOS new
period_count
bright_gen
interval_mul
period_reduce
interval_add
period_step_count
as_string
period
interval_step_count
parse
tamnams Module:TAMNAMS degree_quality
verify_prefix
verify_abbrev
yesno Module:Yesno yesno

No function descriptions were provided. The Lua code may have further information.


local mos = require("Module:MOS")
local tamnams = require("Module:TAMNAMS")
local yesno = require("Module:Yesno")
local p = {}

-- TODO
-- - Cell coloring
-- - Mosprefix and mosabbrev entering
-- - Collapse option

-- Global variables for cell colors
-- Colors are as follows:
-- - Orange and blue for small and large sizes, respectively
-- - Darker colors for altered scale degrees
-- - No color for period intervals
p.cell_color_none = "NONE"				-- For cells that don't have a color (default cell color applies)
p.cell_color_perfect_size = "NONE"		-- Only applies for periods, including the root and equave
p.cell_color_lg_altered_size = "#BDD7EE"
p.cell_color_large_size      = "#DDEBF7"
p.cell_color_small_size      = "#FCE4D6"
p.cell_color_sm_altered_size = "#F8CBAD"

function p.preprocess_genchain(input_mos)
	local input_mos = input_mos or mos.new(5,2)
	local num_gens = (2 * (input_mos.nL + input_mos.nL + input_mos.ns))/mos.period_count(input_mos) - 2
	
	local bright_gen = mos.bright_gen(input_mos)
	local gens = mos.interval_mul(bright_gen, math.floor(num_gens/2))
	bright_gen = mos.interval_mul(bright_gen, -1)
	local genchain = { mos.period_reduce(gens, input_mos) }
	for i = 1, num_gens do
		gens = mos.interval_add(gens, bright_gen)
		table.insert(genchain, mos.period_reduce(gens, input_mos))
	end
	return genchain
end

function p._mos_genchain(input_mos, mos_prefix, mos_abbrev, is_collapsed)
	local input_mos = input_mos or mos.new(5,2)
	local mos_prefix = mos_prefix or "mos"
	local mos_abbrev = mos_abbrev or "m"
	local is_collapsed = is_collapsed == true
	
	local num_gens = mos.period_step_count(input_mos)
	
	local genchain = p.preprocess_genchain(input_mos)
	local period_count = mos.period_count(input_mos)
	
	local scale_sig = mos.as_string(input_mos)
	
	-- Begin table
	local result = "{| class=\"wikitable center-1 center-3 mw-collapsible" .. (is_collapsed and " mw-collapsed\"\n" or "\"\n")
	
	-- Table caption
	result = result .. "|+ style=\"font-size: 105%; white-space: nowrap;\" | " .. string.format("Generator chain of %s\n", scale_sig)

	-- Headers for each period
	result = result .. "|-\n"
	    .. "! Bright gens"
	for i = 1, period_count do
		result = result
		.. " !! Scale degree"
		.. " !! Abbrev."
	end
	result = result .. "\n"
		
	-- Add a row for each scale degree, plus their period-shifted counterparts
	for i = 1, #genchain do
		result = result .. "|-\n"
		
		-- Number of generators
		local num_gens = math.ceil(#genchain / 2) - i
		result = result .. string.format("| %s", string.gsub(num_gens, "-", "&minus;"))
		
		-- Scale degree (full name) and abbrev
		for j = 1, period_count do
			-- If the scale degree corresponds to the root, say it's both the
			-- root and the degree one period up.
			-- If the scale degree is reached by a negative number of gens, then
			-- say it's the degree one period up instead.
			local period_interval = mos.period(input_mos)
			local current_interval = mos.interval_add(genchain[i], mos.interval_mul(period_interval, j - 1))
			local period_raised_interval = mos.interval_add(current_interval, period_interval)
			if num_gens == 0 then
				result = result 
					.. string.format(" || %s<br />%s || %s<br />%s",
						tamnams.degree_quality(current_interval, input_mos, "sentence-case", mos_prefix),
						tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case", mos_prefix),
						tamnams.degree_quality(current_interval, input_mos, "abbrev" , mos_abbrev),
						tamnams.degree_quality(period_raised_interval, input_mos, "abbrev", mos_abbrev))
			elseif num_gens < 0 and mos.interval_step_count(current_interval) % mos.period_step_count(input_mos) == 0 then
				result = result 
					.. string.format(" || %s || %s",
						tamnams.degree_quality(period_raised_interval, input_mos, "sentence-case", mos_prefix),
					    tamnams.degree_quality(period_raised_interval, input_mos, "abbrev", mos_abbrev))
			else
				result = result 
					.. string.format(" || %s || %s",
						tamnams.degree_quality(current_interval, input_mos, "sentence-case", mos_prefix),
						tamnams.degree_quality(current_interval, input_mos, "abbrev", mos_abbrev))
			end
		end
		
		-- End of row
		result = result 
			.. "\n"
	end
	result = result .. "|}"
	
	return result
end

function p.mos_genchain(frame)
	local scalesig = frame.args["Scale Signature"]
	local mos_prefix = frame.args["MOS Prefix"]
	local mos_abbrev = frame.args["MOS Abbrev"]
	local collapsed  = yesno(frame.args["Collapsed"])
	local debugg = yesno(frame.args["debug"])

	-- Parse scalesig
	local input_mos = mos.parse(scalesig)
	
	-- Verify name/prefix/abbrev
	mos_prefix = tamnams.verify_prefix(input_mos, mos_prefix)
	mos_abbrev = tamnams.verify_abbrev(input_mos, mos_abbrev)
	
	local result = p._mos_genchain(input_mos, mos_prefix, mos_abbrev, collapsed)
	
	-- Debugger option
	if debugg == true then
		result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
	end
	
	return frame:preprocess(result)
end

return p