diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index eaf67cc0e7..89929b0563 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -262,12 +262,19 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma } MP_DEFINE_CONST_FUN_OBJ_KW(synthio_from_file_obj, 1, synthio_from_file); +STATIC mp_obj_t midi_to_hz(mp_obj_t arg) { + mp_int_t note = mp_arg_validate_int_range(mp_obj_get_int(arg), 1, 127, MP_QSTR_note); + return mp_obj_new_float(common_hal_synthio_midi_to_hz_float(note)); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_midi_to_hz_obj, midi_to_hz); + STATIC const mp_rom_map_elem_t synthio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_synthio) }, { MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) }, { MP_ROM_QSTR(MP_QSTR_Synthesizer), MP_ROM_PTR(&synthio_synthesizer_type) }, { MP_ROM_QSTR(MP_QSTR_from_file), MP_ROM_PTR(&synthio_from_file_obj) }, { MP_ROM_QSTR(MP_QSTR_Envelope), MP_ROM_PTR(&synthio_envelope_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_midi_to_hz), MP_ROM_PTR(&synthio_midi_to_hz_obj) }, }; STATIC MP_DEFINE_CONST_DICT(synthio_module_globals, synthio_module_globals_table); diff --git a/shared-bindings/synthio/__init__.h b/shared-bindings/synthio/__init__.h index 6ea323905a..d3ccc1ce04 100644 --- a/shared-bindings/synthio/__init__.h +++ b/shared-bindings/synthio/__init__.h @@ -33,3 +33,4 @@ extern int16_t shared_bindings_synthio_square_wave[]; extern const mp_obj_namedtuple_type_t synthio_envelope_type_obj; void synthio_synth_envelope_set(synthio_synth_t *synth, mp_obj_t envelope_obj); mp_obj_t synthio_synth_envelope_get(synthio_synth_t *synth); +mp_float_t common_hal_synthio_midi_to_hz_float(mp_int_t note); diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index c7e1096632..8c17dfdeed 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -36,6 +36,12 @@ STATIC const int16_t square_wave[] = {-32768, 32767}; STATIC const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840, 12544, 13290, 14080, 14917, 15804}; // 9th octave +mp_float_t common_hal_synthio_midi_to_hz_float(mp_int_t arg) { + uint8_t octave = arg / 12; + uint16_t base_freq = notes[arg % 12]; + return MICROPY_FLOAT_C_FUN(ldexp)(base_freq, octave - 10); +} + STATIC int16_t convert_time_to_rate(uint32_t sample_rate, mp_obj_t time_in, int16_t difference) { mp_float_t time = mp_obj_get_float(time_in); int num_samples = (int)MICROPY_FLOAT_C_FUN(round)(time * sample_rate);