Constant summary | |
---|---|
+edo-prime-octave-offsets+ | (loop for prime in +primes+ collect (round (log (/ prime (ji-pc-ratio prime)) 2))) |
+nominal->ratio-table+ | (alexandria.0.dev:alist-hash-table (loop for nom in +nominals+ for no-of-fifths from -1 collect (cons nom (ji-pc-ratio (monzo-to-ratio (list 0 no-of-fifths)))))) |
+nominals+ | '(f c g d a e b) |
+prime->comma-ratio-table+ | (alexandria.0.dev:alist-hash-table (list* (list* 3 (expt 2187/2048 -1)) (list* (list* 5 (expt 81/80 -1)) (list* (list* 7 (expt 64/63 -1)) (list* '(11 . 33/32) (list* (list* 13 (expt 27/26 -1)) (list* (list* 17 (expt 256/255 -1)) (list* '(19 . 513/512) (list* '(23 . 736/729) (list* '(29 . 145/144) (list (list* 31 (expt 1024/1023 -1))))))))))))) |
+primes+ | '(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61) |
+ratio->nominal-table+ | (flip-hash-table +nominal->ratio-table+) |
List of prime numbers from 2 to 61.
+edo-prime-octave-offsets+ | (loop for prime in +primes+ collect (round (log (/ prime (ji-pc-ratio prime)) 2))) | [Constant] |
List of octave offsets of prime frequency ratios, i.e., in which octave lies a prime frequency ratio compared to 1/1. For example, the first prime (2) is one octave and the third prime (5) is two octaves above 1.
Standard pitch nominals in order of fifth chain. These will be tuned Pythagorean in JI.
+nominal->ratio-table+ | (alexandria.0.dev:alist-hash-table (loop for nom in +nominals+ for no-of-fifths from -1 collect (cons nom (ji-pc-ratio (monzo-to-ratio (list 0 no-of-fifths)))))) | [Constant] |
Hashtable mapping pitch nominals (symbols like A, B, C...) to their corresponding Pythagorean frequency ratios.
Hashtable mapping Pythagorean frequency ratios for pitch nominals to their corresponding symbols (A, B, C...).
+prime->comma-ratio-table+ | (alexandria.0.dev:alist-hash-table (list* (list* 3 (expt 2187/2048 -1)) (list* (list* 5 (expt 81/80 -1)) (list* (list* 7 (expt 64/63 -1)) (list* '(11 . 33/32) (list* (list* 13 (expt 27/26 -1)) (list* (list* 17 (expt 256/255 -1)) (list* '(19 . 513/512) (list* '(23 . 736/729) (list* '(29 . 145/144) (list (list* 31 (expt 1024/1023 -1))))))))))))) | [Constant] |
A hashtable filled with function store-temperament and accessed by get-temperament-vals and get-temperament-generators.
Currently set global temperament (e.g., used by my snippet audition from within Emacs).
Hashtable mapping symbols representing accidentals to corresponding prime limit ratios and their combinations. Combinations are representing by their own symbol, so that for notating chords we only need a single accidental symbol per tone.
Notation: s and b are the Pythagorean sharp and flat accidentals K stands for prime limit 'c'omma (K as in the original Greek κόμμα, 'c' is already used for OMN attributes denoting cents) 5K means prime limit 5 comma up -5K means prime limit 5 comma down 1K is the natural accidental xx is used for combinations of the same symbol (two quasi multiplication signs read as power of frequency ratios) 5Kxx3 means triple prime limit 5 comma up x combines accidentals (quasi multiplication sign read as factor of frequency ratios) -5Kx-7K means a limit 5 and additionally a limit 7 comma down 5Kxx2x7K means two limit 5 commas and additionally a limit 7 comma up
Remember that these symbols do not distinguish between upper and lower case, case is just used for a (very little) bit of readability.
NOTE: Currently always only at most 2 prime limits are combined in a single accidental.
Source for the initial prime limit ratios: Nicholson, T. & Sabat, M. (2018) Fundamental Principles of Just Intonation and Microtonal Composition. p. 18
Map prime limit ratios to corresponding symbols representing accidentals. The inverse map of *accidental->ratio-table*
Turns the keys of the given hash `table' into values and vice versa
Return a ratio that corresponds to a monzo represented by a list of integers.
See also https://en.xen.wiki/w/Monzo
Return a monzo represented by a list of integers that corresponds to the fraction `frac'.
See also https://en.xen.wiki/w/Monzo
Transform the frequency ratio `frac' into the corresponding cent value.
Return a val (list of ints) given a subdivision of the octave (an int) and mappings for all prime limits as a list of temperament degrees *within an octave* (list of ints). The first mapping should be 0 (and not `edo').
Return an interval in a 1D temperament specified by its `val' that corresponds to the JI interval ratio `frac'. The resulting interval is specified as a factor (or exponent) for the single generator of the temperament. For example, if the generator is the smallest interval of an equal temperament, the returned degree specifies how many such intervals are needed to reach a pitch that corresponds to the given fraction. (If the generator is measured in cents, the returned degree is to be used as a factor for the measured, but if the generator is a frequency ratio, then the returned degree is to be used as an exponent.)
frac (rational): a JI interval for which we want to get a tempered interval
val (list of ints): the val that specifies how JI pitches of prime limits are mapped to the temperament. See also https://en.xen.wiki/w/Keenan%27s_explanation_of_vals and https://en.xen.wiki/w/Val
We can specify arbitrary equal temperaments (not just EDOs) by using their smallest step as a generator. The val then contains the ordered number of theses steps to the temperament intervals that should serve as the prime frequency ratios 2, 3, 5... up to the desired prime limit. For 12-EDO, the smallest step is 100 cent. 12 such steps correspond to the frequency ratio 2 (the octave), 19 such steps to the frequency ratios 3 (the octave plus a fifth), 28 such steps correspond to the frequency ratio 5 and so on.
(setf 12-EDO-val '(12 19 28))
With this 5-limit val, we can now obtain the 12-EDO intervals for arbitrary 5-limit JI intervals specified by ratios, for example the minor third (6/5) in 12-EDO is 3 steps.
(ratio-to-1D-temperament-degree 6/5 12-EDO-val)
=> 3
Remember that 12-EDO is a meantone temperament (https://en.wikipedia.org/wiki/Meantone_temperament), so the syntonic comma (81/80) is tempered out: the size of that interval is 0.
(ratio-to-1D-temperament-degree 81/80 12-EDO-val)
=> 0
As a consequence, intervals that differ only by this comma have the same size in this temperament. For example, the Pythagorean minor third (32/27) has also the size of 3 in 12-EDO.
(ratio-to-1D-temperament-degree (* 6/5 80/81) 12-EDO-val)
=> 3
The 7-limit val for the temperament 22-EDO (https://en.xen.wiki/w/22edo) is as follows. You can collect the data for writing such vals yourself simply by collecting the temperament interval sizes for prime frequency ratios up to the relevant limit (2, 3, 5, and 7 in this case), e.g., from a table for that temperament listing all its intervals the the approximated JI ratios (e.g., see https://en.xen.wiki/w/22edo#Superpyth.2FPorcupine_Notation). For 22-EDO, the ratio 2 corresponds to 22 steps, the ratio 3 to 13 (fifth) plus 22 (1 octave) steps and so forth.
(setf 22-EDO-val (list 22 (+ 13 22) (+ 7 (* 2 22)) (+ 18 (* 2 22))))
With this 7-limit val for 22-EDO, we can now get the 22-EDO intervals for arbitrary 7-limit JI ratios. Here is the subminor third (7/6). You can confirm the resulting value with the above-mentioned table for this temperament.
(ratio-to-1D-temperament-degree 7/6 22-EDO-val)
=> 5
Return the pitch of an interval (measured in cents) that corresponds to the JI interval ratio `frac' in an equal temperament (not just EDOs) defined by the given `val' and the generator for a step in that equal temperament (also measured in cents).
Return an interval in an arbitrary regular temperament specified by a list of its `vals' that corresponds to the JI interval ratio `frac'. The resulting interval is specified as a list of factors for the generators of the temperament measured in cent (or as exponents for generators that are frequency ratios).
frac (rational): a JI interval for which we want to get a tempered interval
vals (list of list of ints): the list of vals that specify how the temperament how JI pitches are mapped to the temperament. See also https://en.xen.wiki/w/Keenan%27s_explanation_of_vals and https://en.xen.wiki/w/Val
We can specify arbitrary regular temperaments by their generators. The vals then specify how JI pitches are mapped into this temperament. This is done by stating how often each generator must be repeated to reach a tempered tone that should serve as the prime frequency ratios 2, 3, 5... up to the desired prime limit.
Meantone temperament is specified by two generators, one specifying the size of the octave and one that of the fifth (the second generator can also be an octave plus a fifth, but then the vals are slightly different). As meantone has two generators, we must specify two vals, one for each of them. The first value in each val states how often its generator must be repeated to reach the frequency ratio 2, i.e., the octave. For reaching the octave we need 1 octave (generator 1) and 0 fifths (generator 2), so the first value in the first val is 1 and the first in the second val is 0. The second value in each val states how often its generator must be repeated to reach the frequency ratio 3, i.e., the octave plus a fifth. Obviously, we need one octave (second value of val 1) and one fifth (second value of val 2). The third (and for 5-limit meantone the last) val values state how to reach the prime frequency ratio 5 (two octaves and a major third). We can reach this interval by stacking 5 fifths and no additional octave is needed. So, the third value for the val 1 is 0 and for val 2 is 4. So, the vals for meantone are as follows.
(setf 5-limit-meantone-vals '((1 1 0) (0 1 4)))
With this 5-limit val, we can now obtain the meantone intervals measured in repetitions of generators for arbitrary 5-limit JI intervals specified by ratios. For example, to reach a fourth (ratio 4/3), we need to go one octave up and one fifth down. So, the first generator is repeated once upwards, and the second once downwards (specified by a negative count).
(ratio-to-regular-temperament-degrees 4/3 5-limit-meantone-vals) => (1 -1)
A minor third (6/5) is reached by 2 octaves up and 3 fifths down.
(ratio-to-regular-temperament-degrees 6/5 5-limit-meantone-vals)
=> (2 -3)
Translate given temperament `degrees' into a corresponding JI ratio. `generator-ratios' is the list of primes that correspond to the generators for which the given degrees would be fitting. Does not temper out any commas and gives preference to ratios with a lower limit (e.g., Pythagorean third instead of just third).
[main function in background] Translate a JI interval (ratio) into the corresponding interval measured in cents of a regular temperament. The temperament is specified by its `vals' and `generators'.
frac (rational): a JI interval for which we want to get a tempered interval
vals (list of list of ints): the list of vals that specify how the temperament how JI pitches are mapped to the temperament. See also https://en.xen.wiki/w/Keenan%27s_explanation_of_vals and https://en.xen.wiki/w/Val
generators (list of numbers): the list of generators that specify the temperament.
The order of vals and generators must match (i.e. the val of a certain generator must be at the same position).
See the documentation of `deftemperament' and also `ratio-to-regular-temperament-degrees' for more information.
Store a temperament with the given `vals' and `generators' under the key the `name' in `*temperaments*'.
Return list of names (symbols) of all temperaments so far defined with `deftemperament'.
You can jump to the definition of a temperament, by jumping to the definition of a function/method with the name of a temperament.
Return vals of a temperament with `name' defined with `deftemperament'.
Return generators of a temperament with `name' defined with `deftemperament'.
Return list of degrees of the temperament specified by `generators'.
generators (list of rationals or list of floats): List of temperament generators. If rationals, generators are assumed to be frequency ratios, otherwise they are assumed to be measured in cent.
ns (list of its): Specifies how often the generators should be repeated. Each n specifies the number the corresponding generator (at the same position) is repeated.
mode (either :up-and-down or :up): Whether generators are repeated upwards and downwards or only upwards.
* Examples
Using just the octave (2) as a generator, repeating that generator up and down until in total 7 frequency ratios are generated.
(temperament-degrees '(2) '(7))
=> (1/8 1/4 1/2 1 2 4 8)
Generating a single octave of 12-EDO by repeating its generator (100.0 cent) to result in 12 tones.
(temperament-degrees '(100.0) '(12))
=> (-600.0 -500.0 -400.0 -300.0 -200.0 -100.0 0.0 100.0 200.0 300.0 400.0 500.0)
Collect the ratios of a 5-limit JI lattice without the octave, so that there is a sequence of 12 tones in the dimension of fifths and 3 tones in the dimension of thirds.
(temperament-degrees '(3/2 5/4) '(12 3))
Repeating generators only upwards.
(temperament-degrees '(100.0) '(12) :mode :up)
=> (0.0 100.0 200.0 300.0 400.0 500.0 600.0 700.0 800.0 900.0 1000.0 1100.0)
[For temperament-pcs-infos arg sort-ratios] Given two ratios, return T if the first ratio has a lower prime limit.
[For temperament-pcs-infos arg sort-ratios] Given two ratios, return T if the first ratio needs fewer accidentals for notating it.
temperament-pcs-infos | temperament generator-ns limit-ratios ratio-ns fn &key (ratios-comparison #'has-fewer-accidentals?) | [Function] |
Return nested list where each sublist starts with a temperament degree measured in cents (as returned by `temperament-degrees') and the remaining values of each sublist are results of the function `fn' given rationals that are tempered to this degree in the given temperament.
temperament (symbol): A temperament defined by `deftemperament'.
generator-ns (list of ints): Specifies how often each generator (implicitly specified by the temperament symbol) should be repeated. Each n specifies the number the corresponding generator (at the same position) is repeated.
limit-ratios (list of rationals): Specifies generators for creating a JI tuning that is then matched to the temperament.
ratio-ns (list of ints): Specifies how often the corresponding generator (at the same position) is repeated.
fn (binary function): Function for generating further information on temperament tones. The function expects a JI rational and the corresponding temperament degree in cents. ;; - sorted-degrees? (Boolean): if T, the result is sorted in increasing order of degrees.
ratios-comparison (binary function): Function comparing two ratios that is used for sorting ratios per degree. * Examples
TODO:
Collect list of (relatively simple) note names for temperament degrees
Compute tuning errors as difference between degrees and ratios turned into cents.
For the given `accidental' symbol, add `n' accidentals that are powers of the corresponding frequency ratios. If `n' is two, accidental doubles are added, if it is tree, triple are added etc. These accidentals are notated with a double star for expressing the power relation. E.g., sxx3 is a triple sharp.
Return T if ratio1 or ratio2 share the same prime limit (of if either is 1).
Returns a new string in which all the occurrences of the part is replaced with replacement.
Automatically define for all accidentals (keys of `*accidental->ratio-table*') corresponding OMN text attributes.
Pairwise combine all accidentals into product accidentals (resulting in a huge accidental number overall).
Each spec is a pair (accidentals . n), where accidentals is a list of accidental symbols, and n is the number of power accidentals to add to them.
Each spec is a pair (accidentals . n), where accidentals is a list of accidental symbols, and n is the number of power accidentals to add to them.
Can be used, e.g., for adding some custom interpretation of the OMN builtin accidentals like + and - or (for adding higher prime limits?).
[Aux for ratio-to-ji-pc-symbols etc] Return list of accidental symbols list beyond limit 5 that corresponds to ratio.
Return PC symbol list that corresponds to ratio (i.e. octaves are ignored).
Return OMN pitch plus accidental attribute that corresponds to ratio (i.e. octaves are ignored).
Return a plist that contains the components of `pitch' (an OMN pitch symbol), each component as a string.
(parse-OMN-pitch 'c4)
=> (:NOMINAL C :STANDARD-ACCIDENTAL NIL :OCTAVE 4 :MICROTONE-ACCIDENTAL ||)
(parse-OMN-pitch 'cs4+)
=> (:NOMINAL C :STANDARD-ACCIDENTAL S :OCTAVE 4 :MICROTONE-ACCIDENTAL +)
Return a flat list of tuning values for the given `sequence'. The tuning values are floats (1.0 is 100 cents).
sequence (list, possibly nested): OMN sequence with custom JI accidentals (as defined in *accidental->ratio-table*) as OMN attributes.