back to list

Algorithm for 'unfolding' regular temperaments

🔗Torsten Anders <torstenanders@gmx.de>

4/7/2008 3:06:46 PM

Dear all,

[This is possibly a newbie FAQ, please point me to the relevant
literature in this case :) ]

thanks again for your many responses (in particular to George who I
did not thank explicitly before).

Many of you kindly gave me tuning specifications (generator and
period) for regular temperaments / linear temperaments. I understood
that I can use Scala to create the respective temperaments with these
specs. Nevertheless, I would like to compute them myself (e.g., I can
then easily use these temperaments in some composition software --
without any dependency to Scale). Unfortunately, I was unable so far
to find any formal explanation how a tuning table is computed from
such a regular temperament specification.

So, my question is: what is the formula or algorithm you use in order
to compute a tuning table (a list of cent values) for a regular
temperament for which the generator and the period is given? Also,
can you recommend some introductory reading on what regular
temperaments / linear temperaments are?

Thank you!

Best
Torsten

--
Torsten Anders
Interdisciplinary Centre for Computer Music Research
University of Plymouth
Office: +44-1752-233667
Private: +44-1752-558917
http://strasheela.sourceforge.net
http://www.torsten-anders.de

🔗Carl Lumma <carl@lumma.org>

4/7/2008 5:48:46 PM

Hi Torsten,

> So, my question is: what is the formula or algorithm you use
> in order to compute a tuning table (a list of cent values)
> for a regular temperament for which the generator and the
> period is given?

If the period (P) and generator (G) are given as frequency
ratios (e.g. the Pythagorean regime with 2/1 and 3/2), the
pitches of a scale supporting it are given by (G^n)/(P^m),
where n and m are integers between 1 and anything you like
(the total number of pitches you end up with will be n*m).

The distinction between generator and period here is somewhat
artificial. Really they are both just generators. These
temperaments are called "rank 2 regular temperaments" because
their pitches are mapped using two generators. Typically,
one of the generators quickly gives a good approximation to
an interval of psychoacoustic equivalence like the octave.
This generator is called the period by convention. Usually
it is either 1/3 or 1/2 of an octave, or a whole octave.
When it is a whole octave we call the temperament a "linear
temperament", mostly by convention. So Pythagorean scales
can been seen as scales of a linear temperament with a
generator of 3/2 and a mapping of

< 1 1 ]
< 0 1 ]

This is a 3-limit mapping consisting of two "vals". The
first line is the val for the period; the second line is
the val for the generator. The column on the left is the
mapping to the prime number 2, and the column on the right
is the mapping to the prime number 3. So there is 1 period
and 0 generators to get 2:1, and 1 generator and 1 period
to get 3:1.

Is this making any sense?

If P and G are given in cents, the pitches are given by
(G*N) - (P*M). For example, in Pythagorean tuning we
have G = 702 cents and P = 1200 cents.

> Also, can you recommend some introductory reading on what
> regular temperaments / linear temperaments are?

Hopefully the above has demystified it a little.

-Carl

🔗Graham Breed <gbreed@gmail.com>

4/7/2008 7:32:21 PM

Torsten Anders wrote:

> So, my question is: what is the formula or algorithm you use in order
> to compute a tuning table (a list of cent values) for a regular
> temperament for which the generator and the period is given? Also,
> can you recommend some introductory reading on what regular
> temperaments / linear temperaments are?

Here's a simplification of my Python code

scale = []
for nSteps in range(stepsPerPeriod):
root = (nSteps*generator)%period
for repeat in range(periodsPerOctave):
scale.append(period*repeat + root)
scale.sort()

It assumes the generator and period are specified in cents. It also assumes periodsPerOctave is given. If you don't have that you can still get a tuning table for one period.

sorted([(n*generator)%period
for n in range(stepsPerPeriod)])

You always have to choose the number of steps you want. You may also like the period to be include in the table

sorted([(n*generator)%period
for n in range(stepsPerPeriod)])+[period]

For background,

http://eceserv0.ece.wisc.edu/%7Esethares/paperspdf/Erlich-MiddlePath.pdf

Graham

🔗Torsten Anders <torstenanders@gmx.de>

4/8/2008 1:12:36 AM

Dear Carl,

thank you very much for your reply including these simple formulas.
Thanks helpful.

Just for my better understanding: with your following formula I am in
fact creating a lattice (segment) for the dimensions G and P. Is that
correct?

(G^n)/(P^m), n \in 1..n_max, m \in 1..m_max

What are typical values for n_max and m_max? For example, if I have a
generator and a period for pajara (there where many examples in the
recent postings) and I want 22 pitches, do I then use the following?

n_max = 11, m_max = 2

> If P and G are given in cents, the pitches are given by
> (G*N) - (P*M). For example, in Pythagorean tuning we
> have G = 702 cents and P = 1200 cents.

That looks simple enough :)

Thanks!

Best
Torsten

