Module:MOS: Difference between revisions
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) |
Better comments; rewrote et_tuning_by_hardness() function as mos_to_et() and several interval_to_et_step functions |
||
| Line 6: | Line 6: | ||
-- - Finding certain modes of a mos | -- - Finding certain modes of a mos | ||
-- - Finding generators for a mos | -- - Finding generators for a mos | ||
-- - Producing vectors for simple mos intervals | |||
-- - Interval arithmetic, in the form of adding vectors of L's and s's, and | -- - Interval arithmetic, in the form of adding vectors of L's and s's, and | ||
-- period/equave-reducing intervals | -- period/equave-reducing intervals | ||
-- - Finding equal tunings for mosses | |||
local rat = require('Module:Rational') | local rat = require('Module:Rational') | ||
local utils = require('Module:Utils') | local utils = require('Module:Utils') | ||
local et = require('Module:ET') | local et = require('Module:ET') | ||
local p = {} | local p = {} | ||
| Line 24: | Line 26: | ||
-- - If a function requires an interval and mos as input, the interval(s) come | -- - If a function requires an interval and mos as input, the interval(s) come | ||
-- after the mos. | -- after the mos. | ||
-- - Functions that have to do with equal tunings will have "et" in its name. | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 243: | Line 246: | ||
['L'] = 0, | ['L'] = 0, | ||
['s'] = 0 | ['s'] = 0 | ||
} | |||
return result | |||
end | |||
-- 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() | |||
local result = { | |||
['L'] = 1, | |||
['s'] = -1 | |||
} | } | ||
return result | return result | ||
| Line 261: | Line 274: | ||
['L'] = 0, | ['L'] = 0, | ||
['s'] = 1 | ['s'] = 1 | ||
} | } | ||
return result | return result | ||
| Line 299: | Line 302: | ||
-- 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. | ||
-- EG, a perfect 4-diastep (perf. 5th) is 4 steps. Since it's the large size, | |||
-- the offset is 0, but to get the diminished 5th, the offset should be -1. | |||
function p.interval(mos, step_count, size_offset) | function p.interval(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 347: | Line 352: | ||
end | end | ||
-- Intervals | -- Intervals usually denote distances between two scale degrees and should be | ||
-- positive values. Normalizing makes a negative interval positive again. | |||
-- | |||
function p.normalize_interval(interval) | function p.normalize_interval(interval) | ||
return p.interval_step_count(interval) < 0 and p.interval_mul(interval, -1) or interval | return p.interval_step_count(interval) < 0 and p.interval_mul(interval, -1) or interval | ||
| Line 398: | 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. | ||
-- | -- If the number of chromas from a small (EG minor) interval is desired, then | ||
-- | -- using the param size_offset can be used: 0 for chromas from large size, -1 | ||
-- | -- for chromas from small size. This can exceed the range [-1, 0] if needed. | ||
-- EG, a diminished 2-diastep (dim. 3rd) has the vector {0,2}. It's reached by | |||
-- either lowering the major 2-step by 2 chromas, or lowering the minor 2-step | |||
-- by 1 chroma. | |||
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 | local size_offset = size_offset or 0 -- Default of 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) | ||
| Line 476: | Line 478: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
------------ | ---------------------------- EQUAL-TUNING FUNCTIONS ---------------------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Given mos a | -- Given a mos and a step ratio, return an equal tuning (or equal division). | ||
-- | -- The step ratio is entered as a 2-element array to allow non-simplified | ||
-- | -- ratios to be entered. (The rational module isn't suitable since it simplifies | ||
-- | -- ratios.) | ||
function p. | function p.mos_to_et(mos, step_ratio) | ||
local | local et_size = mos.nL * step_ratio[1] + mos.ns * step_ratio[2] | ||
return et.new(et_size, mos.equave, rat.as_ratio(mos.equave)) | |||
end | |||
end | -- Given a mos and a step ratio, return the number of et-steps for its bright | ||
-- generator. | |||
function p.bright_gen_to_et_steps(mos, step_ratio) | |||
return interval_to_et_steps(p.bright_gen(mos), step_ratio) | |||
local | end | ||
-- Given a mos and a step ratio, return the number of et-steps for its dark | |||
-- generator. | |||
function p.dark_gen_to_et_steps(mos, step_ratio) | |||
return interval_to_et_steps(p.dark_gen(mos), step_ratio) | |||
end | |||
-- Given a mos and a step ratio, return the number of et-steps for its period. | |||
function p.period_to_et_steps(mos, step_ratio) | |||
return interval_to_et_steps(p.period(mos), step_ratio) | |||
end | |||
-- Given a mos and a step ratio, return the number of et-steps for its equave. | |||
function p.equave_to_et_steps(mos, step_ratio) | |||
return interval_to_et_steps(p.equave(mos), step_ratio) | |||
end | |||
-- Given an interval vector and step ratio, compute the number of et-steps it | |||
-- corresponds to. (To find an et's cent value, use this as input for the et | |||
-- module's cents() function.) | |||
function p.interval_to_et_steps(interval, step_ratio) | |||
local et_size = interval['L'] * step_ratio[1] + interval['s'] * step_ratio[2] | |||
end | end | ||
-------------------------------------------------------------------------------- | |||
------------ UNUSED FUNCTIONS OR FUNCTIONS TO MOVE TO OTHER MODULES ------------ | |||
-------------------------------------------------------------------------------- | |||
-- Given a mos, find the ancestor mos with a target note count (default 10) | -- Given a mos, find the ancestor mos with a target note count (default 10) | ||
| Line 528: | Line 554: | ||
function p.tester() | function p.tester() | ||
local interval = p.dark_gen(p.new(5,2)) | --local interval = p.dark_gen(p.new(5,2)) | ||
return p.interval_chroma_count(interval, p.new(5,2), -1) | --return p.interval_chroma_count(interval, p.new(5,2), -1) | ||
return p.mos_to_et(p.new(5,2), {5,4}) | |||
end | end | ||
return p | return p | ||