#!/usr/bin/env python3 import wave import random import struct import sys import math """ Generate a header file with an array mapping each ASCII character to the frequency control word of the corresponding piano key. """ if len(sys.argv) < 3: print("Usage: ./fcw_generator <output header file> <sample frequency>") print("Example: ./fcw_generator scale.h 30e3") sys.exit(1) output_file = sys.argv[1] sample_freq = float(sys.argv[2]) # Can supply custom sampling frequency, otherwise defaults to 30 KHz if len(sys.argv) > 2: sample_freq = float(sys.argv[2]) else: sample_freq = 30.0e3 note_map = { 'Z': 65.4064, 'S': 69.2957, 'X': 73.4162, 'D': 77.7817, 'C': 82.4069, 'V': 87.3071, 'G': 92.4986, 'B': 97.9989, 'H': 103.826, 'N': 110.000, 'J': 116.541, 'M': 123.471, '<': 130.813, 'z': 130.813, 's': 138.591, 'x': 146.832, 'd': 155.563, 'c': 164.814, 'v': 174.614, 'g': 184.997, 'b': 195.998, 'h': 207.652, 'n': 220.000, 'j': 233.082, 'm': 246.942, ',': 261.626, 'q': 261.626, '2': 277.183, 'w': 293.665, '3': 311.127, 'e': 329.628, 'r': 349.228, '5': 369.994, 't': 391.127, '6': 415.305, 'y': 440.000, '7': 466.164, 'u': 493.883, 'i': 523.251, 'Q': 523.251, '@': 554.365, 'W': 587.330, '#': 622.254, 'E': 659.255, 'R': 698.456, '%': 739.989, 'T': 783.991, '^': 830.609, 'Y': 880.000, '&': 932.328, 'U': 987.767, 'I': 1046.50 } fcw_output_file = open(output_file, 'w') fcw_output_file.write('static const uint32_t switch_periods[256] = {\n') for ascii_index in range(128): if chr(ascii_index) in note_map: note_freq = note_map[chr(ascii_index)] note_tone_switch_period = round(float(note_freq) * (2**24 / sample_freq) / 2.0) fcw_output_file.write(" ['{}'] = {},\n".format(chr(ascii_index), note_tone_switch_period)) fcw_output_file.write('};') fcw_output_file.close()