On Apr 8, 2008, at 1:48 AM, Carl Lumma wrote:
> Hi Torsten,
>
>> So, my question is: what is the formula or algorithm you use
>> in order to compute a tuning table (a list of cent values)
>> for a regular temperament for which the generator and the
>> period is given?
>
> If the period (P) and generator (G) are given as frequency
> ratios (e.g. the Pythagorean regime with 2/1 and 3/2), the
> pitches of a scale supporting it are given by (G^n)/(P^m),
> where n and m are integers between 1 and anything you like
> (the total number of pitches you end up with will be n*m).
>
> The distinction between generator and period here is somewhat
> artificial. Really they are both just generators. These
> temperaments are called "rank 2 regular temperaments" because
> their pitches are mapped using two generators. Typically,
> one of the generators quickly gives a good approximation to
> an interval of psychoacoustic equivalence like the octave.
> This generator is called the period by convention. Usually
> it is either 1/3 or 1/2 of an octave, or a whole octave.
> When it is a whole octave we call the temperament a "linear
> temperament", mostly by convention. So Pythagorean scales
> can been seen as scales of a linear temperament with a
> generator of 3/2 and a mapping of
>
> < 1 1 ]
> < 0 1 ]
>
> This is a 3-limit mapping consisting of two "vals". The
> first line is the val for the period; the second line is
> the val for the generator. The column on the left is the
> mapping to the prime number 2, and the column on the right
> is the mapping to the prime number 3. So there is 1 period
> and 0 generators to get 2:1, and 1 generator and 1 period
> to get 3:1.
>
> Is this making any sense?
>
> If P and G are given in cents, the pitches are given by
> (G*N) - (P*M). For example, in Pythagorean tuning we
> have G = 702 cents and P = 1200 cents.
>
>> Also, can you recommend some introductory reading on what
>> regular temperaments / linear temperaments are?
>
> Hopefully the above has demystified it a little.
>
> -Carl
>
>
> --
Torsten Anders
Interdisciplinary Centre for Computer Music Research
University of Plymouth
Office: +44-1752-233667
Private: +44-1752-558917
http://strasheela.sourceforge.net
http://www.torsten-anders.de

🔗Torsten Anders <torstenanders@gmx.de>

4/8/2008 1:12:43 AM

Dear Carl,

thanks a lot for these Python lines. It appears to me that your
formula differs slightly from Carl's. I am translating them into a
common format:

Pitch_i = (Generator * N mod Period) + (Period * M)
where N \in 1..StepsPerPeriod, M \in PeriodsPerOctave

or

Pitch_i = (Generator * N) - (Period * M)

I don't see how I can transform one formula into the other (but that
might be because my last math classes are almost 20 years ago :).
What am I missing?

Thank you!

Best
Torsten

On Apr 8, 2008, at 3:32 AM, Graham Breed wrote:
> Here's a simplification of my Python code
>
> scale = []
> for nSteps in range(stepsPerPeriod):
> root = (nSteps*generator)%period
> for repeat in range(periodsPerOctave):
> scale.append(period*repeat + root)
> scale.sort()
>
> It assumes the generator and period are specified in cents.
> It also assumes periodsPerOctave is given. If you don't
> have that you can still get a tuning table for one period.
>
> sorted([(n*generator)%period
> for n in range(stepsPerPeriod)])
>
> You always have to choose the number of steps you want. You
> may also like the period to be include in the table
>
> sorted([(n*generator)%period
> for n in range(stepsPerPeriod)])+[period]

--
Torsten Anders
Interdisciplinary Centre for Computer Music Research
University of Plymouth
Office: +44-1752-233667
Private: +44-1752-558917
http://strasheela.sourceforge.net
http://www.torsten-anders.de

🔗Torsten Anders <torstenanders@gmx.de>

4/8/2008 1:13:35 AM

Oops, this should of course read "Dear Graham".

On Apr 8, 2008, at 9:12 AM, Torsten Anders wrote:
> Dear Carl,
>
> thanks a lot for these Python lines. It appears to me that your
> formula differs slightly from Carl's. I am translating them into a
> common format:
>
> Pitch_i = (Generator * N mod Period) + (Period * M)
> where N \in 1..StepsPerPeriod, M \in PeriodsPerOctave
>
> or
>
> Pitch_i = (Generator * N) - (Period * M)
>
> I don't see how I can transform one formula into the other (but that
> might be because my last math classes are almost 20 years ago :).
> What am I missing?
>
> Thank you!
>
> Best
> Torsten
>
> On Apr 8, 2008, at 3:32 AM, Graham Breed wrote:
>> Here's a simplification of my Python code
>>
>> scale = []
>> for nSteps in range(stepsPerPeriod):
>> root = (nSteps*generator)%period
>> for repeat in range(periodsPerOctave):
>> scale.append(period*repeat + root)
>> scale.sort()
>>
>> It assumes the generator and period are specified in cents.
>> It also assumes periodsPerOctave is given. If you don't
>> have that you can still get a tuning table for one period.
>>
>> sorted([(n*generator)%period
>> for n in range(stepsPerPeriod)])
>>
>> You always have to choose the number of steps you want. You
>> may also like the period to be include in the table
>>
>> sorted([(n*generator)%period
>> for n in range(stepsPerPeriod)])+[period]
>
> --
> Torsten Anders
> Interdisciplinary Centre for Computer Music Research
> University of Plymouth
> Office: +44-1752-233667
> Private: +44-1752-558917
> http://strasheela.sourceforge.net
> http://www.torsten-anders.de
>
>
>
>

