Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add synthio.BlockInput support to synthio.Note waveform loop parameters #9788

Merged
merged 7 commits into from
Nov 4, 2024
64 changes: 29 additions & 35 deletions shared-bindings/synthio/Note.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ static const mp_arg_t note_properties[] = {
{ MP_QSTR_amplitude, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } },
{ MP_QSTR_bend, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
{ MP_QSTR_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
{ MP_QSTR_waveform_loop_start, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_waveform_loop_end, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
relic-se marked this conversation as resolved.
Show resolved Hide resolved
{ MP_QSTR_envelope, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
{ MP_QSTR_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
{ MP_QSTR_ring_frequency, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_bend, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_frequency, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_bend, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
{ MP_QSTR_ring_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
{ MP_QSTR_ring_waveform_loop_start, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
{ MP_QSTR_ring_waveform_loop_end, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
};
//| class Note:
//| def __init__(
Expand All @@ -37,17 +37,17 @@ static const mp_arg_t note_properties[] = {
//| frequency: float,
//| panning: BlockInput = 0.0,
//| waveform: Optional[ReadableBuffer] = None,
//| waveform_loop_start: int = 0,
//| waveform_loop_end: int = waveform_max_length,
//| waveform_loop_start: BlockInput = 0,
//| waveform_loop_end: BlockInput = waveform_max_length,
//| envelope: Optional[Envelope] = None,
//| amplitude: BlockInput = 0.0,
//| amplitude: BlockInput = 1.0,
//| bend: BlockInput = 0.0,
//| filter: Optional[Biquad] = None,
//| ring_frequency: float = 0.0,
//| ring_bend: float = 0.0,
//| ring_waveform: Optional[ReadableBuffer] = None,
//| ring_waveform_loop_start: int = 0,
//| ring_waveform_loop_end: int = waveform_max_length,
//| ring_waveform_loop_start: BlockInput = 0,
//| ring_waveform_loop_end: BlockInput = waveform_max_length,
//| ) -> None:
//| """Construct a Note object, with a frequency in Hz, and optional panning, waveform, envelope, tremolo (volume change) and bend (frequency change).
//|
Expand Down Expand Up @@ -198,46 +198,44 @@ MP_PROPERTY_GETSET(synthio_note_waveform_obj,
(mp_obj_t)&synthio_note_get_waveform_obj,
(mp_obj_t)&synthio_note_set_waveform_obj);

//| waveform_loop_start: int


//| waveform_loop_start: BlockInput
//| """The sample index of where to begin looping waveform data.
//|
//| Values outside the range ``0`` to ``waveform_max_length-1`` (inclusive) are rejected with a `ValueError`.
//|
//| Values greater than or equal to the actual waveform length are treated as 0."""
//| The value is limited to the range ``0`` to ``len(waveform)-1`` (inclusive)."""
static mp_obj_t synthio_note_get_waveform_loop_start(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_start(self));
return common_hal_synthio_note_get_waveform_loop_start(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_start_obj, synthio_note_get_waveform_loop_start);

static mp_obj_t synthio_note_set_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_waveform_loop_start(self, mp_obj_get_int(arg));
common_hal_synthio_note_set_waveform_loop_start(self, arg);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_start_obj, synthio_note_set_waveform_loop_start);
MP_PROPERTY_GETSET(synthio_note_waveform_loop_start_obj,
(mp_obj_t)&synthio_note_get_waveform_loop_start_obj,
(mp_obj_t)&synthio_note_set_waveform_loop_start_obj);

//| waveform_loop_end: int
//| waveform_loop_end: BlockInput
//| """The sample index of where to end looping waveform data.
//|
//| Values outside the range ``1`` to ``waveform_max_length`` (inclusive) are rejected with a `ValueError`.
//|
//| If the value is greater than the actual waveform length, or less than or equal to the loop start, the loop will occur at the end of the waveform.
//| The value is limited to the range ``waveform_loop_start+1`` to ``len(waveform)`` (inclusive).
//|
//| Use the `synthio.waveform_max_length` constant to set the loop point at the end of the wave form, no matter its length."""
//|
static mp_obj_t synthio_note_get_waveform_loop_end(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_end(self));
return common_hal_synthio_note_get_waveform_loop_end(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_end_obj, synthio_note_get_waveform_loop_end);

static mp_obj_t synthio_note_set_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_waveform_loop_end(self, mp_obj_get_int(arg));
common_hal_synthio_note_set_waveform_loop_end(self, arg);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_end_obj, synthio_note_set_waveform_loop_end);
Expand Down Expand Up @@ -331,46 +329,42 @@ MP_PROPERTY_GETSET(synthio_note_ring_waveform_obj,
(mp_obj_t)&synthio_note_get_ring_waveform_obj,
(mp_obj_t)&synthio_note_set_ring_waveform_obj);

//| ring_waveform_loop_start: int
//| ring_waveform_loop_start: BlockInput
//| """The sample index of where to begin looping waveform data.
//|
//| Values outside the range ``0`` to ``waveform_max_length-1`` (inclusive) are rejected with a `ValueError`.
//|
//| Values greater than or equal to the actual waveform length are treated as 0."""
//| The value is limited to the range ``0`` to ``len(ring_waveform)-1`` (inclusive)."""
static mp_obj_t synthio_note_get_ring_waveform_loop_start(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_start(self));
return common_hal_synthio_note_get_ring_waveform_loop_start(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_start_obj, synthio_note_get_ring_waveform_loop_start);

static mp_obj_t synthio_note_set_ring_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_ring_waveform_loop_start(self, mp_obj_get_int(arg));
common_hal_synthio_note_set_ring_waveform_loop_start(self, arg);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_start_obj, synthio_note_set_ring_waveform_loop_start);
MP_PROPERTY_GETSET(synthio_note_ring_waveform_loop_start_obj,
(mp_obj_t)&synthio_note_get_ring_waveform_loop_start_obj,
(mp_obj_t)&synthio_note_set_ring_waveform_loop_start_obj);

//| ring_waveform_loop_end: int
//| ring_waveform_loop_end: BlockInput
//| """The sample index of where to end looping waveform data.
//|
//| Values outside the range ``1`` to ``waveform_max_length`` (inclusive) are rejected with a `ValueError`.
//|
//| If the value is greater than the actual waveform length, or less than or equal to the loop start, the loop will occur at the end of the waveform.
//| The value is limited to the range ``ring_waveform_loop_start+1`` to ``len(ring_waveform)`` (inclusive).
//|
//| Use the `synthio.waveform_max_length` constant to set the loop point at the end of the wave form, no matter its length."""
//|
static mp_obj_t synthio_note_get_ring_waveform_loop_end(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_end(self));
return common_hal_synthio_note_get_ring_waveform_loop_end(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_end_obj, synthio_note_get_ring_waveform_loop_end);

static mp_obj_t synthio_note_set_ring_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_ring_waveform_loop_end(self, mp_obj_get_int(arg));
common_hal_synthio_note_set_ring_waveform_loop_end(self, arg);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_end_obj, synthio_note_set_ring_waveform_loop_end);
Expand Down
16 changes: 8 additions & 8 deletions shared-bindings/synthio/Note.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ void common_hal_synthio_note_set_bend(synthio_note_obj_t *self, mp_obj_t value);
mp_obj_t common_hal_synthio_note_get_waveform_obj(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t value);

mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in);
mp_obj_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value);

mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in);
mp_obj_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value);

mp_float_t common_hal_synthio_note_get_ring_frequency(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_frequency(synthio_note_obj_t *self, mp_float_t value);
Expand All @@ -46,11 +46,11 @@ void common_hal_synthio_note_set_ring_bend(synthio_note_obj_t *self, mp_obj_t va
mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_t value);

mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in);
mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value);

mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in);
mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self);
void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value);

mp_obj_t common_hal_synthio_note_get_envelope_obj(synthio_note_obj_t *self);
void common_hal_synthio_note_set_envelope(synthio_note_obj_t *self, mp_obj_t value);
36 changes: 16 additions & 20 deletions shared-module/synthio/Note.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,20 @@ void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t wav
self->waveform_obj = waveform_in;
}

mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self) {
return self->waveform_loop_start;
mp_obj_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self) {
return self->waveform_loop_start.obj;
}

void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) {
mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_waveform_loop_start);
self->waveform_loop_start = val;
void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value_in) {
synthio_block_assign_slot(value_in, &self->waveform_loop_start, MP_QSTR_waveform_loop_start);
}

mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self) {
return self->waveform_loop_end;
mp_obj_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self) {
return self->waveform_loop_end.obj;
}

void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) {
mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_waveform_loop_end);
self->waveform_loop_end = val;
void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value_in) {
synthio_block_assign_slot(value_in, &self->waveform_loop_end, MP_QSTR_waveform_loop_end);
}

mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self) {
Expand All @@ -133,22 +131,20 @@ void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_
self->ring_waveform_obj = ring_waveform_in;
}

mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self) {
return self->ring_waveform_loop_start;
mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self) {
return self->ring_waveform_loop_start.obj;
}

