Module:MOS degrees: Difference between revisions

Ganaram inukshuk (talk | contribs)
mNo edit summary
Ganaram inukshuk (talk | contribs)
Added a new function as part of a future rewrite
Line 47: Line 47:
return { num, den }
return { num, den }
end
-- Function that produces a chain of scale degrees. If the genchain function
-- from the module mos gamut were read as scale degrees, what would they be?
-- (EG, major 2nd, augmented 2nd, etc)
-- TODO: part of a rewrite for the mos degrees function
function p.mos_degreechain(input_mos, genchain_length_per_period, going_up)
-- Default parameters for testing
local input_mos = input_mos or mos.new(6, 2, 2)
local genchain_length_per_period = genchain_length_per_period or 10
local going_up = true
-- Get the number of mossteps per period and equave
local mossteps_per_equave = input_mos.nL + input_mos.ns
local periods_per_equave = rat.gcd(input_mos.nL, input_mos.ns)
local mossteps_per_period = mossteps_per_equave / periods_per_equave
-- The easiest way to get scale degrees is through the following method:
-- - Get the genchain corresponding to the second-brightest mode and
--  interpret the result as scale degrees.
-- - If this is the ascending chain, then this represents every interval
--  class' large size. For each period, the first two elements represent
--  the root (perfect) and bright generator (large size is perfect).
-- - If this is the descending chain, then find the period complement of
--  each element, which represents every interval class's small size.
--  For each period, the first two elements represent the root (perfect)
--  and dark generator (small size is perfect).
-- - Since the root and generators start as perfect, anything beyond that
--  represents augmented/diminished unisons/generators.
-- Note that this is agnostic of notation, so only the genchain length is
-- needed. The UDP for the second-brightest mode is auto-calculated and is
-- used regardless of whether the chain is going up or down.
local genchain = mosg.mos_genchain(input_mos, mossteps_per_period - 2, genchain_length_per_period, true)
-- Interpret as scale degrees
-- The first two elements are always perfect.
-- 0 chromas are major (or minor if descending)
-- 1 chroma is augmented, negative for diminished
-- n chromas is n-times augmented, negative for diminished
local degreechain = {}
for j = 1, periods_per_equave do
local chain_for_period = {}
for i = 1, #genchain[j] do
local note = genchain[j][i]
local mossteps = note['mossteps']
local chromas = note['chromas']
-- If not going up, use the period complements instead
-- Period complements of the root will end up being the note one
-- period up, so use modular arithmetic to keep the starting point
-- constrained to the root
local aug_or_dim = "augmented"
local maj_or_min = "major"
if not going_up then
mossteps =  (j - 1) * mossteps_per_period + (mossteps_per_period - mossteps) % mossteps_per_period
aug_or_dim = "diminished"
maj_or_min = "minor"
end
local quality = ""
if i == 1 then
quality = "perfect"
elseif i == 2 then
quality = "perfect"
else
if chromas == 0 then
quality = maj_or_min
elseif chromas == 1 then
quality = aug_or_dim
else
quality = chromas .. "×" .. aug_or_dim
end
end
local degree = quality .. " " .. mossteps .. "-mosstep"
table.insert(chain_for_period, degree)
end
table.insert(degreechain, chain_for_period)
end
return degreechain
end
end