back to list

Re: Happy Holidays, Paul and everyone -- a gift

🔗M. Schulter <MSCHULTER@VALUE.NET>

12/25/2001 3:46:50 PM

Hello, there, Paul Erlich and everyone, and here's a small holiday
present addressing one of my pet topics: "virtually closed" tunings,
and how to find them.

Basically, a virtually closed tuning is something in a convention
system with 1:2 octaves like 53-note Pythagorean, or a 31-note version
of 1/4-comma meantone. The circle doesn't _precisely_ close from a
mathematical point of view, but musically we have a nice circulating
tuning, with one "odd" fifth slightly larger or smaller than the
others. In contrast to 53-tET or 31-tET, we have a system with
_slight_ "asymmetries," but much the same "circular" qualities.

Thus explanations on why no number of pure 3:2 fifths can form an
exact multiple of a pure 2:1 octave are quite correct -- but don't
prevent Pythagorean from circulating admirably in 53 notes, let alone
665, say.

What follows is a program taken a chosen size of generator, for
example, 701.955 cents, and testing points at which a chain of such
generators closely approximate an even 1200-cent octave.

This program can also be used to list _all_ the intervals generated
from a chain of identical intervals, in the order they appear on the
chain -- for example, the first 53 or 665 or 1024 notes along a chain
of pure fifths, or 1/4-comma meantone fifths, or whatever generator
you might be curious about. I'll explain this feature below.

I've written it in PostScript, the programming language with which I'm
most familiar, although I'm sure some people familiar with this area
might comment that a compiled language like C would handle numerics
more efficiently -- and also that PostScript's precisely is hardly the
highest <grin>. For calculations in cents, however, where the first
couple of decimal places may be the most musically significant, I hope
that this routine may be useful as well as fun.

Here I have a bit to explain, and maybe should take things in this
order:

(1) What you'll need to use the program, mainly a
PostScript language interpreter of some kind
(for example the free Aladdin or GNU Ghostscript
available on the Internet) to display the results
on screen or print them out;

(2) The actual PostScript program file, a plain ASCII
text file

(3) What the program does, the main Tuning List
interest, whether it is done in PostScript
or some other programming language, and how to
choose a generator size and other options when
using the program.

----------------------
1. What is PostScript?
----------------------

PostScript is a computer language which specializes in imaging font
characters and other graphics objects on a page, while also including
some generalized programming features including the mathematical
operations necessary to make calculations in cents.

Often a PostScript file is simply an ASCII text file with appropriate
programming instructions, much like source code in C or some other
language. A PostScript interpreter is necessary in order to process
the file, usually resulting in text characters or other shapes drawn
on one or more output pages -- either printed, or displayed on a
monitor.

Dedicated PostScript-compatible printers have their own PostScript
interpreters, but another option is to use a computer-based
interpreter such as the free Aladdin or GNU Ghostscript to translate a
PostScript file into output either for displaying on screen, or for
printing on any of a large number of supported printers which don't
have their own dedicated PostScript interpreters.

For the "virtual closure" program which follows, virtcl09.ps, the
screen display option might be very convenient, since you might often
be curious about virtual closure points for this or that generator
without necessarily wanting to expend paper (and ink or toner) to
print hard copy for each generator size you casually test.

Also, if used to test points of virtual closure, typically the program
produces only a few lines of output, one for each such point. For
example, searching for virtually closed systems along a Pythagorean
chain of up to 1024 notes with a "tolerance" of up to 5 cents from
perfect closure turns up eight such possibilities (53, 306, 359, 612,
665, 718, 971, or 1024 notes).

If you use the option to list _all_ the intervals in a large tuning
set, of course, then you can generate _lots_ of output to screen or
printer, and the program has a capability to produce multiple pages if
necessary.

-------------------------------------------------------------------
2. The PostScript program itself -- explanation immediately follows
-------------------------------------------------------------------

Why don't I first give a listing of the program itself, and then an
explanation of the part which specifies the generator size and the
other options for calculating a listing of virtual closure points --
or a listing of all intervals generated from the starting note of a
tuning chain.

In looking over the code, you might find it somewhat reassuring that
generally a user need deal with only three relevant choices specified
near the end of the file: the generator size (here '701.955'); the
maximum number of notes to test (here '1024'), and the "tolerance" in
cents, or how close the system should come to perfect closure in order
to be listed (here '5').

--------- virtcl09.ps: PostScript file starts next line of text ----

%!PS

/50string 50 string def
/StartCurLine 720 def
/StartCurPos 72 def
/LineSpace 12 def
/ColumnSpace 150 def
/PageWidth 612 def
/RightMargin 120 def
/LowerMargin 72 def
/SetFont { /Palatino-Roman findfont 10 scalefont setfont } bind def

/StartNewPage
{ showpage
SaveState restore
/SaveState save def
/CurPos StartCurPos def
/CurLin StartCurLine def
} bind def