🔗Graham Breed <gbreed@gmail.com>

4/8/2008 6:24:14 AM

Torsten Anders wrote:

> thanks a lot for these Python lines. It appears to me that your
> formula differs slightly from Carl's. I am translating them into a
> common format:
> > Pitch_i = (Generator * N mod Period) + (Period * M)
> where N \in 1..StepsPerPeriod, M \in PeriodsPerOctave
> > or
> > Pitch_i = (Generator * N) - (Period * M)
> > I don't see how I can transform one formula into the other (but that
> might be because my last math classes are almost 20 years ago :).
> What am I missing?

The "mod Period" part adds or subtracts a number of periods such that (Generator * N mod Period) is always between a unison and a period. This is an extension of the modulo operation because it doesn't require integer arguments.

Let's define the modulus as

x/y = floor(x/y) + (x mod y)/y

Then

x mod y = x - y * floor(x/y)

Generator * N mod Period =
Generator * N - Period * floor[(Generator*N)/Period]

the transformation you need is

M = floor[(Generator*N)/Period]

The reason for the modulus being there is that it ensures you get all the notes within the period when all you have to specify is the number of notes (and the period and generator sizes, of course).

More generally you'd have to specify the slice of the spiral of generators you want to use. For example, set the period to 1200 and the generator to 700. The simple algorithm with stepsPerPeriod=7 will give you a Lydian scale. If you wanted a major scale you'd go from -1 to 5 generators instead of 0 to 6. And more generally still you have to be explicit about M.

Graham

🔗Carl Lumma <carl@lumma.org>

4/8/2008 12:57:11 PM

Hi Torsten,

> thank you very much for your reply including these simple
> formulas. Thanks helpful.

Sure. A little too simple, perhaps, but hopefully they
got the point across.

> Just for my better understanding: with your following formula
> I am in fact creating a lattice (segment) for the dimensions
> G and P. Is that correct?

Yes.

> (G^n)/(P^m), n \in 1..n_max, m \in 1..m_max
>
> What are typical values for n_max and m_max?

It depends on the particular generator and period. For
a given G and P, certain values of n_max and m_max will
result in "MOS" scales. These are most popular because
they have a simpler interval structure (at most 2 sizes
of each generic diatonic interval... 2nds 3rds etc.).

>For example, if I have a generator and a period for
>pajara (there where many examples in the recent postings)
>and I want 22 pitches, do I then use the following?
>
> n_max = 11, m_max = 2

It depends where you want those 22 pitches. They could be
obtained with 21 generators and 0 periods, or 21 periods
and 0 generators. Probably you want 22/octave, so 10
generators/period and O*2 periods, where O is the number
of octaves on your instrument.

-Carl

🔗Torsten Anders <torstenanders@gmx.de>

4/8/2008 3:56:35 PM

Thank you for this clarification!

Torsten

On Apr 8, 2008, at 8:57 PM, Carl Lumma wrote:
> Hi Torsten,
>
> > thank you very much for your reply including these simple
> > formulas. Thanks helpful.
>
> Sure. A little too simple, perhaps, but hopefully they
> got the point across.
>
> > Just for my better understanding: with your following formula
> > I am in fact creating a lattice (segment) for the dimensions
> > G and P. Is that correct?
>
> Yes.
>
> > (G^n)/(P^m), n \in 1..n_max, m \in 1..m_max
> >
> > What are typical values for n_max and m_max?
>
> It depends on the particular generator and period. For
> a given G and P, certain values of n_max and m_max will
> result in "MOS" scales. These are most popular because
> they have a simpler interval structure (at most 2 sizes
> of each generic diatonic interval... 2nds 3rds etc.).
>
> >For example, if I have a generator and a period for
> >pajara (there where many examples in the recent postings)
> >and I want 22 pitches, do I then use the following?
> >
> > n_max = 11, m_max = 2
>
> It depends where you want those 22 pitches. They could be
> obtained with 21 generators and 0 periods, or 21 periods
> and 0 generators. Probably you want 22/octave, so 10
> generators/period and O*2 periods, where O is the number
> of octaves on your instrument.
>
> -Carl
>
>
>
--
Torsten Anders
Interdisciplinary Centre for Computer Music Research
University of Plymouth
Office: +44-1752-233667
Private: +44-1752-558917
http://strasheela.sourceforge.net
http://www.torsten-anders.de