def main(output_file): with output_file.open("w") as fh: fh.write( textwrap.dedent( """\ /* This file is generated by scripts/generate_voice_param_table.py. Do not edit directly. */ /* clang-format off */ #include "gem_lookup_tables.h" #include "fix16.h" const struct GemPitchTableEntry gem_pitch_table[] = { """ ) ) for note in oscillators.midi_note_range(): voltage = oscillators.midi_note_to_voltage(note) frequency = oscillators.midi_note_to_frequency(note) period_reg = oscillators.frequency_to_timer_period(frequency) fh.write(f" {{.pitch_cv = F16({voltage:.6f}), .period = {period_reg}}},\n") fh.write( textwrap.dedent( """\ }; struct GemRampTableEntry gem_ramp_table[] = { """ ) ) for note in oscillators.calibration_note_range(): voltage = oscillators.midi_note_to_voltage(note) frequency = oscillators.midi_note_to_frequency(note) period_reg = oscillators.frequency_to_timer_period(frequency) dac_code_castor = reference_calibration.castor[period_reg] dac_code_pollux = reference_calibration.pollux[period_reg] fh.write( f" {{.period = {period_reg}, .castor_ramp_cv = {dac_code_castor}, .pollux_ramp_cv = {dac_code_pollux} }},\n" ) fh.write( textwrap.dedent( """\ }; size_t gem_pitch_table_len = sizeof(gem_pitch_table) / sizeof(struct GemPitchTableEntry); size_t gem_ramp_table_len = sizeof(gem_ramp_table) / sizeof(struct GemRampTableEntry); /* clang-format on */ """ ) )
def set_oscillators_to_note(note, calibration=reference_calibration): freq = oscillators.midi_note_to_frequency(note) period = oscillators.frequency_to_timer_period(freq) charge_code_castor = oscillators.calibrated_charge_code_for_period( period, calibration.castor) charge_code_pollux = oscillators.calibrated_charge_code_for_period( period, calibration.pollux) print( f"Note: {note}, Freq: {freq}, Charge codes: {charge_code_castor}, {charge_code_pollux}" ) gem.set_period(0, period) gem.set_dac(0, charge_code_castor, 0) time.sleep(0.1) # Needed so the DAC has time to update EEPROM gem.set_period(1, period) gem.set_dac(2, charge_code_pollux, 0)
# Copyright (c) 2021 Alethea Katherine Flowers. # Published under the standard MIT License. # Full text available at: https://opensource.org/licenses/MIT """Ramp calibration values estimated based on circuit design. These values will get close to the target ramp voltage, but will probably be a little off. Generally, reference_calibration is used instead.""" from libgemini import oscillators castor = { oscillators.frequency_to_timer_period( oscillators.midi_note_to_frequency(note)): oscillators.charge_code_for_frequency( oscillators.midi_note_to_frequency(note)) for note in oscillators.calibration_note_range() } pollux = castor.copy()