Skip to content

Commit 55db6b7

Browse files
committed
Added SYNTHIO_WAVEFORM_SIZE definition, renamed 'loop_...' to 'waveform_loop_...', added 'ring_waveform_loop_...` parameters, and updated docstrings.
1 parent 785ef5a commit 55db6b7

File tree

6 files changed

+131
-54
lines changed

6 files changed

+131
-54
lines changed

shared-bindings/synthio/Note.c

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ static const mp_arg_t note_properties[] = {
4040
{ MP_QSTR_amplitude, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } },
4141
{ MP_QSTR_bend, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } },
4242
{ MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
43+
{ MP_QSTR_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
44+
{ MP_QSTR_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
4345
{ MP_QSTR_envelope, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
4446
{ MP_QSTR_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
4547
{ MP_QSTR_ring_frequency, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
4648
{ MP_QSTR_ring_bend, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
4749
{ MP_QSTR_ring_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
48-
{ MP_QSTR_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
49-
{ MP_QSTR_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
50+
{ MP_QSTR_ring_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
51+
{ MP_QSTR_ring_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } },
5052
};
5153
//| class Note:
5254
//| def __init__(
@@ -55,15 +57,17 @@ static const mp_arg_t note_properties[] = {
5557
//| frequency: float,
5658
//| panning: BlockInput = 0.0,
5759
//| waveform: Optional[ReadableBuffer] = None,
60+
//| waveform_loop_start: int = 0,
61+
//| waveform_loop_end: int = 0,
5862
//| envelope: Optional[Envelope] = None,
5963
//| amplitude: BlockInput = 0.0,
6064
//| bend: BlockInput = 0.0,
6165
//| filter: Optional[Biquad] = None,
6266
//| ring_frequency: float = 0.0,
6367
//| ring_bend: float = 0.0,
6468
//| ring_waveform: Optional[ReadableBuffer] = 0.0,
65-
//| loop_start: int = 0,
66-
//| loop_end: int = 0,
69+
//| ring_waveform_loop_start: int = 0,
70+
//| ring_waveform_loop_end: int = 0,
6771
//| ) -> None:
6872
//| """Construct a Note object, with a frequency in Hz, and optional panning, waveform, envelope, tremolo (volume change) and bend (frequency change).
6973
//|
@@ -214,6 +218,43 @@ MP_PROPERTY_GETSET(synthio_note_waveform_obj,
214218
(mp_obj_t)&synthio_note_get_waveform_obj,
215219
(mp_obj_t)&synthio_note_set_waveform_obj);
216220

221+
//| waveform_loop_start: int
222+
//| """The index of where to begin looping waveform data. Must be greater than or equal to 0 and less than the total size of the waveform data."""
223+
STATIC mp_obj_t synthio_note_get_waveform_loop_start(mp_obj_t self_in) {
224+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
225+
return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_start(self));
226+
}
227+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_start_obj, synthio_note_get_waveform_loop_start);
228+
229+
STATIC mp_obj_t synthio_note_set_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) {
230+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
231+
common_hal_synthio_note_set_waveform_loop_start(self, mp_obj_get_int(arg));
232+
return mp_const_none;
233+
}
234+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_start_obj, synthio_note_set_waveform_loop_start);
235+
MP_PROPERTY_GETSET(synthio_note_waveform_loop_start_obj,
236+
(mp_obj_t)&synthio_note_get_waveform_loop_start_obj,
237+
(mp_obj_t)&synthio_note_set_waveform_loop_start_obj);
238+
239+
//| waveform_loop_end: int
240+
//| """The index of where to end looping waveform data. Must be greater than 0 or ``waveform_loop_start`` and less than or equal to the total size of the waveform data. If the value of the index does not match these parameters, the loop will occur at the end of the waveform."""
241+
//|
242+
STATIC mp_obj_t synthio_note_get_waveform_loop_end(mp_obj_t self_in) {
243+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
244+
return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_end(self));
245+
}
246+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_end_obj, synthio_note_get_waveform_loop_end);
247+
248+
STATIC mp_obj_t synthio_note_set_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) {
249+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
250+
common_hal_synthio_note_set_waveform_loop_end(self, mp_obj_get_int(arg));
251+
return mp_const_none;
252+
}
253+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_end_obj, synthio_note_set_waveform_loop_end);
254+
MP_PROPERTY_GETSET(synthio_note_waveform_loop_end_obj,
255+
(mp_obj_t)&synthio_note_get_waveform_loop_end_obj,
256+
(mp_obj_t)&synthio_note_set_waveform_loop_end_obj);
257+
217258

218259
//| envelope: Envelope
219260
//| """The envelope of this note"""
@@ -300,42 +341,42 @@ MP_PROPERTY_GETSET(synthio_note_ring_waveform_obj,
300341
(mp_obj_t)&synthio_note_get_ring_waveform_obj,
301342
(mp_obj_t)&synthio_note_set_ring_waveform_obj);
302343

303-
//| loop_start: int
304-
//| """The index of where to begin looping waveform data. Must be greater than 0 and less than the total size of the waveform data."""
305-
STATIC mp_obj_t synthio_note_get_loop_start(mp_obj_t self_in) {
344+
//| ring_waveform_loop_start: int
345+
//| """The index of where to begin looping waveform data. Must be greater than or equal to 0 and less than the total size of the waveform data."""
346+
STATIC mp_obj_t synthio_note_get_ring_waveform_loop_start(mp_obj_t self_in) {
306347
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
307-
return mp_obj_new_int(common_hal_synthio_note_get_loop_start(self));
348+
return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_start(self));
308349
}
309-
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_loop_start_obj, synthio_note_get_loop_start);
350+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_start_obj, synthio_note_get_ring_waveform_loop_start);
310351

