diff --git a/shared-bindings/synthio/__init__.h b/shared-bindings/synthio/__init__.h index d09fab815e..6f3aed0124 100644 --- a/shared-bindings/synthio/__init__.h +++ b/shared-bindings/synthio/__init__.h @@ -30,7 +30,7 @@ #include "py/enum.h" typedef enum synthio_bend_mode_e { - SYNTHIO_BEND_MODE_STATIC, SYNTHIO_BEND_MODE_VIBRATO, SYNTHIO_BEND_MODE_SWEEP + SYNTHIO_BEND_MODE_STATIC, SYNTHIO_BEND_MODE_VIBRATO, SYNTHIO_BEND_MODE_SWEEP, SYNTHIO_BEND_MODE_SWEEP_IN } synthio_bend_mode_t; extern const cp_enum_obj_t bend_mode_VIBRATO_obj; diff --git a/shared-module/synthio/Note.c b/shared-module/synthio/Note.c index 9b72129834..89de8bce16 100644 --- a/shared-module/synthio/Note.c +++ b/shared-module/synthio/Note.c @@ -224,6 +224,8 @@ STATIC int synthio_bend_value(synthio_note_obj_t *self, int16_t dur) { return synthio_lfo_step(&self->bend_state, dur); case SYNTHIO_BEND_MODE_SWEEP: return synthio_sweep_step(&self->bend_state, dur); + case SYNTHIO_BEND_MODE_SWEEP_IN: + return synthio_sweep_in_step(&self->bend_state, dur); default: return 32768; } diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index 2bca3db439..36ca709541 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -480,25 +480,35 @@ void synthio_lfo_set(synthio_lfo_state_t *state, const synthio_lfo_descr_t *desc state->dds = synthio_frequency_convert_float_to_dds(descr->frequency * 65536, sample_rate); } -int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur) { +STATIC int synthio_lfo_step_common(synthio_lfo_state_t *state, uint16_t dur) { uint32_t phase = state->phase; uint16_t whole_phase = phase >> 16; // advance the phase accumulator state->phase = phase + state->dds * dur; - if (state->phase < phase) { + + return whole_phase; +} +STATIC int synthio_lfo_sweep_common(synthio_lfo_state_t *state, uint16_t dur) { + uint16_t whole_phase = synthio_lfo_step_common(state, dur); + if (state->phase < state->dds) { state->phase = 0xffffffff; } + return whole_phase; +} + +int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur) { + uint16_t whole_phase = synthio_lfo_sweep_common(state, dur); + return (state->amplitude_scaled * whole_phase) / 65536 + state->offset_scaled; +} + +int synthio_sweep_in_step(synthio_lfo_state_t *state, uint16_t dur) { + uint16_t whole_phase = 65535 - synthio_lfo_sweep_common(state, dur); return (state->amplitude_scaled * whole_phase) / 65536 + state->offset_scaled; } int synthio_lfo_step(synthio_lfo_state_t *state, uint16_t dur) { - uint32_t phase = state->phase; - uint16_t whole_phase = phase >> 16; - - // advance the phase accumulator - state->phase = phase + state->dds * dur; - + uint16_t whole_phase = synthio_lfo_step_common(state, dur); // create a triangle wave, it's quick and easy int v; if (whole_phase < 16384) { // ramp from 0 to amplitude diff --git a/shared-module/synthio/__init__.h b/shared-module/synthio/__init__.h index 895b0cae5b..c68fb00f97 100644 --- a/shared-module/synthio/__init__.h +++ b/shared-module/synthio/__init__.h @@ -111,3 +111,4 @@ uint32_t synthio_frequency_convert_scaled_to_dds(uint64_t frequency_scaled, int3 void synthio_lfo_set(synthio_lfo_state_t *state, const synthio_lfo_descr_t *descr, uint32_t sample_rate); int synthio_lfo_step(synthio_lfo_state_t *state, uint16_t dur); int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur); +int synthio_sweep_in_step(synthio_lfo_state_t *state, uint16_t dur);