#!/usr/bin/env python # # Compute piano tuning table # Author: Yotam Medini yotam.medini@gmail.com -- 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)