311-
STATIC mp_obj_t synthio_note_set_loop_start(mp_obj_t self_in, mp_obj_t arg) {
352+
STATIC mp_obj_t synthio_note_set_ring_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) {
312353
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
313-
common_hal_synthio_note_set_loop_start(self, mp_obj_get_int(arg));
354+
common_hal_synthio_note_set_ring_waveform_loop_start(self, mp_obj_get_int(arg));
314355
return mp_const_none;
315356
}
316-
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_loop_start_obj, synthio_note_set_loop_start);
317-
MP_PROPERTY_GETSET(synthio_note_loop_start_obj,
318-
(mp_obj_t)&synthio_note_get_loop_start_obj,
319-
(mp_obj_t)&synthio_note_set_loop_start_obj);
357+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_start_obj, synthio_note_set_ring_waveform_loop_start);
358+
MP_PROPERTY_GETSET(synthio_note_ring_waveform_loop_start_obj,
359+
(mp_obj_t)&synthio_note_get_ring_waveform_loop_start_obj,
360+
(mp_obj_t)&synthio_note_set_ring_waveform_loop_start_obj);
320361

321-
//| loop_end: int
322-
//| """The index of where to end looping waveform data. Must be greater than 0 or ``loop_start`` and less than the total size of the waveform data."""
362+
//| ring_waveform_loop_end: int
363+
//| """The index of where to end looping waveform data. Must be greater than 0 or ``waveform_loop_start`` and less than or equal to the total size of the waveform data. If the value of the index does not match these parameters, the loop will occur at the end of the waveform."""
323364
//|
324-
STATIC mp_obj_t synthio_note_get_loop_end(mp_obj_t self_in) {
365+
STATIC mp_obj_t synthio_note_get_ring_waveform_loop_end(mp_obj_t self_in) {
325366
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
326-
return mp_obj_new_int(common_hal_synthio_note_get_loop_end(self));
367+
return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_end(self));
327368
}
328-
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_loop_end_obj, synthio_note_get_loop_end);
369+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_end_obj, synthio_note_get_ring_waveform_loop_end);
329370

