tunetbl.py
#!/usr/bin/env python
#
# Compute piano tuning table
# Author: Yotam Medini [email protected] -- Created: 2006/January/15
#
import sys
# Important interval ratios
half_tone_ratio = 2. ** (1./12.)
octave_plus_quint = 2. * half_tone_ratio ** 7
# Important frequencies
La = 440. # Internationally agreed
Si = La * half_tone_ratio ** 2.
Do1 = La * half_tone_ratio ** 3. # 'Do' above central octave
# Indices within octave that we need
DoIndex = 0
FaIndex = 5
LaIndex = 9
SiIndex = 11
# Fit a note frequency by octave-jumping into the central octave
def fit_note_central(freq):
global Si; # already computed outside
global Do1; # already computed outside
# To mark the upper-limit of the central octave,
# we compute imaginary note in the middle between Si and Do1
central_upper_bound = (Si + Do1)/2.
# Move up - or make sure, the frequency is above the central octave
while freq < central_upper_bound:
freq = 2. * freq # jump one octave above
# Move down, the frequency until it is inside the central octave
while freq > central_upper_bound:
freq = freq / 2.
return freq
equalNames = [
"C",
"C#=Db",
"D",
"D#=Eb",
"E",
"F",
"F#=Gb",
"G",
"G#=Ab",
"A",
"A#=Bb",
"B"
]
upHarmonicNames = [ # with Diez
"Do",
"Do-#",
"Re",
"Re-#",
"Mi",
"Fa",
"Fa-#",
"Sol",
"Sol-#",
"La",
"La-#",
"Si"
]
downHarmonicNames = [ # bemol
"Do",
"Re-b",
"Re",
"Mi-b",
"Mi",
"Fa",
"Sol-b",
"Sol",
"La-b",
"La",
"Si-b",
"Si"
]
# Frequencies-lists with dummy initial values
equalFrequencies = 12 * [111.2]
upHarmonicFrequencies = 12 * [222.3]
downHarmonicFrequencies = 12 * [333.4]
# In all tuning systems - we have:
equalFrequencies[LaIndex] = La
upHarmonicFrequencies[LaIndex] = La
downHarmonicFrequencies[LaIndex] = La
##########################################
# Compute the equal-interval frequencies #
##########################################
# Going up
fi = LaIndex + 1
while fi < 12:
equalFrequencies[fi] = equalFrequencies[fi - 1] * half_tone_ratio
fi += 1
# Going down
fi = LaIndex - 1
while fi >= 0:
equalFrequencies[fi] = equalFrequencies[fi + 1] / half_tone_ratio
fi += -1
############################################
# Compute the Up&Down Harmonic frequencies #
############################################
#
# For this, we do quint (qvinta) jumps up & down.
# La -> Mi -> Si ... or La -> Re -> Sol ...
#
#######################################
# Compute the Up-Harmonic frequencies #
#######################################
#
# Going down until Fa (included)
fi = LaIndex
currFrequency = upHarmonicFrequencies[fi] # == La
while fi != FaIndex:
fi = (fi + (12 - 7)) % 12 # 7 half-tones down
currFrequency = fit_note_central(currFrequency / 3.)
upHarmonicFrequencies[fi] = currFrequency
#
# Going Up until Fa (excluded)
fi = LaIndex
currFrequency = upHarmonicFrequencies[fi] # == La
fi = (fi + 7) % 12 # 7 half-tones up
while fi != FaIndex:
currFrequency = fit_note_central(3. * currFrequency)
upHarmonicFrequencies[fi] = currFrequency
fi = (fi + 7) % 12 # 7 half-tones up
#########################################
# Compute the Down-Harmonic frequencies #
#########################################
#
# Going Up until Si (included)
fi = LaIndex
currFrequency = upHarmonicFrequencies[fi] # == La
while fi != SiIndex:
fi = (fi + 7) % 12 # 7 half-tones up
currFrequency = fit_note_central(3. * currFrequency)
downHarmonicFrequencies[fi] = currFrequency
#
# Going down until Si (excluded)
fi = LaIndex
currFrequency = downHarmonicFrequencies[fi] # == La
fi = (fi + (12 - 7)) % 12 # 7 half-tones down
while fi != SiIndex:
currFrequency = fit_note_central(currFrequency / 3.)
downHarmonicFrequencies[fi] = currFrequency
fi = (fi + (12 - 7)) % 12 # 7 half-tones down
# Print the combined table
sys.stdout.write("""
--------------------------------------------------------
| Equal-Interval Up-Harmonic Down-Harmonic |
--------------------------------------------------------
""")
for fi in range(0, 12):
sys.stdout.write(
"| %-5s %6.2f | %-5s %6.2f | %-5s %6.2f |\n" %
(equalNames[fi], equalFrequencies[fi],
upHarmonicNames[fi], upHarmonicFrequencies[fi],
downHarmonicNames[fi], downHarmonicFrequencies[fi]))
sys.stdout.write(" --------------------------------------------------------\n")
sys.exit(0)
Generated by GNU enscript 1.6.4.