Module:Chord consistency

Revision as of 13:01, 14 December 2024 by Dummy index (talk | contribs)
Module documentation[view] [edit] [history] [purge]

This module provides some functions which enumerate consistent equal divisions relative to some chord.

Functions

additively_consistent_int
Slightly differ version of Module:Limits.additively_consistent. That function must be supplied with octave-reduced intervals.
consistent_edos
Output list of consistent edos relative to given chord (Lua table of harmonics) up to 72edo. Different equaves, minimum consistency distance, maximum length of list are specifiable.
noinfobox_chord (obsolete)
A piece of code for Module: Infobox chord.

Format of edos list

Output of consistent_edos are links to individual edos with each trailing several asterisks. These indicate consistency distace d briefly, none as 1 ≤ d < 2; * as 2 ≤ d < 4; ** as 4 ≤ d < 8; …


local rat = require('Module:Rational')
local utils = require("Module:Utils")
local ET = require('Module:ET')
local consistency = require('Module:Limits')
local p = {}

function p.noinfobox_chord(frame)
	local page_name = frame:preprocess("{{PAGENAME}}")
	
	local debug_data = ""
	local infobox_data = {}
	local cats = ""

	--if utils.value_provided(frame.args["Harmonics"]) then
		local harmonics = {}
		for hs in string.gmatch(frame.args["Harmonics"], "[^:]+") do
			h = tonumber(hs)  -- TODO: support rational entries?
			assert(h > 0, "invalid harmonic")
			table.insert(harmonics, h)
		end

		-- reduce harmonics to simplest terms, in case the user accidentally failed to reduce them
		local gcd = harmonics[1]
		for i, h in ipairs(harmonics) do
			gcd = utils._gcd(gcd, h)
			if gcd == 1 then break end
		end
		if gcd > 1 then
			for i, h in ipairs(harmonics) do
				harmonics[i] = harmonics[i] / gcd
			end
		end

		local root = harmonics[1]

		local root_interval_links = {}
		local step_interval_links = {}
		local all_interval = {}
		for i, h in ipairs(harmonics) do
			-- compute ratio of this harmonic relative to the root
			local gcd = utils._gcd(h, root)
			local numer = h / gcd
			local denom = root / gcd
			table.insert(root_interval_links, "[[" .. numer .. "/" .. denom .. "]]")

			-- compute ratio of this harmonic relative to the previous
			if i > 1 then
				local prev = harmonics[i-1]
				local step_gcd = utils._gcd(h, prev)
				local step_numer = h / step_gcd
				local step_denom = prev / step_gcd
				table.insert(step_interval_links, "[[" .. step_numer .. "/" .. step_denom .. "]]")
			end
			
			-- compute all ratio
			for j, g in ipairs(harmonics) do
				if j > i then
					local step_gcd = utils._gcd(g, h)
					local step_numer = g / step_gcd
					local step_denom = h / step_gcd
					local a = rat.new(g, h)
					all_interval[rat.as_ratio(a)] = a
				end
			end
		--end

		local vals = {}
		for i = 1, 50 do
			local et = ET.parse('' .. i .. 'edo')
			local consistent = consistency.additively_consistent(et, all_interval, false, previous)
			if consistent then
				table.insert(vals, "[[" .. i .. "edo]]")
			end
		end
	end
	cat = table.concat(vals, ", ")

	return cat
end

return p