Module:MOS: Difference between revisions
Review code+comments as being its own documentation |
comment review |
||
| Line 10: | Line 10: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Helper function | |||
function p.find_item_in_table(table, item) | function p.find_item_in_table(table, item) | ||
local item_found = false | local item_found = false | ||
| Line 26: | Line 27: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Create a new mos | -- Create a new mos as a table containing the counts for large and small steps, | ||
-- plus the equave. | |||
function p.new(nL, ns, equave) | function p.new(nL, ns, equave) | ||
local nL = nL or 5 | local nL = nL or 5 | ||
| Line 35: | Line 37: | ||
end | end | ||
-- Parse a mos from its scalesig. | -- Parse a mos from its scalesig "xL ys<p/q>" or "xL ys (p/q-equivalent)". | ||
-- If no equave "p/q" is provided, it's assumed to be 2/1-equivalent. | |||
function p.parse(unparsed) | function p.parse(unparsed) | ||
local nL, ns, equave = unparsed:match("^(%d+)[Ll]%s*(%d+)[Ss]%s*(.*)$") | local nL, ns, equave = unparsed:match("^(%d+)[Ll]%s*(%d+)[Ss]%s*(.*)$") | ||
| Line 77: | Line 80: | ||
-- Degenerate mosses (nL 0s or 0L ns) produce a string for its corresponding | -- Degenerate mosses (nL 0s or 0L ns) produce a string for its corresponding | ||
-- et (n-ed-p/q). | -- et (n-ed-p/q). | ||
-- Option to use nbsp is provided using the second param; default is nbsp | -- Option to use nbsp is provided using the second param; default is nbsp. | ||
function p.as_string(mos, use_nbsp) | function p.as_string(mos, use_nbsp) | ||
if p.is_valid(mos) then | if p.is_valid(mos) then | ||
| Line 95: | Line 98: | ||
-- Degenerate mosses (nL 0s or 0L ns) produce a string for its corresponding | -- Degenerate mosses (nL 0s or 0L ns) produce a string for its corresponding | ||
-- et (n-ed-p/q). | -- et (n-ed-p/q). | ||
-- Option to use nbsp is provided using the second param; default is nbsp | -- Option to use nbsp is provided using the second param; default is nbsp. | ||
function p.as_long_string(mos, use_nbsp) | function p.as_long_string(mos, use_nbsp) | ||
if p.is_valid(mos) then | if p.is_valid(mos) then | ||
| Line 178: | Line 181: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Find the parent mos of a mos. May return invalid mosses (nL 0s), meant | -- Find the parent mos of a mos. May return invalid mosses (nL 0s), meant to | ||
-- | -- represent equal divisions of the octave (or arbitrary equave). | ||
function p.parent(mos) | function p.parent(mos) | ||
return p.new(math.min(mos.nL, mos.ns), math.abs(mos.nL-mos.ns), mos.equave) | return p.new(math.min(mos.nL, mos.ns), math.abs(mos.nL-mos.ns), mos.equave) | ||
| Line 292: | Line 295: | ||
end | end | ||
-- List all unique rotations for a mode, by order of leftward shifts. | -- List all unique rotations for a mode, by order of leftward shifts. Order by | ||
-- rotation will usually give a different order compared to order by brightness, | |||
-- but this is expected if the order isn't by brightness (EG, modmosses). | |||
-- Note: there will always be s/p modes, where s is the number of steps in the | -- Note: there will always be s/p modes, where s is the number of steps in the | ||
-- entered mode, and p is the period of repetition. At most, there will be s | -- entered mode, and p is the period of repetition. At most, there will be s | ||
| Line 395: | Line 400: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Compute the bright gen as a vector of L's and s's. | -- Compute the bright gen as a vector of L's and s's. Since all mosstep | ||
-- | -- intervals (excluding the root and period) have two sizes, this returns the | ||
-- | -- large/perfect size. | ||
function p.bright_gen(mos) | function p.bright_gen(mos) | ||
local nL = mos.nL | local nL = mos.nL | ||
| Line 428: | Line 433: | ||
end | end | ||
-- Compute the dark gen as a vector of L's and s's. | -- Compute the dark gen as a vector of L's and s's. Since all mosstep | ||
-- | -- intervals (excluding the root and period) have two sizes, this returns the | ||
-- | -- small/perfect size. | ||
function p.dark_gen(mos) | function p.dark_gen(mos) | ||
local bright_gen = p.bright_gen(mos) | local bright_gen = p.bright_gen(mos) | ||
| Line 437: | Line 441: | ||
end | end | ||
-- Compute the period as a vector of L's and s's. Period intervals only | -- Compute the period as a vector of L's and s's. | ||
-- Period intervals as mossteps only appear as one size. | |||
function p.period(mos) | function p.period(mos) | ||
local gcd = utils._gcd(mos.nL, mos.ns) | local gcd = utils._gcd(mos.nL, mos.ns) | ||
| Line 447: | Line 452: | ||
-- Compute the equave as a vector of L's and s's. | -- Compute the equave as a vector of L's and s's. | ||
-- | -- Equaves as mossteps only appear as one size. For a single-period mos, this | ||
-- the same | -- is the same as p.period(). | ||
function p.equave(mos) | function p.equave(mos) | ||
return { | return { | ||
| Line 460: | Line 465: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- | -- Return the unison as a vector of L's and s's. | ||
-- The unison is denoted by moving up from the root by zero steps, and thus does | -- The unison is denoted by moving up from the root by zero steps, and thus does | ||
-- not need a mos as input. It's basically a zero vector. | -- not need a mos as input. It's basically a zero vector. | ||
| Line 468: | Line 473: | ||
end | end | ||
-- | -- Return the vector for a single chroma. It's a large step minus a small step. | ||
-- Adding or subtracting any interval by this interval changes its "size". | -- Adding or subtracting any interval by this interval changes its "size". | ||
function p.chroma() | function p.chroma() | ||
| Line 474: | Line 479: | ||
end | end | ||
-- | -- Return the vector for an augmented step. It's a large step plus a chroma. | ||
function p.augmented_step() | function p.augmented_step() | ||
return { ["L"] = 2, ["s"] = -1 } | return { ["L"] = 2, ["s"] = -1 } | ||
end | end | ||
-- | -- Return the vector for a single large step. | ||
function p.large_step() | function p.large_step() | ||
return { ["L"] = 1, ["s"] = 0 } | return { ["L"] = 1, ["s"] = 0 } | ||
end | end | ||
-- | -- Return the vector for a single small step. | ||
function p.small_step() | function p.small_step() | ||
return { ["L"] = 0, ["s"] = 1 } | return { ["L"] = 0, ["s"] = 1 } | ||
end | end | ||
-- | -- Return the vector for a diminished step. It's a small step minus a chroma. | ||
function p.diminished_step() | function p.diminished_step() | ||
return { ["L"] = -1, ["s"] = 2 } | return { ["L"] = -1, ["s"] = 2 } | ||
| Line 503: | Line 508: | ||
end | end | ||
-- Compute an arbitrary mos interval as a vector of L's and s's. | -- Compute an arbitrary mos interval as a vector of L's and s's. Params: | ||
-- | -- - step_count: the number of steps subtended by the mosstep. | ||
-- - size_offset: denotes whether to return the large size (0) or the small | |||
- | -- size (-1) (or if this is a period interval, the diminished size). Values | ||
-- other than 0 or 1 represent alterations by multiple chromas, such as | |||
-- | -- augmented (1) or diminished (-2). | ||
-- | |||
-- | |||
-- | |||
- | |||
function p.interval_from_mos(mos, step_count, size_offset) | function p.interval_from_mos(mos, step_count, size_offset) | ||
local size_offset = size_offset or 0 -- Optional param; defaults to large size | local size_offset = size_offset or 0 -- Optional param; defaults to large size | ||
| Line 599: | Line 598: | ||
-- perfect size (for period/root/equave intervals). This requires the mos as | -- perfect size (for period/root/equave intervals). This requires the mos as | ||
-- input. | -- input. | ||
-- | -- size_offset denotes whether to count chromas from the large size; changing | ||
-- this to -1 counts chromas from the small size. Like size_offset for | |||
-- | -- interval_from_mos, this can be used to denote altered mossteps (augmented, | ||
-- | -- diminished, etc). | ||
-- | |||
function p.interval_chroma_count(interval, mos, size_offset) | function p.interval_chroma_count(interval, mos, size_offset) | ||
local size_offset = size_offset or 0 -- Default of 0. | local size_offset = size_offset or 0 -- Default of 0. | ||
| Line 633: | Line 630: | ||
end | end | ||
-- | -- Stack an interval, or repeatedly add the same interval to itself. | ||
function p.interval_mul(interval, amt) | function p.interval_mul(interval, amt) | ||
return { | return { | ||