Skip to content

Commit 4f56b76

Browse files
committed
synthio: slow ramp overall envelope back up
.. and account releasing notes at their sustain level until they're done. this ameliorates the effect where multiple releasing notes don't seem to actually be releasing, but stay at a constant volume.
1 parent a7da245 commit 4f56b76

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

shared-module/synthio/__init__.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ STATIC uint32_t synthio_synth_sum_envelope(synthio_synth_t *synth) {
151151
uint32_t result = 0;
152152
for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) {
153153
if (synth->span.note_obj[chan] != SYNTHIO_SILENCE) {
154-
result += synth->envelope_state[chan].level;
154+
synthio_envelope_state_t *state = &synth->envelope_state[chan];
155+
if (state->state == SYNTHIO_ENVELOPE_STATE_RELEASE) {
156+
result += synth->envelope_definition.sustain_level;
157+
} else {
158+
result += state->level;
159+
}
155160
}
156161
}
157162
return result;
@@ -177,25 +182,38 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t
177182

178183
int32_t sample_rate = synth->sample_rate;
179184
uint32_t total_envelope = synthio_synth_sum_envelope(synth);
185+
if (total_envelope < synth->total_envelope) {
186+
// total envelope is decreasing. Slowly let remaining notes get louder
187+
// the time constant is arbitrary, on the order of 1s at 48kHz
188+
total_envelope = synth->total_envelope = (
189+
total_envelope + synth->total_envelope * 255) / 256;
190+
} else {
191+
// total envelope is steady or increasing, so just store this as
192+
// the high water mark
193+
synth->total_envelope = total_envelope;
194+
}
180195
if (total_envelope > 0) {
181196
uint16_t ovl_loudness = 0x7fffffff / MAX(0x8000, total_envelope);
197+
182198
for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) {
183-
if (synth->span.note_obj[chan] == SYNTHIO_SILENCE) {
199+
mp_obj_t note_obj = synth->span.note_obj[chan];
200+
if (note_obj == SYNTHIO_SILENCE) {
184201
synth->accum[chan] = 0;
185202
continue;
186203
}
187-
// adjust loudness by envelope
188-
uint16_t loudness = (ovl_loudness * synth->envelope_state[chan].level) >> 16;
189204

190205
if (synth->envelope_state[chan].level == 0) {
191-
// note is truly finished
206+
// note is truly finished, but we only just noticed
192207
synth->span.note_obj[chan] = SYNTHIO_SILENCE;
208+
continue;
193209
}
194210

211+
// adjust loudness by envelope
212+
uint16_t loudness = (ovl_loudness * synth->envelope_state[chan].level) >> 16;
213+
195214
uint32_t dds_rate;
196215
const int16_t *waveform = synth->waveform;
197216
uint32_t waveform_length = synth->waveform_length;
198-
mp_obj_t note_obj = synth->span.note_obj[chan];
199217
if (mp_obj_is_small_int(note_obj)) {
200218
uint8_t note = mp_obj_get_int(note_obj);
201219
uint8_t octave = note / 12;

shared-module/synthio/__init__.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef struct {
6262

6363
typedef struct synthio_synth {
6464
uint32_t sample_rate;
65+
uint32_t total_envelope;
6566
int16_t *buffers[2];
6667
const int16_t *waveform;
6768
uint16_t buffer_length;

0 commit comments

Comments
 (0)