/RationalToCents % usage: 3 2 RationalToCents
% this example would convert 3/2 to cents
{ div log 2 log div 1200 mul }
bind def

/VirtualClose
{ /MaxSize exch def /Tolerance exch def /Fifth exch def
SetFont
/CurLine StartCurLine def
/CurPos StartCurPos def
/SaveState save def
1 1 MaxSize
{ /Fifth# exch def
Fifth Fifth# mul dup /IntervalSize exch def
1000 mul cvi 1200000 mod 1000 div
dup dup /FifthCents exch def
Tolerance le exch
1200 sub abs Tolerance le or
{ CurPos CurLine moveto
Fifth 50 string cvs show ( ) show
Fifth# 50 string cvs show ( ) show
IntervalSize 50 string cvs show ( ) show
FifthCents 50 string cvs show
/CurLine dup load LineSpace sub def
CurLine LowerMargin lt
{ /CurPos dup load ColumnSpace add def
PageWidth CurPos sub RightMargin lt
{ StartNewPage
} if
/CurLine StartCurLine def
} if
} if
} for
} bind def

%%EndProlog
save mark

% fifth or generator size

701.955

% tolerance in cents
% (setting to 1200 will list all steps in tuning)

5

% number of generators to check

1024

VirtualClose

cleartomark restore
showpage

%%Trailer

------------ PostScript file ended on line before this one ---------

----------------------------------------------
3. How to choose a generator and other options
----------------------------------------------

For most purposes, the only lines calling for editing are the three
near the end of the program marked by comments; in PostScript, any
portion of a line preceded by a "%" is treated as a comment:

% fifth or generator size

701.955

% tolerance in cents
% (setting to 1200 will list all steps in tuning)

5

% number of generators to check

1024

VirtualClose

Here 'VirtualClose' is the command -- or, technically speaking, the
"PostScript procedure" -- that runs the main program. If we omit the
comment lines -- which I suggest keeping in the actual program as a
user-friendly reference -- then the basic pattern for the program is
as follows:

701.955 5 1024 VirtualClose

The first number gives the generator size in cents, here 701.955, the
approximate size for a pure 3:2 fifth.

The second number gives the "tolerance" in cents, how far we are
willing for a listed system to vary from perfect "mathematical
closure." Here the specified tolerance is five cents, so that we'll
list any systems where the last fifth would produce an interval within
5 cents in either direction of a pure 1200-cent octave from the
starting note.

The third number gives the maximum number of notes to check, here
1024.

Similarly we could do:

696.5784 6.5 830 VirtualClose

and check any points of virtual closure along a chain of 1/4-comma
meantone fifths (about 696.5784 cents) within 6.5 cents of perfect
closure, testing up to 830 notes.

You can get lots of interesting results just by playing around with
these three numbers. However, two features provide some extra options:
specifying a generator as an integer ratio, and listing _all_
intervals of a tuning system in reference to the starting note.

-------------------------------------------------
3.1. Fun and Games (1): Specifying integer ratios
-------------------------------------------------

For our Pythagorean example, we could also have written:

3 2 RationalToCents 5 1024 VirtualClose

This option uses the 'RationalToCents' procedure defined earlier in
the program file to calculate the tuning chain based on an integer
ratio of 3:2. Here there are two big cautions to avoid PostScript
errors.

First, the numbers are written, larger term first, with a space
between them and no other punctuation -- '3 2 RationalToCents'.

Secondly, _PostScript is a case-sensitive language_, meaning that
'RationalToCents' needs to have exactly this form of capitalization;
'rationaltocents' or 'RationaltoCents', for example, would not be
recognized and would produce an 'undefined' error from the
interpreter. In the second incorrect example, only the lowercase 't'
in 'To' differs from the desired form, so this is something to watch.

While 'fifths' are the most familiar types of generators, we're free
to use any desired generator size, specified in cents or as an integer
ratio, e.g.

266.871 5 1024 VirtualClose

or

7 6 RationalToCents 5 1024 VirtualClose

While this isn't Manuel Op de Coul's Scala, one PostScript refinment
may make the 'RationalToCents' option yet more entertaining. Suppose
we want to calculate points of virtual closure for the "Wonder Tuning"
defined in Scala's scale archive, with a generator equal to precisely
1/3 of a pure fifth:

3 2 RationalToCents 3 div 5 1024 VirtualClose

Here '3 2 RationalToCents' gives the size in cents for a 3:2 fifth,
while the PostScript '3 div' divides this result by 3 to find the size
of the desired generator. Note that the '3' comes _before_ the 'div',
a "natural" ordering for those of us who grew up on PostScript, but
different from the order followed in some other languages like C.

Here's another example for a tuning of interest to this list:

18 5 RationalToCents 19 div 5 1024 VirtualClose

This defines the generator as 1/19 of a pure 18:5 -- or, as it might
be written in Scala, 18/5^1/19. Can anyone recognize this tuning?

-----------------------------------------------------------
3.2. Fun and Games (2): Listing _all_ intervals in a tuning
-----------------------------------------------------------