void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) {
mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_ring_waveform_loop_start);
self->ring_waveform_loop_start = val;
void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value_in) {
synthio_block_assign_slot(value_in, &self->ring_waveform_loop_start, MP_QSTR_ring_waveform_loop_start);
}

mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self) {
return self->ring_waveform_loop_end;
mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self) {
return self->ring_waveform_loop_end.obj;
}

void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) {
mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_ring_waveform_loop_end);
self->ring_waveform_loop_end = val;
void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value_in) {
synthio_block_assign_slot(value_in, &self->ring_waveform_loop_end, MP_QSTR_ring_waveform_loop_end);
}

void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate) {
Expand Down
4 changes: 2 additions & 2 deletions shared-module/synthio/Note.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ typedef struct synthio_note_obj {
int32_t ring_frequency_scaled, ring_frequency_bent;

mp_buffer_info_t waveform_buf;
uint32_t waveform_loop_start, waveform_loop_end;
synthio_block_slot_t waveform_loop_start, waveform_loop_end;
mp_buffer_info_t ring_waveform_buf;
uint32_t ring_waveform_loop_start, ring_waveform_loop_end;
synthio_block_slot_t ring_waveform_loop_start, ring_waveform_loop_end;
synthio_envelope_definition_t envelope_def;
} synthio_note_obj_t;

Expand Down
16 changes: 4 additions & 12 deletions shared-module/synthio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,23 +184,15 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
if (note->waveform_buf.buf) {
waveform = note->waveform_buf.buf;
waveform_length = note->waveform_buf.len;
if (note->waveform_loop_start > 0 && note->waveform_loop_start < waveform_length) {
waveform_start = note->waveform_loop_start;
}
if (note->waveform_loop_end > waveform_start && note->waveform_loop_end < waveform_length) {
waveform_length = note->waveform_loop_end;
}
waveform_start = (uint32_t)synthio_block_slot_get_limited(&note->waveform_loop_start, 0, waveform_length - 1);
waveform_length = (uint32_t)synthio_block_slot_get_limited(&note->waveform_loop_end, waveform_start + 1, waveform_length);
}
dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)frequency_scaled * (waveform_length - waveform_start), sample_rate);
if (note->ring_frequency_scaled != 0 && note->ring_waveform_buf.buf) {
ring_waveform = note->ring_waveform_buf.buf;
ring_waveform_length = note->ring_waveform_buf.len;
if (note->ring_waveform_loop_start > 0 && note->ring_waveform_loop_start < ring_waveform_length) {
ring_waveform_start = note->waveform_loop_start;
}
if (note->ring_waveform_loop_end > ring_waveform_start && note->ring_waveform_loop_end < ring_waveform_length) {
ring_waveform_length = note->ring_waveform_loop_end;
}
ring_waveform_start = (uint32_t)synthio_block_slot_get_limited(&note->ring_waveform_loop_start, 0, ring_waveform_length - 1);
ring_waveform_length = (uint32_t)synthio_block_slot_get_limited(&note->ring_waveform_loop_end, ring_waveform_start + 1, ring_waveform_length);
ring_dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)note->ring_frequency_bent * (ring_waveform_length - ring_waveform_start), sample_rate);
uint32_t lim = ring_waveform_length << SYNTHIO_FREQUENCY_SHIFT;
if (ring_dds_rate > lim / sizeof(int16_t)) {
Expand Down
Loading