Module:MOS: Difference between revisions
Added function for making arbitrary intervals; renamed interval() to interval_from_mos() to be more descriptive |
Reclassify functions; added mode rotation function; added arbitrary mode function; added function to negate an interval; simplified code for a few cent functions |
||
| Line 117: | Line 117: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Find the brightest (true-mos) mode of a mos. | -- Find the brightest (true-mos) mode of a mos, as a string of L's and s's. | ||
-- Calculation is based on the definition of a Christoffel word, as the closest | -- Calculation is based on the definition of a Christoffel word, as the closest | ||
-- integer approximation to line y = #s/#L*x. | -- integer approximation to line y = #s/#L*x. | ||
| Line 164: | Line 164: | ||
end | end | ||
return string.rep(result, d) | return string.rep(result, d) | ||
end | |||
-- Given a mos, return a mode based on how it's ranked by modal brightness. | |||
-- 0 is brightest, 1 is 2nd-brightest, 2 is 3rd-brightest, etc... These values | |||
-- can be thought of as rotate amounts (for p.rotate_mode()), where the size of | |||
-- the bright gen is a multiplier, so the kth brightest mode rotates the | |||
-- brightest mode k * g times (where g is the size of the generator). | |||
function p.mode_from_mos(mos, brightness) | |||
return p.rotate_mode(p.brightest_mode(mos), brightness * p.bright_gen_step_count(mos)) | |||
end | |||
-- Rotate a mode by shifting the step sequence to the left. Negative values | |||
-- shift it to the right. Helper function for mode_from_mos(). | |||
function p.rotate_mode(mode_string, shift_amt) | |||
local shift_amt = shift_amt % #mode_string | |||
local first = string.sub(mode_string, 1, shift_amt) | |||
local second = string.sub(mode_string, shift_amt + 1, #mode_string) | |||
return second .. first | |||
end | end | ||
| Line 332: | Line 350: | ||
return interval_vector | return interval_vector | ||
end | end | ||
| Line 424: | Line 436: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
---------------------- | ---------------------- INTERVAL MANIPULATION FUNCTIONS ------------------------- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 461: | Line 473: | ||
return p.interval_sub(interval, equaves) | return p.interval_sub(interval, equaves) | ||
end | |||
-- Invert an interval. This makes an interval negative. | |||
function p.invert_interval(interval) | |||
return p.interval_mul(interval, -1) | |||
end | |||
-- 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) | |||
return p.interval_step_count(interval) < 0 and p.interval_mul(interval, -1) or interval | |||
end | end | ||
| Line 508: | Line 531: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- Given a mos and a step ratio, return the number of cents for its bright | -- Given a mos and a step ratio, return the number of cents for its bright gen. | ||
function p.bright_gen_to_cents(mos, step_ratio) | function p.bright_gen_to_cents(mos, step_ratio) | ||
local interval_steps = p.interval_to_et_steps(p.bright_gen(mos), step_ratio) | local interval_steps = p.interval_to_et_steps(p.bright_gen(mos), step_ratio) | ||
| Line 516: | Line 538: | ||
end | end | ||
-- Given a mos and a step ratio, return the number of cents for its dark | -- Given a mos and a step ratio, return the number of cents for its dark gen. | ||
function p.dark_gen_to_cents(mos, step_ratio) | function p.dark_gen_to_cents(mos, step_ratio) | ||
local interval_steps = p.interval_to_et_steps(p.dark_gen(mos), step_ratio) | local interval_steps = p.interval_to_et_steps(p.dark_gen(mos), step_ratio) | ||
| Line 525: | Line 546: | ||
-- Given a mos and a step ratio, return the number of cents for its period. | -- Given a mos and a step ratio, return the number of cents for its period. | ||
-- The period is the interval at which the step pattern repeats, so no step | |||
-- ratio is needed. | |||
function p.period_to_cents(mos) | |||
return | return rat.cents(mos.equave) / p.period_count(mos) | ||
end | end | ||
-- Given a mos and a step ratio, return the number of cents for its equave. | -- Given a mos and a step ratio, return the number of cents for its equave. | ||
-- The period is the interval at which the step pattern repeats, and the equave | |||
-- is a multiple of that (at least for multi-period mosses), so no step ratio is | |||
-- needed. | |||
return | function p.equave_to_cents(mos) | ||
return rat.cents(mos.equave) | |||
end | end | ||
-- Given an interval vector and step ratio, | -- Given an interval vector and step ratio, convert it to cents. This requires | ||
-- | -- info about the mos itself. | ||
function p.interval_to_cents(interval, mos, step_ratio) | function p.interval_to_cents(interval, mos, step_ratio) | ||
local interval_steps = p.interval_to_et_steps(interval, step_ratio) | local interval_steps = p.interval_to_et_steps(interval, step_ratio) | ||
| Line 586: | Line 608: | ||
--return p.interval_from_mos(p.new(5,2), 4, 1) | --return p.interval_from_mos(p.new(5,2), 4, 1) | ||
--return p.interval_from_step_sequence("LLLdLLc") | --return p.interval_from_step_sequence("LLLdLLc") | ||
return p. | return p.mode_from_mos(p.new(5,2), -90673) | ||
end | end | ||
return p | return p | ||