Module:MOS degrees: Difference between revisions
No edit summary |
Added helper functions for ease of adding step/cent values (possibly for multiple step ratios) |
||
| Line 5: | Line 5: | ||
local mosnot = require('Module:MOS notation') -- Contains the important functions | local mosnot = require('Module:MOS notation') -- Contains the important functions | ||
local p = {} | local p = {} | ||
-- Helper function (TODO: add to main function) | |||
-- Creates the columns for the degree name and note name | |||
function p.preprocess_degrees_and_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length) | |||
-- Test parameters | |||
local input_mos = input_mos or mos.new(5, 2, 2) | |||
local udp = udp or { 3, 3 } | |||
local note_symbols = note_symbols or "DEFGABC" | |||
local sharp_symbol = sharp_symbol or "#" | |||
local flat_symbol = flat_symbol or "b" | |||
local asc_chain_length = input_mos.nL * 2 + input_mos.ns | |||
local des_chain_length = input_mos.nL * 2 + input_mos.ns | |||
-- Get the number of mossteps per period and equave | |||
local mossteps_per_equave = input_mos.nL + input_mos.ns | |||
local periods_per_equave = rat.gcd(input_mos.nL, input_mos.ns) | |||
local mossteps_per_period = mossteps_per_equave / periods_per_equave | |||
-- How long are the initial genchain lengths? (These correspond to the UDP) | |||
local gens_up_per_period = udp[1] / periods_per_equave | |||
local gens_dn_per_period = udp[2] / periods_per_equave | |||
-- Get the genchains | |||
local asc_genchain = mosnot.mos_nomacc_chain(input_mos, gens_up_per_period, asc_chain_length, true) | |||
local des_genchain = mosnot.mos_nomacc_chain(input_mos, gens_dn_per_period, des_chain_length, false) | |||
-- Get the degrees | |||
local asc_degrees = mosnot.mos_degree_chain(input_mos, asc_chain_length, true) | |||
local des_degrees = mosnot.mos_degree_chain(input_mos, des_chain_length, false) | |||
-- Calculate the entries for each row | |||
local rows = {} | |||
for i = 1, periods_per_equave do | |||
-- Add degrees from ascending chain | |||
for j = 1, asc_chain_length do | |||
local mossteps = asc_genchain[i][j]['mossteps'] | |||
local chromas = asc_genchain[i][j]['chromas'] | |||
local quality = asc_degrees [i][j]['quality'] | |||
-- Find the note name | |||
local note_symbol = string.sub(note_symbols, mossteps + 1, mossteps + 1) | |||
local note_name = mosnot.mosstep_and_chroma_to_note_name(mossteps, chromas, note_symbol, sharp_symbol) | |||
-- Find the degree name | |||
-- If the degree is the perfect 0-mosdegree, append "unison" | |||
local degree_name = mosnot.mosstep_and_quality_to_degree(mossteps, quality) | |||
if mossteps == 0 and quality == 0 then | |||
degree_name = degree_name .. " (unison)" | |||
end | |||
local row = { note_name, degree_name } | |||
table.insert(rows, row) | |||
end | |||
-- Calculate the stop value for the for loop as being 1 or 2, depending | |||
-- on whether this is the last period or not | |||
local stop_value = 1 | |||
if i ~= periods_per_equave then | |||
stop_value = stop_value + 1 | |||
end | |||
-- Add degrees from descending chain | |||
for j = des_chain_length, stop_value, -1 do | |||
local mossteps = des_genchain[i][j]['mossteps'] | |||
local chromas = des_genchain[i][j]['chromas'] | |||
local quality = des_degrees [i][j]['quality'] | |||
-- Find the note name | |||
-- If the mosstep is the root of the period, add a period to it | |||
local note_symbol = string.sub(note_symbols, mossteps + 1, mossteps + 1) | |||
if mossteps % mossteps_per_period == 0 then | |||
mossteps = mossteps + mossteps_per_period | |||
end | |||
local note_name = mosnot.mosstep_and_chroma_to_note_name(mossteps, chromas, note_symbol, flat_symbol) | |||
-- Find the degree name | |||
-- If the degree corresponds to the equave, say it's the equave | |||
local degree_name = mosnot.mosstep_and_quality_to_degree(mossteps, quality) | |||
-- If the mosstep is the perfect equave, append "equave" | |||
if mossteps == mossteps_per_equave and quality == 0 then | |||
degree_name = degree_name .. " (equave)" | |||
end | |||
local row = { note_name, degree_name } | |||
table.insert(rows, row) | |||
end | |||
end | |||
return rows | |||
end | |||
-- Helper function (TODO: add to main function) | |||
-- Creates the columns for the step and cent sizes | |||
-- This is its own function for adding multiple columns | |||
function p.preprocess_steps_and_cents(input_mos, step_ratio, asc_chain_length, des_chain_length) | |||
-- Test parameters | |||
local input_mos = input_mos or mos.new(5, 2, 2) | |||
local step_ratio = { 2, 1 } | |||
local asc_chain_length = input_mos.nL * 2 + input_mos.ns | |||
local des_chain_length = input_mos.nL * 2 + input_mos.ns | |||
-- Get the number of mossteps per period and equave | |||
local mossteps_per_equave = input_mos.nL + input_mos.ns | |||
local periods_per_equave = rat.gcd(input_mos.nL, input_mos.ns) | |||
local mossteps_per_period = mossteps_per_equave / periods_per_equave | |||
-- What et is produced given the step ratio and equave? | |||
local steps_in_et = input_mos.nL * step_ratio[1] + input_mos.ns * step_ratio[2] | |||
local et_for_mos = et.new(steps_in_et, input_mos.equave) | |||
-- How many esteps per period? Per bright/dark gen? | |||
local esteps_per_period = steps_in_et / periods_per_equave | |||
local bright_gen = mos.bright_gen(input_mos) | |||
local esteps_per_bright_gen = bright_gen['L'] * step_ratio[1] + bright_gen['s'] * step_ratio[2] | |||
local esteps_per_dark_gen = esteps_per_period - esteps_per_bright_gen | |||
-- Calculate the entries for each row | |||
local rows = {} | |||
for i = 1, periods_per_equave do | |||
-- Add degrees from ascending chain | |||
for j = 1, asc_chain_length do | |||
-- Find the estep count | |||
local estep_count = ((j - 1) * esteps_per_bright_gen) % esteps_per_period + (i - 1) * esteps_per_period | |||
-- Find the cent value, rounded | |||
local cent_value = et.cents(et_for_mos, estep_count) | |||
cent_value = utils._round_dec(cent_value, 1) | |||
-- Add the row | |||
local row = { estep_count, cent_value } | |||
table.insert(rows, row) | |||
end | |||
-- Calculate the stop value for the for loop as being 1 or 2, depending | |||
-- on whether this is the last period or not | |||
local stop_value = 1 | |||
if i ~= periods_per_equave then | |||
stop_value = stop_value + 1 | |||
end | |||
-- Add degrees from descending chain | |||
for j = des_chain_length, stop_value, -1 do | |||
-- Find the estep count | |||
local estep_count = ((j - 1) * esteps_per_dark_gen) % esteps_per_period + (i - 1) * esteps_per_period | |||
-- Find the cent value | |||
local cent_value = et.cents(et_for_mos, estep_count) | |||
cent_value = utils._round_dec(cent_value, 1) | |||
-- Add the row | |||
local row = { estep_count, cent_value } | |||
table.insert(rows, row) | |||
end | |||
end | |||
return rows | |||
end | |||
-- Algorithm: | -- Algorithm: | ||