Here there's a simple trick, involving the second or "tolerance"
option -- set this option to '1200' in order to list all intervals
along the chain as measured from the starting note. For example, for a
53-note Pythagorean tuning, we could use either

701.955 1200 53 VirtualClose

or

3 2 RationalToCents 1200 53 VirtualClose

Sometimes we might first use the usual form of the program with a
tolerance like '3' or '5' to look for some tuning sizes of interest
with a given generator, and then set the tolerance to '1200' to list
all the intervals of such a tuning set.

For example, consider Gary Morrison's 88-cET (88-cent equal
temperament) with a repeated generator of 88 cents. Although this is
a "nonoctave" tuning, we can try something like

88 5 1024 VirtualClose

and find out that 88-cET in fact closes, not only "virtually" but
perfectly, every 150 notes. Then we can list all the intervals of a
150-note set:

88 1200 150 VirtualClose

Running this version shows that the set closes at 13200 cents, where
150 generators of 88 cents equal precisely 13 pure octaves above the
starting note.

This listing, by the way, fits on one page -- but longer ones may go
to multiple pages.

-------------------------------------------------
4. A fine point: Counting by notes or generators?
-------------------------------------------------

Looking over this article, I note a small point which shouldn't
present any problem to a user, but might be worthy of note: I've
sometimes referred, for example, to a Pythagorean tuning set with
either "1024 notes" or "1024 generators." Actually, both are correct
-- but from different viewpoints.

From the viewpoint of the program listing, we are actually testing
virtual closure for a given number of _generators_: 31 fifths in
1/4-comma meantone, or 53 in Pythagorean, or 150 in 88-cET, etc.
We're checking to see how close the interval from the starting note
formed by the given number of generators comes to an exact multiple of
an octave at 2:1 or 1200 cents.

From the viewpoint of actually tuning a virtually closed system as a
pure octave tuning, however, we're talking about the number of _notes_
per octave: 53 for the smallest "virtually closed" Pythagorean system,
or 31 for 1/4-comma meantone, etc.

What happens in 53-note Pythagorean, for example, is that we actually
tune a chain of 52 pure fifths (53 notes), followed by other pure
octaves of these notes -- for example, the octave of the starting
note, which the 53rd fifth would exceed by about 3.62 cents. Thus this
"odd" fifth is "virtually tempered" in the narrow direction by this
amount.

Similarly, in 1/4-comma meantone, we tune a chain of 30 regular
tempered fifths, with the "odd" 31st fifth about 6.07 cents larger
than the others in order to obtain a pure octave to the starting
note. Since the regular fifths are about 5.38 cents narrow, this
produces an "odd" near-pure fifth slightly larger than 3:2.

Thus if a chain of 53 generators would _exceed_ a pure octave by some
amount, for example, a virtually closed system of 53 notes will have the
last odd "generator-like" interval _narrowed_ by the same amount by
comparison to the other generators; if a chain of 31 generators would
_fall short_ of a pure octave by a given amount, then the "odd" interval
will be _widened_ by this amount.

This can have significant implications for the desired "tolerance"
which the program doesn't attempt to address, but users might
consider. For example, consider a 22-note chain of fifths tempered so
as to generate regular major thirds at a pure 9:7 (~435.08 cents).
Here our generator has a size of about 708.771 cents, slightly smaller
than in 22-tET, where the regular third of about 436.36 cents is a bit
larger than a pure 9:7 ratio:

708.771 8 500 VirtualClose

The listing tells us that a chain of 22 such fifths would yield an
interval of 1192.96 cents, or about 7.04 cents short of a pure octave,
and thus within our 8-cent tolerance.

However, since this chain falls short of a pure octave, we must
therefore achieve "virtual closure" by stretching the "odd" fifth of a
22-note tuning an extra 7.04 cents in the _wide_ direction. Since
regular fifths are already about 6.82 cents wide, this means a total
stretching of about 13.85 cents. Such an odd fifth at about 715.81
cents goes beyond usual "well-temperament" standards, although the
success of tunings like 20-tET (720 cents) shows that this option is
quite practical in a suitable timbre. Jacky Ligon or I might relish
this wide fifth, considering it a bit of "local color."

The main practical lesson of this exercise is that the "tolerance"
measures the amount by which the size of an "odd" interval used in a
virtually closed system to complete the circle may differ from the
size of the other generators in _either_ direction. Determining the
musical consequences calls for attention to the direction of the
adjustment, something left to the user.

May I conclude by offering technical support via e-mail, plus best
wishes to all, including Paul and Pierre who have regaled the list
with beautiful graphics to celebrate the season.

Peace, love, and joyous tidings,

Margo Schulter
mschulter@value.net

🔗paulerlich <paul@stretch-music.com>

12/26/2001 12:44:24 PM

Thank you Margo. I hope you're having a very happy holiday time, and
I'll look at your gift when I get a chance. Cheers!