8bitworkshop/tools/mknotes2600.py

92 lines
2.3 KiB
Python
Executable File

#!/usr/bin/python
import sys, string, math, argparse
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--length', type=int, default=64, help="length of note table")
parser.add_argument('-u', '--upper', type=int, default=49, help="upper note # to test")
args = parser.parse_args()
test_notes = args.upper
final_notes = args.length
basehz = 15720.0 #4
basehz2 = 5240.0 #12
basehz3 = 1014.2 #6
s = 8
bittable = [
0b00000000,
0b00000001,
0b00010001,
0b01001001,
0b01010101,
0b10110101,
0b11011011,
0b11101111,
]
results = []
for a440 in range(4200,4600):
error = 0
for note in range(4,test_notes):
notehz = a440 / 10.0 * math.pow(2.0, (note - 49) / 12.0);
period = round(basehz * s / notehz) / s
tonehz = basehz / period
if period < s or period > 32*s:
tonehz = -10000
period2 = round(basehz2 * s / notehz) / s
tonehz2 = basehz2 / period
if period2 < s or period2 > 32*s:
tonehz2 = -10000
period3 = round(basehz3 * s / notehz) / s
tonehz3 = basehz3 / period
if period3 < s or period3 > 32*s:
tonehz3 = -10000
error += min(abs(notehz-tonehz), abs(notehz-tonehz2), abs(notehz-tonehz3))
results.append((error, a440))
results.sort()
best_error, best_a440 = results[0]
best_a440 /= 10.0
print('//', best_a440, best_error, test_notes)
periods = []
tones = []
bits = []
print("const int note_table[%d] = {" % final_notes)
for note in range(0,final_notes):
notehz = best_a440 * math.pow(2.0, (note - 49) / 12.0);
bestperiod = 255
bestscore = 999999
besthz = -1
for hz in [basehz, basehz2, basehz3]:
period = int(round(hz * s / notehz))
if period >= s and period <= 32*s:
tonehz = hz / period
error = notehz - hz
if error < bestscore:
bestscore = error
bestperiod = period
besthz = hz
#print(note, besthz, bestperiod, notehz)
print('%d,' % period, end='')
periods.append(bestperiod / s - 1)
bits.append(bittable[bestperiod & (s-1)])
if besthz==basehz:
tones.append(4)
elif besthz==basehz2:
tones.append(12)
elif besthz==basehz3:
tones.append(6)
else:
tones.append(0)
print("};")
print(periods)
print(bits)
print(tones)