Module:MOS: Difference between revisions

Ganaram inukshuk (talk | contribs)
Removed name/prefix/abbrev lookup, as it's now handled by tamnams module
Ganaram inukshuk (talk | contribs)
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)
local period = p.period(mos)
return p.period_complement(mos, bright_gen)
local dark_gen = {
['L'] = period['L'] - bright_gen['L'],
['s'] = period['s'] - bright_gen['s']
}
return dark_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(mos, 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().
-- This operates similarly to the above function, except arbitrary strings can
-- Sequences of steps can be entered, where each step is one of five sizes:
-- be entered, such as with step sequences for certain modmosses. The step types
-- are as follows:
-- - 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(mos, 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.add_intervals(v1, v2)
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.subtract_intervals(v1, v2)
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.multiply_interval(v1, amt)
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.equave_complement(mos, v1)
-- 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 size of the bright gen in mossteps (L's plus s's).
-- 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 size of the dark gen in mossteps (L's plus s's).
-- 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 size of the period in mossteps (L's plus s's).
-- 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 size of the equave in mossteps (L's plus s's).
-- 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


-- Compute the k-mosstep corresponding to a vector of L's and s's.
-- Given a vector representing an interval, compute the number of mossteps it
-- This does not require the mos it corresponds to.
-- 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