Module:MOS intervals: Difference between revisions
Jump to navigation
Jump to search
ArrowHead294 (talk | contribs) No edit summary |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| Line 5: | Line 5: | ||
local et = require("Module:ET") | local et = require("Module:ET") | ||
local tamnams = require("Module:TAMNAMS") | local tamnams = require("Module:TAMNAMS") | ||
local | local he = require("Module:Harmonic entropy") | ||
local p = {} | local p = {} | ||
| Line 70: | Line 70: | ||
.. string.format("|| %s " , mos.interval_as_string(current_bright_interval)) | .. string.format("|| %s " , mos.interval_as_string(current_bright_interval)) | ||
.. string.format("|| %.1f¢ ", cents) | .. string.format("|| %.1f¢ ", cents) | ||
.. string.format("|| ~%.4f nats ", | .. string.format("|| ~%.4f nats ", he.harmonic_entropy(cents)) | ||
.. string.format("|| ~%.4f nats\n", | .. string.format("|| ~%.4f nats\n", he.harmonic_entropy(cents)) | ||
else | else | ||
-- Calculate the best and average harmonic entropies | -- Calculate the best and average harmonic entropies | ||
| Line 80: | Line 80: | ||
for i = 1, #step_ratios do | for i = 1, #step_ratios do | ||
local step_ratio = step_ratios[i] | local step_ratio = step_ratios[i] | ||
local he_dark = | local he_dark = he.harmonic_entropy(mos.interval_to_cents(current_dark_interval, input_mos, step_ratio)) | ||
local he_bright = | local he_bright = he.harmonic_entropy(mos.interval_to_cents(current_bright_interval, input_mos, step_ratio)) | ||
he_dark_average = he_dark_average + he_dark / #step_ratios | he_dark_average = he_dark_average + he_dark / #step_ratios | ||
he_bright_average = he_bright_average + he_bright / #step_ratios | he_bright_average = he_bright_average + he_bright / #step_ratios | ||
Revision as of 16:13, 13 July 2024
- This module should not be invoked directly; use its corresponding template instead: Template:MOS intervals.
This module generates a table showing interval varieties and qualities for a given MOS scale.
| Introspection summary for Module:MOS intervals | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||||||||||||||||||||||||||
No function descriptions were provided. The Lua code may have further information.
local mos = require("Module:MOS")
local rat = require("Module:Rational")
local ord = require("Module:Ordinal")
local utils = require("Module:Utils")
local et = require("Module:ET")
local tamnams = require("Module:TAMNAMS")
local he = require("Module:Harmonic entropy")
local p = {}
-- TODO:
-- - Convert tooltips to footnotes... somehow
-- Main function; to be called by wrapper
function p._mos_intervals(input_mos, mos_prefix, mos_abbrev)
-- Default param for input mos is 5L 2s
local input_mos = input_mos or mos.new(5, 2, 2)
local mos_prefix = mos_prefix or "mos"
local mos_abbrev = mos_abbrev or "m"
-- Get the scale sig
local scale_sig = mos.as_string(input_mos)
-- Get the brightest and darkest modes as step matrices
local bright_step_matrix = mos.mode_to_step_matrix(mos.brightest_mode(input_mos))
local dark_step_matrix = mos.mode_to_step_matrix(mos.darkest_mode(input_mos))
-- Get the number of steps per period and equave
local equave_step_count = mos.equave_step_count(input_mos)
local period_step_count = mos.period_step_count(input_mos)
-- Get the step counts for the bright and dark generators
local bright_gen_step_count = mos.bright_gen_step_count(input_mos)
local dark_gen_step_count = mos.dark_gen_step_count(input_mos)
-- Setup for harmonic entropy
local step_ratios = {
{ 4, 3 },
{ 3, 2 },
{ 5, 3 },
{ 2, 1 },
{ 5, 2 },
{ 3, 1 },
{ 4, 1 },
}
-- Create the table, starting with the headers
local result = "{| class=\"wikitable\"\n"
.. "|+ style=\"font-size: 105%;\" | Intervals of " .. scale_sig .. "\n"
.. "! colspan=\"3\" | Intervals !! rowspan=\"2\" | Steps subtended !! rowspan=\"2\" | Range in cents !! rowspan=\"2\" | Average of [[HE]]<br/>(from [http://www.mikebattagliamusic.com/HE-JS/HE.html HE Calc])\n !! rowspan=\"2\" | Min of [[HE]]\n"
.. '|-\n'
.. '! Generic<sup>[[#mosstep-1|[1]]]</sup> !! Specific<sup>[[#mosstep-2|[2]]]</sup> !! Abbrev.<sup>[[#mosstep-3|[3]]]</sup>\n'
-- Write each row
for i = 1, #bright_step_matrix do
-- Compare the bright and dark intervals. If they're the same, then the
-- current interval class is a period interval.
local current_bright_interval = bright_step_matrix[i]
local current_dark_interval = dark_step_matrix[i]
local is_period = mos.interval_eq(current_bright_interval, current_dark_interval)
-- If it's a period interval, then there is only one row to write.
-- Otherwise, there are two rows to write, one for each size.
if is_period then
local cents = mos.interval_to_cents(current_bright_interval, input_mos, {1,1})
result = result .. "|-\n"
.. string.format("| '''%s-%sstep''' ", i - 1, mos_prefix)
.. string.format("|| %s " , tamnams.interval_quality(current_bright_interval, input_mos, "sentence-case"))
.. string.format("|| %s " , tamnams.interval_quality(current_bright_interval, input_mos, "abbrev", "m"))
.. string.format("|| %s " , mos.interval_as_string(current_bright_interval))
.. string.format("|| %.1f¢ ", cents)
.. string.format("|| ~%.4f nats ", he.harmonic_entropy(cents))
.. string.format("|| ~%.4f nats\n", he.harmonic_entropy(cents))
else
-- Calculate the best and average harmonic entropies
local he_dark_average = 0
local he_bright_average = 0
local he_dark_best = 1000
local he_bright_best = 1000
for i = 1, #step_ratios do
local step_ratio = step_ratios[i]
local he_dark = he.harmonic_entropy(mos.interval_to_cents(current_dark_interval, input_mos, step_ratio))
local he_bright = he.harmonic_entropy(mos.interval_to_cents(current_bright_interval, input_mos, step_ratio))
he_dark_average = he_dark_average + he_dark / #step_ratios
he_bright_average = he_bright_average + he_bright / #step_ratios
if he_dark_best > he_dark then
he_dark_best = he_dark
end
if he_bright_best > he_bright then
he_bright_best = he_bright
end
end
-- Calculate the cent values min and max for the current intervals
local sm_min_cents = mos.interval_to_cents(current_dark_interval, input_mos, {1,1})
local sm_max_cents = mos.interval_to_cents(current_dark_interval, input_mos, {1,0})
local lg_min_cents = mos.interval_to_cents(current_bright_interval, input_mos, {1,1})
local lg_max_cents = mos.interval_to_cents(current_bright_interval, input_mos, {1,0})
-- Then sort, as the min and max may be swapped
-- This happens if the dark interval has more small steps than large steps
local dark_interval_range = string.format("%.1f¢ to %.1f¢", math.min(sm_min_cents, sm_max_cents), math.max(sm_min_cents, sm_max_cents))
local bright_interval_range = string.format("%.1f¢ to %.1f¢", math.min(lg_min_cents, lg_max_cents), math.max(lg_min_cents, lg_max_cents))
result = result .. "|-\n"
.. string.format("| rowspan=\"2\" | %s-%sstep ", i - 1, mos_prefix)
.. string.format("|| %s " , tamnams.interval_quality(current_dark_interval, input_mos, "sentence-case"))
.. string.format("|| %s " , tamnams.interval_quality(current_dark_interval, input_mos, "abbrev", "m"))
.. string.format("|| %s " , mos.interval_as_string(current_dark_interval))
.. string.format("|| %s " , dark_interval_range)
.. string.format("|| ~%.4f nats " , he_dark_average)
.. string.format("|| ~%.4f nats\n" , he_dark_best)
.. "|-\n"
.. string.format("| %s " , tamnams.interval_quality(current_bright_interval, input_mos, "sentence-case"))
.. string.format("|| %s " , tamnams.interval_quality(current_bright_interval, input_mos, "abbrev", "m"))
.. string.format("|| %s " , mos.interval_as_string(current_bright_interval))
.. string.format("|| %s " , bright_interval_range)
.. string.format("|| ~%.4f nats " , he_bright_average)
.. string.format("|| ~%.4f nats\n" , he_bright_best)
end
end
result = result .. "|}\n"
.. "<span style=\"font-size: 0.75em;\">\n"
.. "# <span id=\"mosstep-1\">Generic intervals are denoted solely by the number of steps they subtend.</span>\n"
.. "# <span id=\"mosstep-2\">Specific intervals denote whether an interval is major, minor, augmented, perfect, or diminished.</span>\n"
.. "# <span id=\"mosstep-3\">Abbreviations can be further shortened to 'ms' if context allows.</span>\n"
.. "</span>"
return result
end
-- Wrapper function; to be called by template
function p.mos_intervals(frame)
-- Get input mos
local input_mos = mos.parse(frame.args["Scale Signature"])
-- Default param for mos prefix
-- If "NONE" is given, no prefix will be used
-- If left blank, try to find the appropriate mos prefix, or else defualt to "mos"
-- If not left blank, use the prefix passed in instead
local scale_sig = mos.as_string(input_mos)
local mos_prefix = tamnams.lookup_prefix(input_mos)
local mos_abbrev = tamnams.lookup_abbrev(input_mos)
if frame.args["MOS Prefix"] == "NONE" then
mos_prefix = ""
mos_abbrev = ""
elseif string.len(frame.args["MOS Prefix"]) > 0 then
mos_prefix = frame.args["MOS Prefix"]
mos_abbrev = frame.args["MOS Prefix"]
end
if frame.args["MOS Abbrev"] == "NONE" then
mos_abbrev = ""
elseif string.len(frame.args["MOS Abbrev"]) > 0 then
mos_abbrev = frame.args["MOS Abbrev"]
end
return p._mos_intervals(input_mos, mos_prefix, mos_abbrev)
end
return p