Module:ED intro: Difference between revisions
Work-in-progress |
Still work-in-progress; includes todo on what to bugfix |
||
| Line 1: | Line 1: | ||
local ord = require('Module:Ordinal') | local ord = require('Module:Ordinal') | ||
local utils = require('Module:Utils') | local utils = require('Module:Utils') | ||
local rat = require('Module:Rational') | |||
local p = {} | local p = {} | ||
-- TODO: | |||
-- - Enforce ED types: edo, edt, edf, edh, edr, edc for octave, tritave/twelfth, | |||
-- fifth, arbitrary harmonic h, arbitrary ratio r, and arbitrary cent value c. | |||
-- Note that EDs of named constants, like pi, are currently not included, as | |||
-- they probably need their own typing (ednc) separate from edc. | |||
-- - Bugfix edr not reporting the correct equave | |||
function p.parse_ed(unparsed) | function p.parse_ed(unparsed) | ||
local unparsed = unparsed or " | local unparsed = unparsed or "12edo" | ||
-- If the unparsed ed is only a numeric value, default to edo | -- If the unparsed ed is only a numeric value, default to edo | ||
| Line 12: | Line 20: | ||
-- Parse | -- Parse | ||
local steps | local steps, equave = unparsed:match('^(%d+)[Ee][Dd](.+)$') | ||
steps = tonumber(steps) | |||
-- If the equave is text, then the equave is: | -- If the equave is text, then the equave is: | ||
| Line 18: | Line 27: | ||
-- t: tritave or twelfth, 3/1 (3rd harmonic) | -- t: tritave or twelfth, 3/1 (3rd harmonic) | ||
-- f: fifth, 3/2 | -- f: fifth, 3/2 | ||
local ed_type = "" | |||
local ratio = "n/a" | |||
local cents = 0 | |||
if equave == "o" or equave == "O" or equave == "2" then | |||
if equave == "o" or equave == "O" then | |||
equave = "2" | equave = "2" | ||
elseif equave == "t" or equave == "T" then | ratio = "2/1" | ||
cents = 1200 | |||
ed_type = "edo" | |||
elseif equave == "t" or equave == "T" or equave == "3" then | |||
equave = "3" | equave = "3" | ||
elseif equave == "f" or equave == "F" then | ratio = "3/1" | ||
cents = math.log(3) * 1200 / math.log(2) | |||
ed_type = "edt" | |||
elseif equave == "f" or equave == "F" or equave == "3/2" then | |||
equave = "3/2" | equave = "3/2" | ||
ratio = "3/2" | |||
equave = | cents = math.log(3/2) * 1200 / math.log(2) | ||
ed_type = "edf" | |||
end | |||
-- For equaves not 2/1, 3/1, or 3/2 | |||
if ed_type == "" then | |||
-- If the equave is a number or ratio, convert it to cents | |||
-- If the equave is already a cent value, extract it | |||
local is_cents = string.match(equave, '^(.+)c') ~= nil | |||
local is_numeric = tonumber(equave) ~= nil | |||
local is_ratio = string.match(equave, '^%d+/%d+$') ~= nil | |||
if is_cents then | |||
cents = tonumber(equave:match('^(.+)c')) | |||
ed_type = "edc" | |||
elseif is_numeric then | |||
cents = math.log(tonumber(equave)) * 1200 / math.log(2) | |||
-- Classify ed type as either ed of a constant (if not a whole number) | |||
-- or ed of a harmonic (if it's a whole number); if it is a harmonic, | |||
-- write it as a ratio (h/1) | |||
if math.floor(tonumber(equave)) ~= tonumber(equave) then | |||
ed_type = "edc" | |||
else | |||
ed_type = "edh" | |||
ratio = equave .. "/1" | |||
end | |||
elseif is_ratio then | |||
local ratio = rat.parse(equave) | |||
cents = rat.cents(ratio) | |||
equave = rat.as_ratio(ratio) -- Ensures ratio is simplified | |||
ratio = equave | |||
ed_type = "edr" | |||
end | |||
end | end | ||
return { ['steps'] = steps, [' | return { ['cents'] = cents, ['equave'] = equave, ['steps'] = steps, ['ratio'] = ratio, ['type'] = ed_type } | ||
end | end | ||
function p.ed_intro(ed) | function p.ed_intro(ed) | ||
local ed = ed or "12ed19/13" | |||
local parsed_ed = p.parse_ed(ed) | |||
local ed_type = parsed_ed['type'] | |||
-- Intro formats for each possible case | -- Intro formats for each possible case | ||
-- - Common abbrevs: edo, edt, edf | -- - Common abbrevs: edo, edt, edf; these have specially written intros | ||
-- - General harmonic: edh (h-th harmonic) | -- - General harmonic: edh (h-th harmonic) | ||
-- - Arbitrary JI ratio: | -- - Arbitrary JI ratio: edr (ratio of p/q) | ||
-- - Arbitrary constant: edc | -- - Arbitrary constant: edc | ||
-- - Equal-step tunings: 1edo, 1edt, 1edf, 1edh, 1edp/q, 1edc | -- - Equal-step tunings: 1edo, 1edt, 1edf, 1edh, 1edp/q, 1edc | ||
local intro_text = "" | local intro_text = "" | ||
if is_est then | if is_est then | ||
if | if ed_type == "edo" then | ||
intro_text = "'''1 equal division of the octave''' (abbreviated '''1edo''' or '''1ed2'''), also called '''1-tone equal temperament''' ('''1tet'''), or '''1 equal temperament''' ('''1et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] where adjacent pitches are one [[octave]], or exactly/about s [[¢]], from each other. | intro_text = "'''1 equal division of the octave''' (abbreviated '''1edo''' or '''1ed2'''), also called '''1-tone equal temperament''' ('''1tet'''), or '''1 equal temperament''' ('''1et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] where adjacent pitches are one [[octave]], or exactly/about ''s'' [[¢]], from each other." | ||
elseif | elseif ed_type == "edt" then | ||
intro_text = "'''1 equal division of the tritave''' (abbreviated '''1edt''' or '''1ed3''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one tritave ([[3/1]]), or exactly/about s [[¢]], apart from each other. | intro_text = "'''1 equal division of the tritave''' (abbreviated '''1edt''' or '''1ed3''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one tritave ([[3/1]]), or exactly/about ''s'' [[¢]], apart from each other." | ||
elseif | elseif ed_type == "edf" then | ||
intro_text = "'''1 equal division of the fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one perfect fifth ([[3/2]]), or exactly/about s [[¢]], apart from each other. | intro_text = "'''1 equal division of the fifth''' (abbreviated '''1edf''' or '''1ed3/2''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one perfect fifth ([[3/2]]), or exactly/about ''s'' [[¢]], apart from each other." | ||
elseif | elseif ed_type == "edh" then | ||
intro_text = "'''1 equal division of the '' | intro_text = "'''1 equal division of the ''hth'' harmonic''' (abbreviated '''1ed''h''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''h''/1]], or exactly/about ''s'' [[¢]], apart from each other." | ||
elseif | elseif ed_type == "edr" then | ||
intro_text = "'''1 equal division of ''p''/''q''''' (abbreviated '''1ed''p''/''q''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''p''/''q'']], or exactly/about s [[¢]], apart from each other. | intro_text = "'''1 equal division of ''p''/''q''''' (abbreviated '''1ed''p''/''q''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are one interval of [[''p''/''q'']], or exactly/about ''s'' [[¢]], apart from each other." | ||
elseif | elseif ed_type == "edc" then | ||
intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are s [[¢]], apart from each other. | intro_text = "'''1 equal division of ''c''¢''' (abbreviated '''1ed''c''''') is the [[non-octave]] [[tuning system]] where adjacent pitches are ''s'' [[¢]], apart from each other." | ||
end | end | ||
else | else | ||
if | if ed_type == "edo" then | ||
intro_text = "'''''k'' equal divisions of the octave''' (abbreviated '''''k''edo''' or '''''k''ed2'''), also called '''''k''-tone equal temperament''' ('''''k''tet'''), or '''''k'' equal temperament''' ('''''k''et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that divides the [[octave]] into ''k'' [[equal]] parts of exactly/about s [[¢]] each. Each step of ''k''edo represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the '' | intro_text = "'''''k'' equal divisions of the octave''' (abbreviated '''''k''edo''' or '''''k''ed2'''), also called '''''k''-tone equal temperament''' ('''''k''tet'''), or '''''k'' equal temperament''' ('''''k''et''') when viewed under a [[regular temperament]] perspective, is the [[tuning system]] that divides the [[octave]] into ''k'' [[equal]] parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edo represents a [[frequency ratio]] of 2<sup>1/''k''</sup>, or the ''kth'' root of 2." | ||
elseif | elseif ed_type == "edt" then | ||
intro_text = "'''''k'' equal divisions of the tritave''' (abbreviated '''''k''edt''' or '''''k''ed3''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/1]] – also called the [[tritave]] or perfect twelfth – into ''k'' equal parts of exactly/about s [[¢]] each. Each step of ''k''edt represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the '' | intro_text = "'''''k'' equal divisions of the tritave''' (abbreviated '''''k''edt''' or '''''k''ed3''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/1]] – also called the [[tritave]] or perfect twelfth – into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edt represents a [[frequency ratio]] of 3<sup>1/''k''</sup>, or the ''kth'' root of 3." | ||
elseif | elseif ed_type == "edf" then | ||
intro_text = "'''''k'' equal divisions of the fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/2]], or perfect fifth, into ''k'' equal parts of exactly/about s [[¢]] each. Each step of ''k''edf represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the '' | intro_text = "'''''k'' equal divisions of the fifth''' (abbreviated '''''k''edf''' or '''''k''ed3/2''') is the [[non-octave]] [[tuning system]] that divides the interval [[3/2]], or perfect fifth, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''edf represents a [[frequency ratio]] of (3/2)<sup>1/''k''</sup>, or the ''kth'' root of 3/2." | ||
elseif | elseif ed_type == "edh" then | ||
intro_text = "'''''k'' equal divisions of the '' | intro_text = "'''''k'' equal divisions of the ''hth'' harmonic''' (abbreviated '''''k''ed''h''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''h''/1]], or the ''hth'' harmonic, into ''k'' equal parts of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''h'' represents a [[frequency ratio]] of ''h''<sup>1/''k''</sup>, or the ''kth'' root of ''h''." | ||
elseif | elseif ed_type == "edr" then | ||
intro_text = "'''''k'' equal divisions of ''p''/''q''''' (abbreviated '''''k''ed''p''/''q''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''p''/''q'']] into ''k'' [[equal]] pieces of exactly/about s [[¢]] each. Each step of ''k''ed''p''/''q'' represents the [[frequency ratio]] of (''p''/''q'')<sup>1/''k''</sup>, or the '' | intro_text = "'''''k'' equal divisions of ''p''/''q''''' (abbreviated '''''k''ed''p''/''q''''') is the [[non-octave]] [[tuning system]] that divides the interval [[''p''/''q'']] into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each. Each step of ''k''ed''p''/''q'' represents the [[frequency ratio]] of (''p''/''q'')<sup>1/''k''</sup>, or the ''kth'' root of ''p''/''q''." | ||
elseif | elseif ed_type == "edc" then | ||
intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''c''' or '''''k''ed''c''¢''') is the [[non-octave]] [[tuning system]] that divides interval of | intro_text = "'''''k'' equal divisions of ''c''¢''' (abbreviated '''''k''ed''c''c''' or '''''k''ed''c''¢''') is the [[non-octave]] [[tuning system]] that divides interval of ''c''¢ is divided into ''k'' [[equal]] pieces of exactly/about ''s'' [[¢]] each." | ||
end | end | ||
end | end | ||
-- Produce a map of text to replace | |||
-- - ''k'': number of steps in ed | |||
-- - ''s'': size of a step | |||
-- - ''p''/''q'': equave as a ratio | |||
-- - ''h'': equave as a harmonic | |||
-- - ''c'': equave as a cent value | |||
-- - ''hth'': harmonic as an ordinal | |||
-- - ''kth'': step count as an ordinal | |||
local step_size = parsed_ed['cents'] / parsed_ed['steps'] | |||
local text_replace_map = { | |||
["''k''"] = parsed_ed['steps'], | |||
["''s''"] = utils._round(step_size, 3), | |||
["''c''"] = utils._round(parsed_ed['cents'], 3), | |||
["''p''/''q''"] = parsed_ed['ratio'], | |||
["''h''"] = parsed_ed['equave'], | |||
["''hth''"] = ord._ordinal(parsed_ed['equave']), | |||
["''kth''"] = ord._ordinal(parsed_ed['steps']), | |||
["exactly/about"] = (utils._round(step_size, 3) == step_size and "exactly" or "about") | |||
} | |||
for key, value in pairs(text_replace_map) do | |||
intro_text = string.gsub(intro_text, key, value) | |||
end | |||
return intro_text | |||
end | end | ||
return p | return p | ||