Module:MOS: Difference between revisions
Added functions for basic 1-step sizes |
Bugfixes, added size-offset param to chroma-count function; added normalize function that turns negative intervals back into positive intervals (since intervals here are meant to be interpreted as distances between two scale degrees) |
||
| Line 257: | Line 257: | ||
-- Compute the vector for a single small step. | -- Compute the vector for a single small step. | ||
function p. | function p.small_step() | ||
local result = { | local result = { | ||
['L'] = 0, | ['L'] = 0, | ||
| Line 266: | Line 266: | ||
-- Compute the vector for a single chroma. It's a large step minus a small step. | -- Compute 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". | |||
function p.chroma() | function p.chroma() | ||
local result = { | local result = { | ||
| Line 279: | Line 280: | ||
end | end | ||
-- Compute the vector for a diminished step. It's a small | -- Compute the vector for a diminished step. It's a small step minus a chroma. | ||
function p.diminished_step() | function p.diminished_step() | ||
return p.interval_sub(p.small_step(), p.chroma()) | return p.interval_sub(p.small_step(), p.chroma()) | ||
| Line 293: | Line 294: | ||
-- Mossteps larger than the equave (eg, the minor 9th in non-xen music theory) | -- Mossteps larger than the equave (eg, the minor 9th in non-xen music theory) | ||
-- are allowed. | -- are allowed. | ||
-- The | -- The size_offset denotes whether the interval is the large size (0) or the | ||
-- small size (-1). This can exceed the range of [-1, 0] to represent intervals | |||
-- | -- raised/lowered by multiple chromas (augmented, diminished, etc). | ||
-- Note that for period intervals (eg, the root and equave), there is only one | -- Note that for period intervals (eg, the root and equave), there is only one | ||
-- size (0 = perfect), so -1 is diminished and 1 is augmented. | -- size (0 = perfect), so -1 is diminished and 1 is augmented. | ||
function p.interval(mos, step_count, | function p.interval(mos, step_count, size_offset) | ||
local | local size_offset = size_offset or 0 -- Optional param; defaults to large size | ||
local step_sequence = p.brightest_mode(mos) | local step_sequence = p.brightest_mode(mos) | ||
step_sequence = string.rep(step_sequence, math.ceil(step_count/(mos.nL + mos.ns))) | step_sequence = string.rep(step_sequence, math.ceil(step_count/(mos.nL + mos.ns))) | ||
| Line 305: | Line 306: | ||
local interval_vector = p.interval_from_step_sequence(step_sequence) | local interval_vector = p.interval_from_step_sequence(step_sequence) | ||
interval_vector['L'] = interval_vector['L'] + | interval_vector['L'] = interval_vector['L'] + size_offset | ||
interval_vector['s'] = interval_vector['s'] - | interval_vector['s'] = interval_vector['s'] - size_offset | ||
return interval_vector | return interval_vector | ||
end | end | ||
| Line 344: | Line 345: | ||
return interval_vector | return interval_vector | ||
end | |||
-- Intervals always denote positive values as they are distances between two | |||
-- scale degrees, even if in the interval vector, one value is negative. | |||
-- In cases where a negative interval is encountered or was previously needed, | |||
-- such as if negative intervals denote direction (downwards stacking instead of | |||
-- upwards stacking), normalize_interavl() makes those intervals positive again. | |||
-- EG, a perfect 4-diastep (perfect 5th) is the vector { 3, 1 }, but so is | |||
-- { -3, -1 }. | |||
function p.normalize_interval(interval) | |||
return p.interval_step_count(interval) < 0 and p.interval_mul(interval, -1) or interval | |||
end | end | ||
| Line 386: | Line 398: | ||
-- 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. | ||
function p.interval_chroma_count(interval, mos) | -- The offset param is used to denote whether the interval is the large size (0) | ||
-- or the small size (-1). This way, the small size of an interval is shown as | |||
-- having zero chromas IF the interval is to be viewed as its small size rather | |||
-- than the large size. This can exceed the range [-1, 0] if needed. | |||
function p.interval_chroma_count(interval, mos, size_offset) | |||
local size_offset = size_offset or 0 | |||
local step_count = p.interval_step_count(interval) | local step_count = p.interval_step_count(interval) | ||
local base_interval = p.interval(mos, step_count, 0) | local base_interval = p.interval(mos, step_count, 0) | ||
return interval['L'] - base_interval['L'] | return interval['L'] - base_interval['L'] - size_offset | ||
end | end | ||
| Line 446: | Line 463: | ||
local periods = p.interval_mul(p.period(mos), reduce_amt) | local periods = p.interval_mul(p.period(mos), reduce_amt) | ||
return p.interval_sub(interval) | return p.interval_sub(interval, periods) | ||
end | end | ||
| Line 510: | Line 527: | ||
-- Tester function | -- Tester function | ||
function p.tester() | function p.tester() | ||
local interval = p.dark_gen(p.new(5,2)) | |||
return p.interval_chroma_count(interval, p.new(5,2), -1) | |||
end | end | ||
return p | return p | ||