stepper-motor-synth/gen_pitch_table.py
Peter Cai eeb92cb75b gen_pitch_table: remove workaround for resonance frequencies
Hard-coding this here is not appropriate since we can tune the current
and microstep to move the resonance frequency around.

But really, we should be avoiding the resonating notes during
arrangement, not here as a hard-coded workaround.
2021-06-14 15:44:09 +08:00

66 lines
1.9 KiB
Python

#!/usr/bin/env python3
start_pitch = 36 # C2
end_pitch = 84 # C6
pitch_A0 = 21
pitch_C1 = 24
pitch_A4 = 69
freq_A4 = 440
pitch_D5 = 74
pitch_F5 = 77
def pitch_to_freq(pitch):
dist_A4 = pitch - pitch_A4
factor = pow(2, abs(dist_A4) / 12)
if dist_A4 > 0:
# Notes after A4 are about 20 cents flat
factor = factor * pow(2, 20 / 12 / 100)
if pitch >= pitch_D5:
# After D5 it's about another 10 cents flat
factor = factor * pow(2, 10 / 12 / 100)
if pitch >= pitch_F5:
# After F5 it's about another 10 cents flat
factor = factor * pow(2, 10 / 12 / 100)
return freq_A4 * factor
else:
return freq_A4 / factor
def pitch_to_period_micros(pitch):
return 1 / pitch_to_freq(pitch) * 1000 * 1000
pitch_names = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"]
def pitch_to_name(pitch):
return pitch_names[(pitch - pitch_A0) % 12] + str(int((pitch - pitch_C1) / 12) + 1)
print("#pragma once")
print("#include <avr/pgmspace.h>")
print("")
print("constexpr unsigned int midi_pitch_offset = " + str(start_pitch) + ";")
print("constexpr unsigned int midi_pitch_max = " + str(end_pitch) + ";")
print("// period is in units of 0.5 us, instead of 1 us")
print("constexpr unsigned long midi_pitch_period[" + str(end_pitch - start_pitch) + "] = {")
for i in range(start_pitch, end_pitch):
period = int(2.0 * pitch_to_period_micros(i))
name = pitch_to_name(i)
print(" " + str(period) + "ul,\t// " + name)
print("};")
print("")
print("// scale factors for bend values from 0 to 2047")
print("// We don't support the full 16385 levels of MIDI bend")
print("// MIDI bend values have to be converted first to the nearest supported one")
print("constexpr PROGMEM float midi_pitch_bend_scale[2048] = {")
for i in range(0, 2048):
factor = pow(2, (8192 - i * 8) / 49152)
print(" " + str(factor) + "f,\t// " + str(i))
print("};")