Skip to content

Commit 9e878f7

Browse files
committed
synthio: Calculate LFO.value at construction
Originally, the only (non-debug) way to make an LFO calculate its value was to associate it with a playing synthesizer. This posed a problem for LFOs that had "power on values" other than 0, and where the value was used other than to internally drive a note property. Now, an initial, possibly non-zero value is calculated at object construction time: ```py >>> l = synthio.LFO(offset = 1) >>> l.value 1.0 ``` Note that this happens just once at construction; it does not happen when updating LFO properties: ```py >>> l.offset = 2 >>> l.value 1.0 ```
1 parent 781c577 commit 9e878f7

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

shared-bindings/synthio/LFO.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ STATIC const uint16_t triangle[] = {0, 32767, 0, -32767};
6060
//| should be considered an implementation detail, though it affects how LFOs
6161
//| behave for instance when used to implement an integrator (``l.offset = l``).
6262
//|
63-
//| An LFO's output, which is reflected in its `value` property, is not
64-
//| updated in any other way than when its associated synthesizer updates it.
65-
//| For instance, if an LFO is created with ``offset=1``, its `value` will still
66-
//| be ``0`` until it is updated by its associated synthesizer. Similarly, merely
67-
//| updating its properties does not update its value property.
63+
//| An LFO's ``value`` property is computed once when it is constructed, and then
64+
//| when its associated synthesizer updates it.
65+
//|
66+
//| This means that for instance an LFO **created** with ``offset=1`` has ```value==1``
67+
//| immediately, but **updating** the ``offset`` property alone does not
68+
//| change ``value``; it only updates through an association with an active synthesizer.
6869
//|
6970
//| The interpolation of the waveform is necessarily different depending on the
7071
//| ``once`` property. Consider a LFO with ``waveform=np.array([0, 100],
@@ -120,11 +121,17 @@ STATIC mp_obj_t synthio_lfo_make_new(const mp_obj_type_t *type_in, size_t n_args
120121
synthio_synth_parse_waveform(&self->waveform_bufinfo, args[ARG_waveform].u_obj);
121122
}
122123
self->waveform_obj = args[ARG_waveform].u_obj;
123-
self->base.last_tick = synthio_global_tick;
124124

125125
mp_obj_t result = MP_OBJ_FROM_PTR(self);
126126
properties_construct_helper(result, lfo_properties + 1, args + 1, MP_ARRAY_SIZE(lfo_properties) - 1);
127127

128+
// Force computation of the LFO's initial output
129+
synthio_global_rate_scale = 0;
130+
self->base.last_tick = synthio_global_tick - 1;
131+
synthio_block_slot_t slot;
132+
synthio_block_assign_slot(MP_OBJ_FROM_PTR(result), &slot, MP_QSTR_self);
133+
(void)synthio_block_slot_get(&slot);
134+
128135
return result;
129136
};
130137

tests/circuitpython/synthlfo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@
1717
lfos[2].rate = lfos[1]
1818
lfos[2].offset = lfos[0]
1919

20+
print("Initial values", *(l.value for l in lfos))
21+
2022
for i in range(100):
2123
print(i * 256 / 48000, *list(lfo_tick(*lfos)) + [l.phase for l in lfos])

tests/circuitpython/synthlfo.py.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
Initial values 0.0 1.99993896484375 0.0 0.999969482421875 0.999969482421875
12
0.0 0.02133268229166667 1.973273111979167 0.06342789066420661 0.999969482421875 0.9466377766927083 0.02133333333333333 0.01333333333333333 0.01052412326388889 0.02666666666666667 0.02666666666666667
23
0.005333333333333333 0.04266536458333333 1.946607259114583 0.1262869271612167 0.999969482421875 0.8933060709635416 0.04266666666666667 0.02666666666666667 0.02090602864583333 0.05333333333333333 0.05333333333333333
34
0.01066666666666667 0.06399804687500001 1.91994140625 0.1885771094910304 0.999969482421875 0.8399743652343751 0.064 0.03999999999999999 0.03114571614583333 0.07999999999999998 0.07999999999999998

0 commit comments

Comments
 (0)