Module:MOS degrees: Difference between revisions

Ganaram inukshuk (talk | contribs)
Degreechain function no longer depends on mos gamut module; interval qualities are now encoded numerically (0 = perfect root, 1 = large size, -1 = small size, 2 = augmented, -2 = diminished, etc)
Ganaram inukshuk (talk | contribs)
Degreechain quality encoding (0=perfect, 1=major, -1=minor, 2=augmented, -2=diminished, etc) now names generators as augmented/perfect/diminished for mosses not of the form nL ns
Line 49: Line 49:
end
end


-- Function that produces a chain of scale degrees. If the genchain function
-- Function that produces a chain of scale degrees. What scale degrees are
-- from the module mos gamut were read as scale degrees, what would they be?
-- reached by stacking a generator?
-- (EG, major 2nd, augmented 2nd, etc)
-- (EG, major 2nd, augmented 2nd, etc)
-- This function only works one direction at a time, so it's necessary to call
-- it twice, one for each direction.
-- Quality encodes maj/min/aug/perf/dim numerically:
-- -  3 = 2x augmented
-- -  2 = 1x augmented
-- -  1 = major
-- -  0 = perfect (used for generators and root)
-- - -1 = minor
-- - -2 = 1x diminished
-- - -3 = 2x diminished
-- TODO: part of a rewrite for the mos degrees function
-- TODO: part of a rewrite for the mos degrees function
function p.mos_degreechain(input_mos, genchain_length_per_period, going_up)
function p.mos_degreechain(input_mos, genchain_length_per_period, going_up)
Line 58: Line 68:
local input_mos = input_mos or mos.new(5, 2, 2)
local input_mos = input_mos or mos.new(5, 2, 2)
local genchain_length_per_period = genchain_length_per_period or 10
local genchain_length_per_period = genchain_length_per_period or 10
local going_up = false
local going_up = true
]]--
]]--
Line 74: Line 84:
for j = 1, periods_per_equave do
for j = 1, periods_per_equave do
local chain_for_period = {}
local chain_for_period = {}
 
-- Define mossteps and quality as counters
-- Quality encodes major/minor/perfect/aug/dim numerically this way:
-- -  3 = 2x augmented
-- -  2 = 1x augmented
-- -  1 = large size (major; perfect for bright gen)
-- -  0 = perfect (reserved for root only)
-- - -1 = small size (minor; perfect for dark gen)
-- - -2 = 1x diminished
-- - -3 = 2x diminished
local mossteps = (j - 1) * mossteps_per_period
local quality = 0
for i = 1, genchain_length_per_period do
for i = 1, genchain_length_per_period do
-- Put together the name
local degree = { ['mossteps'] = mossteps, ['quality'] = quality }
table.insert(chain_for_period, degree)
-- Increment the counters
-- Calculate mossteps
local mossteps = 0
if going_up then
if going_up then
-- Increment quality when mossteps is the root of the period
mossteps = (i - 1) * mossteps_per_bright_gen % mossteps_per_period + (j - 1) * mossteps_per_period
if mossteps % mossteps_per_period == 0 then
else
quality = quality + 1
mossteps = (i - 1) * mossteps_per_dark_gen % mossteps_per_period + (j - 1) * mossteps_per_period
end
 
-- Calculate quality
-- The first two elements in the chain are always perfect
-- All intervals after that are major (or minor if going down)
-- After the major intervals are augmented intervals, which starts
-- with the augmented dark generator, which comes before the
-- augmented unison. (or minor and dim bright gen if going down)
-- For nL ns mosses, generators are major and minor instead, so only
-- the root is perfect
local quality = 0
if input_mos.nL ~= input_mos.ns then
if i == 1 or i == 2 then
quality = 0
else
-- Offsetting i by +1 will make it so the dark generator
-- before the augmented unison is denoted as augmented,
-- but lua's start-from-1 indexing offsets it by 1 already.
quality = math.floor(i / mossteps_per_period) + 1
if not going_up then
quality = quality * -1
end
end
end
mossteps = mossteps_per_bright_gen + mossteps -- Increment
mossteps = mossteps % mossteps_per_period -- Constrain
mossteps = mossteps + (j-1) * mossteps_per_period -- Offset by period
else
else
-- Increment quality when mossteps is the root of the period
if i == 1 then
if mossteps % mossteps_per_period == 0 then
quality = 0
quality = quality - 1
else
quality = math.floor((i + 1) / mossteps_per_period)
if not going_up then
quality = quality * -1
end
end
end
mossteps = mossteps_per_dark_gen + mossteps -- Increment
mossteps = mossteps % mossteps_per_period -- Constrain
-- Use contrained mossteps value to determine whether to
-- decrement the quality
mossteps = mossteps + (j-1) * mossteps_per_period -- Offset by period
end
end
-- Put together the name
local degree = { ['mossteps'] = mossteps, ['quality'] = quality }
table.insert(chain_for_period, degree)
end
end
table.insert(degreechain, chain_for_period)
table.insert(degreechain, chain_for_period)