|
|
| Line 10: |
Line 10: |
| function p.preprocess_degrees_and_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length) | | function p.preprocess_degrees_and_note_names(input_mos, udp, note_symbols, sharp_symbol, flat_symbol, asc_chain_length, des_chain_length) |
| -- Test parameters | | -- Test parameters |
| | --[[ |
| local input_mos = input_mos or mos.new(5, 2, 2) | | local input_mos = input_mos or mos.new(5, 2, 2) |
| local udp = udp or { 3, 3 } | | local udp = udp or { 3, 3 } |
| Line 17: |
Line 18: |
| local asc_chain_length = input_mos.nL * 2 + input_mos.ns | | local asc_chain_length = input_mos.nL * 2 + input_mos.ns |
| local des_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 | | -- Get the number of mossteps per period and equave |
| Line 102: |
Line 104: |
| function p.preprocess_steps_and_cents(input_mos, step_ratio, asc_chain_length, des_chain_length) | | function p.preprocess_steps_and_cents(input_mos, step_ratio, asc_chain_length, des_chain_length) |
| -- Test parameters | | -- Test parameters |
| | --[[ |
| local input_mos = input_mos or mos.new(5, 2, 2) | | local input_mos = input_mos or mos.new(5, 2, 2) |
| local step_ratio = { 2, 1 } | | local step_ratio = { 2, 1 } |
| local asc_chain_length = input_mos.nL * 2 + input_mos.ns | | local asc_chain_length = input_mos.nL * 2 + input_mos.ns |
| local des_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 | | -- Get the number of mossteps per period and equave |
| Line 195: |
Line 199: |
| end | | end |
| local udp = mosnot.parse_udp(frame.args['UDP']) or udp_default | | local udp = mosnot.parse_udp(frame.args['UDP']) or udp_default |
| local generators_up = udp[1]
| |
| local generators_down = udp[2]
| |
| | | |
| -- Get note symbols | | -- Get note symbols |
| Line 243: |
Line 245: |
| local scale_sig = mos.as_string(input_mos) | | local scale_sig = mos.as_string(input_mos) |
| ]]-- | | ]]-- |
|
| | |
| -- How long are the initial genchain lengths? (These correspond to the UDP) | | -- Calculate the chain lengths |
| local gens_up_per_period = udp[1] / periods_per_equave
| | -- Ascending and descending chain lengths are hardcoded to be both the same |
| local gens_dn_per_period = udp[2] / periods_per_equave
| | -- and to be 2nx + ny generators (for a mos nxL nys) |
|
| |
| -- How long should the genchains be?
| |
| -- The length should be such that: | |
| -- - Every non-root interval is shown in its small, large, augmented, and
| |
| -- diminished size.
| |
| -- - The root and equave are shown in their perfect sizes, followed by their
| |
| -- augmented and diminished sizes respectively. | |
| -- - Any non-root non-equave periods are shown in their perfect, augmented,
| |
| -- and diminished sizes.
| |
| -- To do this requires going up 2x+2y generators, and down the same amount.
| |
| -- Going up x+y gens from the root reaches every scale degree's large size,
| |
| -- plus the augmented root, then going up x+y-1 more gens reaches each
| |
| -- augmented degree. Same is true for going down to get minor/dim degrees.
| |
| local asc_chain_length = input_mos.nL * 2 + input_mos.ns | | local asc_chain_length = input_mos.nL * 2 + input_mos.ns |
| local des_chain_length = input_mos.nL * 2 + input_mos.ns | | local des_chain_length = input_mos.nL * 2 + input_mos.ns |
| | |
| | -- 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) |
| | | |
| -- Get the genchains | | -- Get the step and cent values |
| local asc_genchain = mosnot.mos_nomacc_chain(input_mos, gens_up_per_period, asc_chain_length, true) | | local steps_and_cents = p.preprocess_steps_and_cents(input_mos, step_ratio, asc_chain_length, des_chain_length) |
| 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)
| |
| | | |
| -- Format the output as a table, starting with the header row | | -- Format the output as a table, starting with the header row |
| Line 277: |
Line 264: |
| local steps_in_et = input_mos.nL * step_ratio[1] + input_mos.ns * step_ratio[2] | | 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) | | local et_for_mos = et.new(steps_in_et, input_mos.equave) |
| result = result .. "! Scale degree !! Steps !! Cents !! Note name on ".. string.sub(note_symbols, 1, 1) .. "\n" | | result = result .. "! Scale degree !! Note name on " .. string.sub(note_symbols, 1, 1) .. " Steps !! Cents\n" |
| | | |
| -- How many esteps per period? Per bright/dark gen?
| | -- Add each row, containing a degree, note name, step count, and cent value |
| local esteps_per_period = steps_in_et / periods_per_equave
| | for i = 1, #degrees_and_note_names do |
| 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
| |
|
| |
| -- Add the rows | |
| local step_ratio_gcd = rat.gcd(step_ratio[1], step_ratio[2]) -- GCD of the sizes of L and s, in case L:s isn't simplified
| |
| local cents_per_equave = rat.cents(input_mos.equave) -- Equave in cents
| |
|
| |
| -- For each period, add a row containing a scale degree, step count, cent
| |
| -- value, and note name from the ascending genchain, then do the same with
| |
| -- the descending genchain, in reverse and skipping the perfect root and
| |
| -- raising any other root by one period. Repeat for all other periods.
| |
| -- For the last period, add the perfect root as the perfect equave.
| |
| -- TODO: Formatting (rounding cent values, row coloring, etc)
| |
| for i = 1, periods_per_equave do | |
| -- Add degrees from ascending chain
| |
| for j = 1, asc_chain_length do
| |
| local note = asc_genchain[i][j]
| |
| local mossteps = note['mossteps']
| |
| local chromas = note['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, chroma_plus_symbol)
| |
|
| |
| -- Find the degree name
| |
| -- If the degree is the 0-mosdegree, say it's the unison
| |
| local degree_name = mosnot.mosstep_and_quality_to_degree(mossteps, quality)
| |
| if mossteps == 0 then
| |
| degree_name = degree_name .. " (unison)"
| |
| end
| |
|
| |
| -- 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
| |
| result = result .. "|-\n"
| |
| result = result .. "| " .. degree_name .. "\n"
| |
| result = result .. "| " .. estep_count .. "\n"
| |
| result = result .. "| " .. cent_value .. "¢\n"
| |
| result = result .. "| " .. note_name .. "\n"
| |
| 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 | | -- Add the row; each row is its own array |
| for j = des_chain_length, stop_value, -1 do
| | result = result .. "|-\n" |
| local note = des_genchain[i][j]
| | result = result .. "| " .. degrees_and_note_names[i][1] .. "\n" -- Degree name |
| local mossteps = note['mossteps']
| | result = result .. "| " .. degrees_and_note_names[i][2] .. "\n" -- Note name |
| local chromas = note['chromas']
| | result = result .. "| " .. steps_and_cents[i][1] .. "\n" -- Steps |
| local quality = des_degrees[i][j]['quality']
| | result = result .. "| " .. steps_and_cents[i][2] .. "¢\n" -- Cents |
|
| |
| -- 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, chroma_minus_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)
| |
|
| |
| -- 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)
| |
|
| |
| -- If the mosstep is for the equave, add that name
| |
| if mossteps == mossteps_per_equave then
| |
| degree_name = degree_name .. " (equave)"
| |
| end
| |
|
| |
| -- If the note corresponds to the root, say it's the equave instead
| |
| if cent_value == 0 then
| |
| cent_value = cents_per_equave
| |
| estep_count = steps_in_et
| |
| note_name = string.sub(note_symbols, 1, 1) .. " (one equave up)"
| |
| end
| |
|
| |
| -- Add the row
| |
| result = result .. "|-\n"
| |
| result = result .. "| " .. degree_name .. "\n"
| |
| result = result .. "| " .. estep_count .. "\n"
| |
| result = result .. "| " .. cent_value .. "¢\n"
| |
| result = result .. "| " .. note_name .. "\n"
| |
| end
| |
| end | | end |
| | | |