Module:MOS: Difference between revisions
Removed name/prefix/abbrev lookup, as it's now handled by tamnams module |
More functions and function skeletons; comments; changes to some function names, order of params |
||
| 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 | ||
-- - Interval arithmetic, in the form of adding vectors of L's and s's | -- - Interval arithmetic, in the form of adding vectors of L's and s's, and | ||
-- period/equave-reducing intervals | |||
local rat = require('Module:Rational') | local rat = require('Module:Rational') | ||
local utils = require('Module:Utils') | local utils = require('Module:Utils') | ||
| Line 25: | Line 26: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Create a new mos. | -- Create a new mos. (Contains the number of large and small steps, and equave.) | ||
function p.new(nL, ns, equave) | function p.new(nL, ns, equave) | ||
local nL = nL or 5 | local nL = nL or 5 | ||
| Line 129: | Line 130: | ||
-- 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. | ||
-- Bright gen has two sizes: perfect (large) and diminished (small). The size | |||
-- given by this function is the large size. | |||
function p.bright_gen(mos) | function p.bright_gen(mos) | ||
local nL = mos.nL | local nL = mos.nL | ||
| Line 159: | Line 162: | ||
-- 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. | ||
-- Dark gen has two sizes: augmented (large) and perfect (small). The size | |||
-- given by this function is the small size. It's the period complement | |||
-- of the bright gen. | |||
function p.dark_gen(mos) | function p.dark_gen(mos) | ||
local bright_gen = p.bright_gen(mos) | local bright_gen = p.bright_gen(mos) | ||
return p.period_complement(mos, bright_gen) | |||
end | end | ||
-- Compute the period as a vector of L's and s's. | -- Compute the period as a vector of L's and s's. | ||
-- Period intervals only have one size: perfect. | |||
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 180: | Line 182: | ||
-- Compute the equave as a vector of L's and s's. | -- Compute the equave as a vector of L's and s's. | ||
-- Equave intervals only have one size: perfect. | |||
function p.equave(mos) | function p.equave(mos) | ||
local result = { | local result = { | ||
| Line 208: | Line 211: | ||
step_sequence = string.sub(step_sequence, 1, step_count) | step_sequence = string.sub(step_sequence, 1, step_count) | ||
local interval_vector = p.interval_from_step_sequence( | local interval_vector = p.interval_from_step_sequence(step_sequence) | ||
interval_vector['L'] = interval_vector['L'] + size | interval_vector['L'] = interval_vector['L'] + size | ||
interval_vector['s'] = interval_vector['s'] - size | interval_vector['s'] = interval_vector['s'] - size | ||
| Line 216: | Line 219: | ||
-- Compute an arbitrary mos interval (as a string of steps) as a vector of L's | -- Compute an arbitrary mos interval (as a string of steps) as a vector of L's | ||
-- and s's. This also serves as a helper function for p.interval(). | -- and s's. This also serves as a helper function for p.interval(). | ||
-- | -- Sequences of steps can be entered, where each step is one of five sizes: | ||
-- - L: large step. | -- - L: large step. | ||
-- - s: small step. | -- - s: small step. | ||
| Line 224: | Line 225: | ||
-- - A: an augmented step; a large step plus a chroma. | -- - A: an augmented step; a large step plus a chroma. | ||
-- - d: a diminished step, or diesis; a small step minus a chroma. | -- - d: a diminished step, or diesis; a small step minus a chroma. | ||
function p.interval_from_step_sequence( | function p.interval_from_step_sequence(step_sequence) | ||
local mossteps = #step_sequence | local mossteps = #step_sequence | ||
local interval_vector = { | local interval_vector = { | ||
| Line 253: | Line 254: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
---------------------- INTERVAL ARITHMETIC FUNCTIONS | ----------------------- INTERVAL ARITHMETIC FUNCTIONS -------------------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Note: interval arithmetic includes stacking and reducing intervals. | |||
-- Size comparisons between intervals can't be done using abstract steps, unless | |||
-- the intervals are the same number of mossteps (EG, a large k-step is larger | |||
-- than a small k-step, an augmented k-step is larger than a large k-step). | |||
-- Rule for formatting: if an interval arithmetic function requires a mos as | |||
-- part of its input, it should come after the interval vectors. | |||
-- Add two intervals together by adding their respective vectors | -- Add two intervals together by adding their respective vectors. | ||
function p. | function p.interval_add(v1, v2) | ||
local interval_vector = { | local interval_vector = { | ||
['L'] = v1['L'] + v2['L'], | ['L'] = v1['L'] + v2['L'], | ||
| Line 265: | Line 272: | ||
end | end | ||
-- Subtract two intervals together by subtracting their respective vectors | -- Subtract two intervals together by subtracting their respective vectors. | ||
function p. | function p.interval_sub(v1, v2) | ||
local interval_vector = { | local interval_vector = { | ||
['L'] = v1['L'] - v2['L'], | ['L'] = v1['L'] - v2['L'], | ||
| Line 274: | Line 281: | ||
end | end | ||
-- Repeatedly add the same interval to itself | -- Repeatedly add the same interval to itself. | ||
function p. | function p.interval_mul(v1, amt) | ||
local interval_vector = { | local interval_vector = { | ||
['L'] = v1['L'] * amt, | ['L'] = v1['L'] * amt, | ||
| Line 283: | Line 290: | ||
end | end | ||
function p.period_complement(mos, v1) | -- Given an interval vector and a mos, find its period complement. | ||
function p.period_complement(v1, mos) | |||
local period_vector = p.period(mos) | |||
return p.interval_sub(period_vector, v1) | |||
end | |||
-- Given an interval vector and a mos, find its equave complement. | |||
function p.equave_complement(v1, mos) | |||
local equave_vector = p.equave(mos, v1) | |||
return p.interval_sub(equave_vector, v1) | |||
end | |||
-- Given an interval vector and a mos, period-reduce it. | |||
function p.period_reduce(v1, mos) | |||
end | end | ||
function p. | -- Given an interval vector and a mos, equave-reduce it. | ||
function p.equave_reduce(v1, mos) | |||
end | end | ||
| Line 293: | Line 314: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Given a mos, compute the | -- Given a mos, compute the number of steps in its bright gen (L's plus s's). | ||
function p.bright_gen_step_count(mos) | function p.bright_gen_step_count(mos) | ||
local interval = p.bright_gen(mos) | local interval = p.bright_gen(mos) | ||
| Line 299: | Line 320: | ||
end | end | ||
-- Given a mos, compute the | -- Given a mos, compute the number of steps in its dark gen (L's plus s's). | ||
function p.dark_gen_step_count(mos) | function p.dark_gen_step_count(mos) | ||
local interval = p.dark_gen(mos) | local interval = p.dark_gen(mos) | ||
| Line 305: | Line 326: | ||
end | end | ||
-- Given a mos, compute the | -- Given a mos, compute the number of steps in its period (L's plus s's). | ||
function p.period_step_count(mos) | function p.period_step_count(mos) | ||
local interval = p.period(mos) | local interval = p.period(mos) | ||
| Line 311: | Line 332: | ||
end | end | ||
-- Given a mos, compute the | -- Given a mos, compute the number of steps in its equave (L's plus s's). | ||
function p.equave_step_count(mos) | function p.equave_step_count(mos) | ||
local interval = p.equave(mos) | local interval = p.equave(mos) | ||
| Line 317: | Line 338: | ||
end | end | ||
-- | -- Given a vector representing an interval, compute the number of mossteps it | ||
-- | -- corresponds to. Knowledge of the corresponding mos is not needed. | ||
function p.interval_step_count(interval) | function p.interval_step_count(interval) | ||
return interval['L'] + interval['s'] | return interval['L'] + interval['s'] | ||
| Line 330: | Line 351: | ||
-- return the et and the bright MOS generator corresponding to the hardness. | -- return the et and the bright MOS generator corresponding to the hardness. | ||
-- Currently unused | -- Currently unused | ||
--[[ | |||
function p.et_tuning_by_hardness(mos, hardness) | function p.et_tuning_by_hardness(mos, hardness) | ||
local nL, ns, equave = mos.nL, mos.ns, mos.equave | local nL, ns, equave = mos.nL, mos.ns, mos.equave | ||
| Line 342: | Line 364: | ||
return et, gen_steps | return et, gen_steps | ||
end | end | ||
]]-- | |||
-- 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 366: | Line 389: | ||
return p.new(z, w, mos.equave) | return p.new(z, w, mos.equave) | ||
end | end | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 374: | Line 396: | ||
-- Tester function | -- Tester function | ||
function p.tester() | function p.tester() | ||
return p.add_intervals({ ['L'] = 3, ['s'] = 1}, { ['L'] = 3, ['s'] = 1}) | --return p.add_intervals({ ['L'] = 3, ['s'] = 1}, { ['L'] = 3, ['s'] = 1}) | ||
--return p.interval(p.new(5, 2), 11, 0) | |||
return p.dark_gen(p.new(5, 2)) | |||
end | end | ||
return p | return p | ||