From 1701552decff4fa50e1f92240d2833f03118339b Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 4 May 2023 07:22:02 -0500 Subject: [PATCH] synthio: make sustain level relative to attack level and re-vamp overall envelope calculation again. Now, if you set a low overall attack level like 0.2 this avoids the "diminishing volume" effect when many notes sound at once. You need simply choose a maximum attack level that is appropriate for the max number of voices that will actually be played. --- shared-bindings/synthio/__init__.c | 8 ++++---- shared-module/synthio/__init__.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index 7478925dcc..5af352b404 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -79,8 +79,8 @@ static const mp_arg_t envelope_properties[] = { //| :param float attack_time: The time in seconds it takes to ramp from 0 volume to attack_volume //| :param float decay_time: The time in seconds it takes to ramp from attack_volume to sustain_volume //| :param float release_time: The time in seconds it takes to ramp from sustain_volume to release_volume. When a note is released before it has reached the sustain phase, the release is done with the same slope indicated by ``release_time`` and ``sustain_level`` -//| :param float attack_level: The relative level, in the range ``0.0`` to ``1.0`` of the peak volume of the attack phase -//| :param float sustain_level: The relative level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase +//| :param float attack_level: The level, in the range ``0.0`` to ``1.0`` of the peak volume of the attack phase +//| :param float sustain_level: The level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase relative to the attack level //| """ //| attack_time: float //| """The time in seconds it takes to ramp from 0 volume to attack_volume""" @@ -92,10 +92,10 @@ static const mp_arg_t envelope_properties[] = { //| """The time in seconds it takes to ramp from sustain_volume to release_volume. When a note is released before it has reached the sustain phase, the release is done with the same slope indicated by ``release_time`` and ``sustain_level``""" //| //| attack_level: float -//| """The relative level, in the range ``0.0`` to ``1.0`` of the peak volume of the attack phase""" +//| """The level, in the range ``0.0`` to ``1.0`` of the peak volume of the attack phase""" //| //| sustain_level: float -//| """The relative level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase""" +//| """The level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase relative to the attack level""" //| STATIC mp_obj_t synthio_envelope_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index 4b32ec3e91..fc9d31f029 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -77,7 +77,7 @@ void synthio_envelope_definition_set(synthio_envelope_definition_t *envelope, mp mp_obj_tuple_get(obj, &len, &fields); envelope->attack_level = (int)(32767 * mp_obj_get_float(fields[3])); - envelope->sustain_level = (int)(32767 * mp_obj_get_float(fields[4])); + envelope->sustain_level = (int)(32767 * mp_obj_get_float(fields[4]) * mp_obj_get_float(fields[3])); envelope->attack_step = convert_time_to_rate( sample_rate, fields[0], envelope->attack_level); @@ -152,10 +152,10 @@ STATIC uint32_t synthio_synth_sum_envelope(synthio_synth_t *synth) { for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) { if (synth->span.note_obj[chan] != SYNTHIO_SILENCE) { synthio_envelope_state_t *state = &synth->envelope_state[chan]; - if (state->state == SYNTHIO_ENVELOPE_STATE_RELEASE) { - result += synth->envelope_definition.sustain_level; - } else { + if (state->state == SYNTHIO_ENVELOPE_STATE_ATTACK) { result += state->level; + } else { + result += synth->envelope_definition.attack_level; } } }