Module:MOS degrees: Difference between revisions

Ganaram inukshuk (talk | contribs)
Added decoupled note names preprocess function; new functions to be added later
Ganaram inukshuk (talk | contribs)
Added support for omitting note names from table; may require debugging
Line 50: Line 50:
end
end


-- Helper function
-- Helper function; creates the column for the note name
-- Creates the columns for the degree name and note name
-- TODO: Separarte degrees and note names into two separate functions
function p.preprocess_degrees_and_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length, prefix, notation)
-- 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, prefix, notation)
if mossteps == 0 and quality == 0 then
degree_name = degree_name .. " (unison)"
end
local row = { degree_name, note_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
-- The descending chain differs from the ascending chain:
-- - The descending chain should follow after the ascending chain.
-- - The descending chain's entries should be added backwards and skip
--  the root.
-- - This way, if the mos is multi-period, the root of the next period's
--  ascending chain (which is the same as the current period's descend-
--  ing chain) won't be added twice.
-- - If the period is the last period, add the root as the equave.
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, prefix, notation)
-- If j is ever 1, then the mosdegree is the equave
-- This only happens if the current period is the last period
-- If the equave is 2/1, that's the octave
if j == 1 then
if rat.eq(input_mos.equave, 2) then
degree_name = degree_name .. " (octave)"
else
degree_name = degree_name .. " (equave)"
end
end
local row = { degree_name, note_name }
table.insert(rows, row)
end
end
return rows
end
 
-- Helper function; FOR FUTURE REWRITE
-- Creates the column for the note name
-- Decoupled degree and note name functions allow note names being omitted.
-- Decoupled degree and note name functions allow note names being omitted.
function p.preprocess_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length)
function p.preprocess_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length)
Line 236: Line 127:
end
end


-- Helper function; FOR FUTURE REWRITE
-- Helper function; creates the column for the degree name
-- Creates the column for the degree name
-- Decoupled degree and note name functions allow note names being omitted.
-- Decoupled degree and note name functions allow note names being omitted.
function p.preprocess_degrees(input_mos, asc_chain_length, des_chain_length, prefix, notation)
function p.preprocess_degrees(input_mos, asc_chain_length, des_chain_length, prefix, notation)
Line 444: Line 334:
local genchain_extend_up = genchain_extend[1] or genchain_extend_default
local genchain_extend_up = genchain_extend[1] or genchain_extend_default
local genchain_extend_dn = genchain_extend[2] or genchain_extend_default
local genchain_extend_dn = genchain_extend[2] or genchain_extend_default
-- Should a note names column be added?
local add_note_names = frame.args['Notation'] ~= "NONE"
-- Get notation: naturals (or nominals), sharp symbol, and flat symbol
-- Get notation: naturals (or nominals), sharp symbol, and flat symbol
Line 494: Line 387:


-- Get the degrees and note names
-- Get the degrees and note names
local degrees_and_note_names = p.preprocess_degrees_and_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length, mos_prefix, degree_notation)
local degrees    = p.preprocess_degrees  (input_mos, asc_chain_length, des_chain_length, mos_prefix, notation)
local note_names = p.preprocess_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length)
-- Get the step and cent values
-- Get the step and cent values
Line 503: Line 397:
table.insert(steps_and_cents, cells)
table.insert(steps_and_cents, cells)
end
end
-- Format the output as a table, starting with the header row
local result = '{| class="wikitable sortable"\n'
-- Pre-calculate the ets and step counts for each step ratio
-- Pre-calculate the ets and step counts for each step ratio
Line 517: Line 408:
end
end


-- Produce the headers; first row
-- Format the output as a table, starting with the header row
local result = '{| class="wikitable sortable"\n'
result = result .. '! rowspan="2" |Scale degree\n'
result = result .. '! rowspan="2" |Scale degree\n'
result = result .. '! rowspan="2" |On ' .. string.sub(note_symbols, 1, 1) .. "\n"
if add_note_names then
result = result .. '! rowspan="2" |On ' .. string.sub(note_symbols, 1, 1) .. "\n"
end
-- Add this once for every step ratio to be represented
-- Add this once for every step ratio to be represented
Line 555: Line 450:
-- Add each row, containing a degree, note name, step count, and cent value
-- Add each row, containing a degree, note name, step count, and cent value
for i = 1, #degrees_and_note_names do
for i = 1, #degrees do
-- Is the row for a nominal? (Nominals have no accidentals and are
-- Is the row for a nominal? (Nominals have no accidentals and are
Line 575: Line 470:
local is_period = cent_value % (steps_in_ets[1] / periods_per_equave) == 0
local is_period = cent_value % (steps_in_ets[1] / periods_per_equave) == 0
-- Add cells for degree and note name
-- Add cell for degree
-- Make any nominals that correspond to the period bold
-- Make any nominals that correspond to the period bold
if is_period and is_nominal then
if is_period and is_nominal then
result = result .. "| '''" .. degrees_and_note_names[i][1] .. "'''\n" -- Degree name
result = result .. "| '''" .. degrees[i] .. "'''\n"
else
else
result = result .. "| " .. degrees_and_note_names[i][1] .. "\n" -- Degree name
result = result .. "| " .. degrees[i] .. "\n"
end
-- Add cell for note name, if allowed
if add_note_names then
result = result .. "| " .. note_names[i] .. "\n"
end
end
result = result .. "| " .. degrees_and_note_names[i][2] .. "\n" -- Note name
-- Add cells for step size
-- Add cells for step size
for j = 1, #step_ratios do
for j = 1, #step_ratios do
result = result .. "| " .. steps_and_cents[j][i][1] .. "\n" -- Steps
result = result .. "| " .. steps_and_cents[j][i][1] .. "\n" -- Steps
result = result .. "| " .. steps_and_cents[j][i][2] .. "¢\n" -- Cents
result = result .. "| " .. steps_and_cents[j][i][2] .. "¢\n" -- Cents
end
end
end
end