In the last few months I've become a big fan of Just Intonation. One tedious aspect of this is that you end up fondling ratios a lot. The math gets boring after a while, though I do believe you should be able to do the math on your own to get a feel for what it is you're doing.
Having said that, I decided I needed some help
because I got sick of reducing multiplied ratios.
I've written a quick
Python module,
ratio.py
, which handles a lot
of the tedium. In particular, building up JI tetrachords and scales
based on justly intuned chords or by katapyknosis is pretty simple for
me now.
Here's an example interactive Python session of me diddling with the generation of a subminor scale.
Python 1.5.1 (#1, Jul 9 1998, 17:44:38) [GCC 2.7.2.3] on sunos5 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> from ratio import * >>> s = Ratio(1, 1).chord_of('subminor-7') >>> s [<1:1>, <7:6>, <3:2>, <11:6>] >>> s.append(Ratio(4, 3)) >>> s.sort() >>> s [<1:1>, <7:6>, <4:3>, <3:2>, <11:6>] >>> s = s + Ratio(3, 2).chord_of('subminor') >>> s [<1:1>, <7:6>, <4:3>, <3:2>, <11:6>, <3:2>, <7:4>, <9:8>] >>> s.sort() >>> s [<1:1>, <9:8>, <7:6>, <4:3>, <3:2>, <3:2>, <7:4>, <11:6>] >>> del s[4] >>> s [<1:1>, <9:8>, <7:6>, <4:3>, <3:2>, <7:4>, <11:6>] >>> s.append(Ratio(2, 1)) >>> s [<1:1>, <9:8>, <7:6>, <4:3>, <3:2>, <7:4>, <11:6>, <2:1>] >>> gamut2intervals(s) [<9:8>, <28:27>, <8:7>, <9:8>, <7:6>, <22:21>, <12:11>] >>> ratiotable(s) 1:1 | 1:1 9:8 7:6 4:3 3:2 7:4 11:6 2:1 9:8 | 8:9 1:1 28:27 32:27 4:3 14:9 44:27 16:9 7:6 | 6:7 27:28 1:1 8:7 9:7 3:2 11:7 12:7 4:3 | 3:4 27:32 7:8 1:1 9:8 21:16 11:8 3:2 3:2 | 2:3 3:4 7:9 8:9 1:1 7:6 11:9 4:3 7:4 | 4:7 9:14 2:3 16:21 6:7 1:1 22:21 8:7 11:6 | 6:11 27:44 7:11 8:11 9:11 21:22 1:1 12:11 2:1 | 1:2 9:16 7:12 2:3 3:4 7:8 11:12 1:1 >>> # Well, that was a little difficult. Time for a Lattice... >>> g = Duodene(vrat=Ratio(7, 6)) >>> g <14:9> <7:6> <7:4> <21:16> <4:3> <1:1> <3:2> <9:8> <8:7> <12:7> <9:7> <27:14> >>> g.gamut() [<1:1>, <9:8>, <8:7>, <7:6>, <9:7>, <21:16>, <4:3>, <3:2>, <14:9>, <12:7>, <7:4>, <27:14>] >>> cents(g.gamut()) [0.0, 203.910001731, 231.174093531, 266.870905603, 435.084095261, \ 470.780907334, 498.044999134, 701.955000865, 764.915904737, \ 933.129094395, 968.825906468, 1137.03909613] >>>
The module file itself is well documented, and
should be perfectly clear to any Pythoneer. The only strange thing to
observe is that since I think of interval addition as addition,
the code snippet Ratio(4, 3) + Ratio(9, 8)
is actually
doing a fraction multiply behind the scenes.
Ratio
class, as
you can tell from the example above.
__float__
float
function. It simply
turns the ratio into a float (real) value. See cents
complement(against=None)
against
isn't set.
cents()
reduce()
octave()
katapykne(n=1)
If n==1, the (non-superparticular) ratio is simply divided. So, <5:3> will return [<5:4>, <4:3>].
This does 1:1 katapyknosis.
katapykne_ab(a, b)
You may also do this using the Python slice
notation. That is, r[1:1]
will do 1:1
katapyknosis on the Ratio r
chord_of(chord_name, ident=0)
Return a list of ratios which make a chord of the named type. The types available: major, minor, diminished, subminor, dom-7, major-7, minor-7, subminor-7, dom-9, major-9, minor-9. See the source for a complete list.
The default is to make the instance ration the lowest identity of the chord. If you wanted to make a septimal minor (or subminor) triad with 3:2 as the second note, you'd do this:
>>> Ratio(3, 2).chord_of('subminor', 1) [<9:7>, <3:2>, <27:14>]
Since Python is zero-indexed, '1' is the second identity in the chord.
Finally, you may use a list or tuple of harmonic identities instead of a chord name:
>>> Ratio(1, 1).chord_of((5, 7, 9, 33), 1) [<10:7>, <1:1>, <9:7>, <33:28>]
This class should probably be called
Latice
but the default behavior looks like Ellis's
duodene, so that's what it's called.
__init__(hrat=Ratio(3, 2), hn=4, vrat=Ratio(5, 4), vn=3)
d = Duodene(horizontal_ratio, horizontal_number, vert_ratio, vert_num) d = Duodene(vrat=Ratio(7, 4), hn=5, vn=5)
The default is for the horizontal scale to be 4 3:2 (perfect 5ths), and for the vertical scale to be 3 5:4 (major 3rds). The chart will be centered on 1:1, but is biased toward producing more ratios above 1:1, rather than below.
gamut
hn
and vn
at their
default values, this will be 12 ratios.
In addition the the Ratio methods listed above, there are a number of utility functions which operate on a list of either scale or interval ratios.
cents(intervals)
intervals2gamut(intervals)
gamut2intervals(ratios)
gamut2series(gamut)
This gets a touch confused when the series spans more than an octave. You may need to fiddle with the argument to guarantee a completely reduced answer.
gamut2identities(gamut)
That is, give us [1, 5, 3] from a major chord, instead of [4, 5, 6].
ratiotable(ratios)
triads(ratios)
sevenths(ratios)
sevenths
is misleading, and will change shortly.