Module:MOS: Difference between revisions
Added step matrix function |
Added mode rotation functions |
||
| Line 35: | Line 35: | ||
local mult = 10^(numDecimalPlaces or 0) | local mult = 10^(numDecimalPlaces or 0) | ||
return math.floor(num * mult + 0.5) / mult | return math.floor(num * mult + 0.5) / mult | ||
end | |||
function p.find_item_in_table(table, item) | |||
local item_found = false | |||
for i = 1, #table do | |||
if table[i] == item then | |||
item_found = true | |||
break | |||
end | |||
end | |||
return item_found | |||
end | end | ||
| Line 173: | Line 184: | ||
function p.mode_from_mos(mos, brightness) | function p.mode_from_mos(mos, brightness) | ||
return p.rotate_mode(p.brightest_mode(mos), brightness * p.bright_gen_step_count(mos)) | return p.rotate_mode(p.brightest_mode(mos), brightness * p.bright_gen_step_count(mos)) | ||
end | |||
-------------------------------------------------------------------------------- | |||
--------------------------- MODE ROTATION FUNCTIONS ---------------------------- | |||
-------------------------------------------------------------------------------- | |||
-- Given a mos, list all modes in descending order of brightness. | |||
function p.modes_by_brightness(mos) | |||
local bright_gen_step_count = p.bright_gen_step_count(mos) | |||
local period_step_count = p.period_step_count(mos) | |||
local modes = {} | |||
local current_mode = p.brightest_mode(mos) | |||
for i = 1, period_step_count do | |||
table.insert(modes, current_mode) | |||
current_mode = p.rotate_mode(current_mode, bright_gen_step_count) | |||
end | |||
return modes | |||
end | |||
-- List all unique rotations for a mode. Order of modes is by rotation. | |||
-- Note: there will always be s/p modes, where s is the number of steps in the | |||
-- entered mode, and p is the period of repetition. At most, there will be s | |||
-- modes, but if there is a substring of length p that repeats within the mode | |||
-- (where p divides s with remainder = 0), then there will be p modes. It's also | |||
-- possible to have only one mode, but this can only happen if there is only one | |||
-- step size, meaning it's a unary scale (only one step size). | |||
function p.mode_rotations(mode_string) | |||
local rotations = {} | |||
local current_mode = mode_string | |||
for i = 1, #mode_string do | |||
if not p.find_item_in_table(rotations, current_mode) then | |||
table.insert(rotations, current_mode) | |||
end | |||
current_mode = p.rotate_mode(current_mode) | |||
end | |||
return rotations | |||
end | end | ||
| Line 178: | Line 226: | ||
-- shift it to the right. Helper function for mode_from_mos(). | -- shift it to the right. Helper function for mode_from_mos(). | ||
function p.rotate_mode(mode_string, shift_amt) | function p.rotate_mode(mode_string, shift_amt) | ||
local shift_amt = shift_amt % #mode_string | local shift_amt = shift_amt == nil and 1 or shift_amt % #mode_string -- Defualt is 1 | ||
local first = string.sub(mode_string, 1, shift_amt) | local first = string.sub(mode_string, 1, shift_amt) | ||
local second = string.sub(mode_string, shift_amt + 1, #mode_string) | local second = string.sub(mode_string, shift_amt + 1, #mode_string) | ||
| Line 184: | Line 233: | ||
end | end | ||
-- Convert a mode (as a string of steps) into a step matrix. | -- Convert a mode (as a string of steps) into a step matrix. This is a listing | ||
-- of every interval's step vector in the mode. | |||
function p.mode_to_step_matrix(mode_string) | function p.mode_to_step_matrix(mode_string) | ||
local matrix = {} | local matrix = {} | ||
| Line 620: | Line 670: | ||
--return p.interval_from_step_sequence("LLLdLLc") | --return p.interval_from_step_sequence("LLLdLLc") | ||
--return p.mode_from_mos(p.new(5,2), -90673) | --return p.mode_from_mos(p.new(5,2), -90673) | ||
return p.mode_to_step_matrix(p.brightest_mode(p.new(5,4))) | --return p.mode_to_step_matrix(p.brightest_mode(p.new(5,4))) | ||
return p.mode_rotations("LssLLssL") | |||
end | end | ||
return p | return p | ||