330-
STATIC mp_obj_t synthio_note_set_loop_end(mp_obj_t self_in, mp_obj_t arg) {
371+
STATIC mp_obj_t synthio_note_set_ring_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) {
331372
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
332-
common_hal_synthio_note_set_loop_end(self, mp_obj_get_int(arg));
373+
common_hal_synthio_note_set_ring_waveform_loop_end(self, mp_obj_get_int(arg));
333374
return mp_const_none;
334375
}
335-
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_loop_end_obj, synthio_note_set_loop_end);
336-
MP_PROPERTY_GETSET(synthio_note_loop_end_obj,
337-
(mp_obj_t)&synthio_note_get_loop_end_obj,
338-
(mp_obj_t)&synthio_note_set_loop_end_obj);
376+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_end_obj, synthio_note_set_ring_waveform_loop_end);
377+
MP_PROPERTY_GETSET(synthio_note_ring_waveform_loop_end_obj,
378+
(mp_obj_t)&synthio_note_get_ring_waveform_loop_end_obj,
379+
(mp_obj_t)&synthio_note_set_ring_waveform_loop_end_obj);
339380

340381

341382

@@ -349,14 +390,16 @@ STATIC const mp_rom_map_elem_t synthio_note_locals_dict_table[] = {
349390
{ MP_ROM_QSTR(MP_QSTR_filter), MP_ROM_PTR(&synthio_note_filter_obj) },
350391
{ MP_ROM_QSTR(MP_QSTR_panning), MP_ROM_PTR(&synthio_note_panning_obj) },
351392
{ MP_ROM_QSTR(MP_QSTR_waveform), MP_ROM_PTR(&synthio_note_waveform_obj) },
393+
{ MP_ROM_QSTR(MP_QSTR_waveform_loop_start), MP_ROM_PTR(&synthio_note_waveform_loop_start_obj) },
394+
{ MP_ROM_QSTR(MP_QSTR_waveform_loop_end), MP_ROM_PTR(&synthio_note_waveform_loop_end_obj) },
352395
{ MP_ROM_QSTR(MP_QSTR_envelope), MP_ROM_PTR(&synthio_note_envelope_obj) },
353396
{ MP_ROM_QSTR(MP_QSTR_amplitude), MP_ROM_PTR(&synthio_note_amplitude_obj) },
354397
{ MP_ROM_QSTR(MP_QSTR_bend), MP_ROM_PTR(&synthio_note_bend_obj) },
355398
{ MP_ROM_QSTR(MP_QSTR_ring_frequency), MP_ROM_PTR(&synthio_note_ring_frequency_obj) },
356399
{ MP_ROM_QSTR(MP_QSTR_ring_bend), MP_ROM_PTR(&synthio_note_ring_bend_obj) },
357400
{ MP_ROM_QSTR(MP_QSTR_ring_waveform), MP_ROM_PTR(&synthio_note_ring_waveform_obj) },
358-
{ MP_ROM_QSTR(MP_QSTR_loop_start), MP_ROM_PTR(&synthio_note_loop_start_obj) },
359-
{ MP_ROM_QSTR(MP_QSTR_loop_end), MP_ROM_PTR(&synthio_note_loop_end_obj) },
401+
{ MP_ROM_QSTR(MP_QSTR_ring_waveform_loop_start), MP_ROM_PTR(&synthio_note_ring_waveform_loop_start_obj) },
402+
{ MP_ROM_QSTR(MP_QSTR_ring_waveform_loop_end), MP_ROM_PTR(&synthio_note_ring_waveform_loop_end_obj) },
360403
};
361404
STATIC MP_DEFINE_CONST_DICT(synthio_note_locals_dict, synthio_note_locals_dict_table);
362405

shared-bindings/synthio/Note.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ void common_hal_synthio_note_set_bend(synthio_note_obj_t *self, mp_obj_t value);
2424
mp_obj_t common_hal_synthio_note_get_waveform_obj(synthio_note_obj_t *self);
2525
void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t value);
2626

27+
mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self);
28+
void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in);
29+
30+
mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self);
31+
void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in);
32+
2733
mp_float_t common_hal_synthio_note_get_ring_frequency(synthio_note_obj_t *self);
2834
void common_hal_synthio_note_set_ring_frequency(synthio_note_obj_t *self, mp_float_t value);
2935

@@ -33,11 +39,11 @@ void common_hal_synthio_note_set_ring_bend(synthio_note_obj_t *self, mp_obj_t va
3339
mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self);
3440
void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_t value);
3541

