Harmonics
In 1992 the author set out to find a consonance rating for musical intervals: a number, worked out from the ratio p/q alone, that says how smooth the interval sounds. The idea was to count how often each interval turns up among pairs of whole numbers, and to call the more frequent ones the more consonant. These are the programs, written in BASIC on a second-hand IBM PCjr and then translated into Fortran and C.
Several do not run as written, so each result below is what the program set out to compute, worked out again by harmonics.py with exact arithmetic. The listings are kept exactly as printed: the scans, and a transcription of each. They are the starting point of Coprime pairs and musical intervals, which takes up the same question.
Did they find a consonance rating?
Partly. The counting programs (Harmonic1, Harmonic3 and Harmonic4) do produce a rating, and it gets the top of the order right: fifth, major sixth, then the harmonic seventh and minor sixth, then the minor seventh. But the count for p/q works out to ⌊(C−1)/(p−q)⌋, so the rating depends only on p−q. Three things follow.
- Ties that should not be. 9/5 ties with 11/7, which the other rules put at least two places lower, and 11/6, 12/7, 13/8 and 14/9 all tie. 13/7 comes last, where p²+q², p+q and Tenney put it ahead of 13/8 and 14/9.
- Half the octave is missing. Counting only pairs with D ≤ C keeps every ratio between 3/2 and 2. The fourth (4/3), the major third (5/4) and the minor third (6/5), three of the six classical consonances after the octave, never appear.
- The rating comes from the cap, not just the interval. A pair lands on p/q when it is a multiple of (p−q, 2q−p), and capping C caps only the first number, so only p−q counts. Capping the sum of the two instead would rank by q alone.
The 11 intervals the programs test are exactly the ratios between 3/2 and 2 with p−q from 1 to 5, plus 13/7. Set beside four rules for consonance, the rating’s rank correlation is 0.90 with three of them and 0.85 with Euler’s:
The consonance rating the counting programs produce, beside four rules for
how simple a ratio p/q is. 1 = most consonant; equal scores share a rank.
The count is how many pairs up to C = 32769 land on the interval:
floor(32768/(p-q)), so the programs' rank is the rank of p-q.
ratio interval count programs p2+q2 p+q Tenney p*q Euler
(p-q)
3/2 perfect 5th 32768 1 1 1 1 1
5/3 major 6th 16384 2 2 2 2 2
7/4 harmonic 7th 10922 3 3 3 3 4
8/5 minor 6th 10922 3 4 4 4 3
9/5 minor 7th 8192 4 5 5 5 4
11/7 8192 4 7 7 7 9
11/6 6553 5 6 6 6 7
12/7 6553 5 8 8 8 5
13/8 6553 5 10 10 10 8
14/9 6553 5 11 11 11 6
13/7 5461 6 9 9 9 10
Rank correlation (Spearman) of the programs' rating with each rule:
p^2 + q^2 0.90
p + q (Pythagorean) 0.90
p * q (Tenney) 0.90
Euler's gradus 0.85
Harmonic4 over all 128 ratios from the 20 x 20 grid: its counts
floor(20/(p-q)) take only 8 values, 96 ratios tie at 1, and the rank correlation
with p^2 + q^2 is 0.74.
The two programs that draw (Harmonic5 and Pattern) rate nothing, but they hold the idea that worked later: the coprime pairs are the ratios in lowest terms, each interval once, and coprime-intervals rates them by height 1/(p²+q²), which very nearly orders the consonances as Helmholtz listed them.
Harmonic1
For every pair 2 ≤ D ≤ C, works out (2C+D−3)/(C+D−2), which always lies between 3/2 and 2, and counts how often it lands exactly on each of 11 intervals. Prints the totals each time C reaches 2, 3, 5, 9, … 32769. The totals turn out to be ⌊(C−1)/(p−q)⌋, so intervals with the same p−q always tie: 7/4 with 8/5, 9/5 with 11/7, and 11/6, 12/7, 13/8 and 14/9 together.
Toward a consonance rating. The first rating: more pairs means more consonant. Its top five, the fifth, the major sixth, the harmonic seventh and minor sixth (tied), and the minor seventh, come in the order p²+q², p+q and Tenney’s p·q give. Below that it goes astray, because it sees only p−q.
As written. The BASIC should print the counts (not run here), stopping with “RETURN without GOSUB” once the loops end; reaching 32769 would take days. The Fortran and its f2c translation divide 3/2 as whole numbers, which gives 1, so every count is 0, and they stop after the first line. The C by hand puts the comparison inside fabs, never declares fabs, starts its counters at garbage and never stops.
BASIC: scan, text · Fortran: scan, text · C from f2c: scan, text · C by hand: scan, text
Harmonic1: how many pairs 2 <= D <= C give (2C+D-3)/(C+D-2) = p/q,
totals printed each time C reaches 2, 3, 5, 9, ... 32769.
Counted pair by pair up to C = 1025; above that from the formula
floor((C-1)/(p-q)), which the counting confirms exactly.
ratio 3/2 5/3 7/4 8/5 9/5 11/7 11/6 12/7 13/8 14/9 13/7
cents 702 884 969 814 1018 782 1049 933 841 765 1072
C
2 1 0 0 0 0 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0 0 0
5 4 2 1 1 1 1 0 0 0 0 0
9 8 4 2 2 2 2 1 1 1 1 1
17 16 8 5 5 4 4 3 3 3 3 2
33 32 16 10 10 8 8 6 6 6 6 5
65 64 32 21 21 16 16 12 12 12 12 10
129 128 64 42 42 32 32 25 25 25 25 21
257 256 128 85 85 64 64 51 51 51 51 42
513 512 256 170 170 128 128 102 102 102 102 85
1025 1024 512 341 341 256 256 204 204 204 204 170
2049 2048 1024 682 682 512 512 409 409 409 409 341
4097 4096 2048 1365 1365 1024 1024 819 819 819 819 682
8193 8192 4096 2730 2730 2048 2048 1638 1638 1638 1638 1365
16385 16384 8192 5461 5461 4096 4096 3276 3276 3276 3276 2730
32769 32768 16384 10922 10922 8192 8192 6553 6553 6553 6553 5461
Harmonic2
Reads a start, an end and a number of steps, walks along sin(x), and lists where the curve turns over. Shown for 0 to 20 in 200 steps.
Toward a consonance rating. No rating. It looks at a single sine wave, not at two notes together.
As written. Records nothing useful in any form: once the curve is rising it never checks for a turn, and when falling it writes every point to the same slot. The Fortran and f2c versions also write outside the array (W(0), w[−1]).
BASIC: scan, text · Fortran: scan, text · C from f2c: scan, text
Harmonic2: turning points of sin(x) from 0 to 20 in 200 steps
(step 0.1). Each is the sample where the curve turns over, with the
true turning point (k + 1/2)pi beside it.
x sin(x) kind true x
1.6000 0.99957 peak 1.5708
4.7000 -0.99992 trough 4.7124
7.9000 0.99894 peak 7.8540
11.0000 -0.99999 trough 10.9956
14.1000 0.99931 peak 14.1372
17.3000 -0.99977 trough 17.2788
Harmonic3
Harmonic1’s count, started again from zero each time the limit doubles. The listing never stops; the result stops at 1025.
Toward a consonance rating. The same rating as Harmonic1. Recounting each pass shows it settles early: from B = 17 on, the order of the 11 intervals never changes.
As written. The BASIC should work, and runs for ever as designed. The Fortran and f2c versions make one pass of zeros (3/2 divided as whole numbers again). The C by hand has Harmonic1’s fabs mistakes and its listing stops partway.
BASIC: scan, text · Fortran: scan, text · C from f2c: scan, text · C by hand: scan, text
Harmonic3: B, then the interval counts for every pair 2 <= D <= C <= B,
recounted from scratch each pass. The listing never stops; this
stops at B = 1025.
ratio 3/2 5/3 7/4 8/5 9/5 11/7 11/6 12/7 13/8 14/9 13/7
cents 702 884 969 814 1018 782 1049 933 841 765 1072
B
2 1 0 0 0 0 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0 0 0 0
5 4 2 1 1 1 1 0 0 0 0 0
9 8 4 2 2 2 2 1 1 1 1 1
17 16 8 5 5 4 4 3 3 3 3 2
33 32 16 10 10 8 8 6 6 6 6 5
65 64 32 21 21 16 16 12 12 12 12 10
129 128 64 42 42 32 32 25 25 25 25 21
257 256 128 85 85 64 64 51 51 51 51 42
513 512 256 170 170 128 128 102 102 102 102 85
1025 1024 512 341 341 256 256 204 204 204 204 170
Harmonic4
Lists every distinct ratio (2X+Y)/(X+Y) of at least 3/2 for X and Y up to 20, then counts how often each occurs. The listing counts only up to 10, where most of the ratios never occur; counted over the same grid up to 20, every ratio occurs at least once.
Toward a consonance rating. The widest attempt: it rates every ratio the grid makes, 128 of them, rather than 11 chosen ones. But the counts are ⌊20/(p−q)⌋ again, with only 8 different values: 96 ratios tie at 1, and the major seventh 15/8 ties with 20/13.
As written. Does not run: its 210 entries overflow a 100-place array, line 90 reads IF N= THEN 110, it tallies only the first two ratios, and its print loop opens with FOR X but closes with NEXT O.
Harmonic4: every distinct ratio (2X+Y)/(X+Y) of at least 3/2 for X, Y
from 1 to 20, smallest first, with how often it occurs in that grid.
128 ratios.
ratio cents count
3/2 702.0 20
59/39 716.7 1
56/37 717.5 1
53/35 718.4 1
50/33 719.4 1
47/31 720.5 1
44/29 721.7 1
41/27 723.2 1
38/25 724.9 1
35/23 726.9 1
32/21 729.2 1
29/19 732.1 2
55/36 733.7 1
26/17 735.6 2
49/32 737.7 1
23/15 740.0 2
43/28 742.7 1
20/13 745.8 2
57/37 748.1 1
37/24 749.4 1
54/35 750.7 1
17/11 753.6 3
48/31 756.9 1
31/20 758.7 1
45/29 760.6 1
14/9 764.9 4
53/34 768.5 1
39/25 769.9 1
25/16 772.6 2
36/23 775.6 1
47/30 777.2 1
11/7 782.5 5
52/33 787.3 1
41/26 788.5 1
30/19 790.8 1
49/31 792.6 1
19/12 795.6 2
46/29 798.7 1
27/17 800.9 2
35/22 803.8 1
43/27 805.7 1
51/32 806.9 1
8/5 813.7 6
53/33 820.2 1
45/28 821.4 1
37/23 823.1 1
29/18 825.7 1
50/31 827.6 1
21/13 830.3 2
34/21 834.2 1
47/29 835.9 1
13/8 840.5 4
44/27 845.5 1
31/19 847.5 1
49/30 849.4 1
18/11 852.6 2
41/25 856.4 1
23/14 859.4 2
51/31 861.9 1
28/17 863.9 1
33/20 867.0 1
38/23 869.2 1
43/26 871.0 1
48/29 872.4 1
5/3 884.4 10
47/28 896.7 1
42/25 898.2 1
37/22 900.0 1
32/19 902.5 1
27/16 905.9 1
49/29 908.1 1
22/13 910.8 2
39/23 914.2 1
17/10 918.6 2
46/27 922.4 1
29/17 924.6 1
41/24 927.1 1
12/7 933.1 4
43/25 938.9 1
31/18 941.1 1
19/11 946.2 2
45/26 949.7 1
26/15 952.3 1
33/19 955.8 1
40/23 958.0 1
47/27 959.6 1
7/4 968.8 6
44/25 978.7 1
37/21 980.6 1
30/17 983.3 1
23/13 987.7 2
39/22 991.2 1
16/9 996.1 2
41/23 1000.8 1
25/14 1003.8 1
34/19 1007.4 1
43/24 1009.6 1
9/5 1017.6 5
38/21 1026.7 1
29/16 1029.6 1
20/11 1035.0 2
31/17 1040.1 1
42/23 1042.5 1
11/6 1049.4 4
35/19 1057.6 1
24/13 1061.4 1
37/20 1065.0 1
13/7 1071.7 3
41/22 1077.7 1
28/15 1080.6 1
43/23 1083.2 1
15/8 1088.3 2
32/17 1095.0 1
17/9 1101.0 2
36/19 1106.4 1
19/10 1111.2 2
40/21 1115.5 1
21/11 1119.5 2
23/12 1126.3 1
25/13 1132.1 1
27/14 1137.0 1
29/15 1141.3 1
31/16 1145.0 1
33/17 1148.3 1
35/18 1151.2 1
37/19 1153.8 1
39/20 1156.2 1
41/21 1158.3 1
Harmonic5
Gives each screen row to a number, splits it into primes, and puts a dot at every multiple of each prime along the row. A dot means the column and row share a factor, so the dark gaps are the coprime pairs.
Toward a consonance rating. No rating, but a different idea: the coprime pairs are the ratios in lowest terms, each interval exactly once. This is the map coprime-intervals later rates by height.
As written. Draws nothing: the lines that store a new prime can never be reached. The Fortran does not compile.
BASIC: scan, text · Fortran: scan, text
Pattern
Prints every point (X, Y) up to 199 where X and Y are both multiples of some A from 2 to 199: every pair with a common factor, 24,471 lines in all.
Toward a consonance rating. No rating: the same map as Harmonic5, from the other side, listing the pairs that are not in lowest terms.
As written. The BASIC and the C by hand work. The Fortran and its f2c translation stop after A = 2, for want of a jump back.
BASIC: scan, text · Fortran: scan, text · C from f2c: scan, text · C by hand: scan, text