36-
mp_obj_t common_hal_synthio_note_get_envelope_obj(synthio_note_obj_t *self);
37-
void common_hal_synthio_note_set_envelope(synthio_note_obj_t *self, mp_obj_t value);
42+
mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self);
43+
void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in);
3844

39-
mp_int_t common_hal_synthio_note_get_loop_start(synthio_note_obj_t *self);
40-
void common_hal_synthio_note_set_loop_start(synthio_note_obj_t *self, mp_int_t value_in);
45+
mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self);
46+
void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in);
4147

42-
mp_int_t common_hal_synthio_note_get_loop_end(synthio_note_obj_t *self);
43-
void common_hal_synthio_note_set_loop_end(synthio_note_obj_t *self, mp_int_t value_in);
48+
mp_obj_t common_hal_synthio_note_get_envelope_obj(synthio_note_obj_t *self);
49+
void common_hal_synthio_note_set_envelope(synthio_note_obj_t *self, mp_obj_t value);

shared-bindings/synthio/__init__.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "py/objnamedtuple.h"
3030
#include "py/enum.h"
3131

32+
#define SYNTHIO_WAVEFORM_SIZE 16384
33+
3234
typedef enum {
3335
SYNTHIO_ENVELOPE_STATE_ATTACK, SYNTHIO_ENVELOPE_STATE_DECAY,
3436
SYNTHIO_ENVELOPE_STATE_SUSTAIN, SYNTHIO_ENVELOPE_STATE_RELEASE

shared-module/synthio/Note.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,24 @@ void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t wav
120120
self->waveform_obj = waveform_in;
121121
}
122122

123+
mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self) {
124+
return self->waveform_loop_start;
125+
}
126+
127+
void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) {
128+
mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_waveform_loop_start);
129+
self->waveform_loop_start = val;
130+
}
131+
132+
mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self) {
133+
return self->waveform_loop_end;
134+
}
135+
136+
void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) {
137+
mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_waveform_loop_end);
138+
self->waveform_loop_end = val;
139+
}
140+
123141
mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self) {
124142
return self->ring_waveform_obj;
125143
}
@@ -135,22 +153,22 @@ void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_
135153
self->ring_waveform_obj = ring_waveform_in;
136154
}
137155

138-
mp_int_t common_hal_synthio_note_get_loop_start(synthio_note_obj_t *self) {
139-
return self->loop_start;
156+
mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self) {
157+
return self->ring_waveform_loop_start;
140158
}
141159

142-
void common_hal_synthio_note_set_loop_start(synthio_note_obj_t *self, mp_int_t value_in) {
143-
mp_int_t val = mp_arg_validate_int_range(value_in, 0, 32767, MP_QSTR_loop_start);
144-
self->loop_start = val;
160+
void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) {
161+
mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_ring_waveform_loop_start);
162+
self->ring_waveform_loop_start = val;
145163
}
146164

147-
mp_int_t common_hal_synthio_note_get_loop_end(synthio_note_obj_t *self) {
148-
return self->loop_end;
165+
mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self) {
166+
return self->ring_waveform_loop_end;
149167
}
150168

151-
void common_hal_synthio_note_set_loop_end(synthio_note_obj_t *self, mp_int_t value_in) {
152-
mp_int_t val = mp_arg_validate_int_range(value_in, 0, 32767, MP_QSTR_loop_end);
153-
self->loop_end = val;
169+
void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) {
170+
mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_ring_waveform_loop_end);
171+
self->ring_waveform_loop_end = val;
154172
}
155173

156174
void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate) {

shared-module/synthio/Note.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ typedef struct synthio_note_obj {
4848
int32_t ring_frequency_scaled, ring_frequency_bent;
4949

5050
mp_buffer_info_t waveform_buf;
51+
uint32_t waveform_loop_start, waveform_loop_end;
5152
mp_buffer_info_t ring_waveform_buf;
53+
uint32_t ring_waveform_loop_start, ring_waveform_loop_end;
5254
synthio_envelope_definition_t envelope_def;
53-
54-
uint32_t loop_start, loop_end;
5555
} synthio_note_obj_t;
5656

5757
void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate);

shared-module/synthio/__init__.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
185185

186186
uint32_t ring_dds_rate = 0;
187187
const int16_t *ring_waveform = NULL;
188+
uint32_t ring_waveform_start = 0;
188189
uint32_t ring_waveform_length = 0;
189190

190191
if (mp_obj_is_small_int(note_obj)) {
@@ -203,18 +204,24 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
203204
if (note->waveform_buf.buf) {
204205
waveform = note->waveform_buf.buf;
205206
waveform_length = note->waveform_buf.len;
206-
if (note->loop_start > 0 && note->loop_start < waveform_length) {
207-
waveform_start = note->loop_start;
207+
if (note->waveform_loop_start > 0 && note->waveform_loop_start < waveform_length) {
208+
waveform_start = note->waveform_loop_start;
208209
}
209-
if (note->loop_end > waveform_start && note->loop_end < waveform_length) {
210-
waveform_length = note->loop_end;
210+
if (note->waveform_loop_end > waveform_start && note->waveform_loop_end < waveform_length) {
211+
waveform_length = note->waveform_loop_end;
211212
}
212213
}
213214
dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)frequency_scaled * (waveform_length - waveform_start), sample_rate);
214215
if (note->ring_frequency_scaled != 0 && note->ring_waveform_buf.buf) {
215216
ring_waveform = note->ring_waveform_buf.buf;
216217
ring_waveform_length = note->ring_waveform_buf.len;
217-
ring_dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)note->ring_frequency_bent * ring_waveform_length, sample_rate);
218+
if (note->ring_waveform_loop_start > 0 && note->ring_waveform_loop_start < ring_waveform_length) {
219+
ring_waveform_start = note->waveform_loop_start;
220+
}
221+
if (note->ring_waveform_loop_end > ring_waveform_start && note->ring_waveform_loop_end < ring_waveform_length) {
222+
ring_waveform_length = note->ring_waveform_loop_end;
223+
}
224+
ring_dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)note->ring_frequency_bent * (ring_waveform_length - ring_waveform_start), sample_rate);
218225
uint32_t lim = ring_waveform_length << SYNTHIO_FREQUENCY_SHIFT;
219226
if (ring_dds_rate > lim / sizeof(int16_t)) {
220227
ring_dds_rate = 0; // can't ring at that frequency
@@ -257,18 +264,19 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
257264

258265
// now modulate by ring and accumulate
259266
accum = synth->ring_accum[chan];
267+
offset = ring_waveform_start << SYNTHIO_FREQUENCY_SHIFT;
260268
lim = ring_waveform_length << SYNTHIO_FREQUENCY_SHIFT;
261269

262270
// can happen if note waveform gets set mid-note, but the expensive modulo is usually avoided
263271
if (accum > lim) {
264-
accum %= lim;
272+
accum = accum % lim + offset;
265273
}
266274

267275
for (uint16_t i = 0; i < dur; i++) {
268276
accum += ring_dds_rate;
269277
// because dds_rate is low enough, the subtraction is guaranteed to go back into range, no expensive modulo needed
270278
if (accum > lim) {
271-
accum -= lim;
279+
accum = accum - lim + offset;
272280
}
273281
int16_t idx = accum >> SYNTHIO_FREQUENCY_SHIFT;
274282
int16_t wi = (ring_waveform[idx] * out_buffer32[i]) / 32768;
@@ -442,7 +450,7 @@ STATIC void parse_common(mp_buffer_info_t *bufinfo, mp_obj_t o, int16_t what, mp
442450

443451
void synthio_synth_parse_waveform(mp_buffer_info_t *bufinfo_waveform, mp_obj_t waveform_obj) {
444452
*bufinfo_waveform = ((mp_buffer_info_t) { .buf = (void *)square_wave, .len = 2 });
445-
parse_common(bufinfo_waveform, waveform_obj, MP_QSTR_waveform, 16384);
453+
parse_common(bufinfo_waveform, waveform_obj, MP_QSTR_waveform, SYNTHIO_WAVEFORM_SIZE);
446454
}
447455

448456
STATIC int find_channel_with_note(synthio_synth_t *synth, mp_obj_t note) {

0 commit comments

Comments
 (0)