@@ -151,7 +151,12 @@ STATIC uint32_t synthio_synth_sum_envelope(synthio_synth_t *synth) {
151
151
uint32_t result = 0 ;
152
152
for (int chan = 0 ; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS ; chan ++ ) {
153
153
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
+ }
155
160
}
156
161
}
157
162
return result ;
@@ -177,25 +182,38 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t
177
182
178
183
int32_t sample_rate = synth -> sample_rate ;
179
184
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
+ }
180
195
if (total_envelope > 0 ) {
181
196
uint16_t ovl_loudness = 0x7fffffff / MAX (0x8000 , total_envelope );
197
+
182
198
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 ) {
184
201
synth -> accum [chan ] = 0 ;
185
202
continue ;
186
203
}
187
- // adjust loudness by envelope
188
- uint16_t loudness = (ovl_loudness * synth -> envelope_state [chan ].level ) >> 16 ;
189
204
190
205
if (synth -> envelope_state [chan ].level == 0 ) {
191
- // note is truly finished
206
+ // note is truly finished, but we only just noticed
192
207
synth -> span .note_obj [chan ] = SYNTHIO_SILENCE ;
208
+ continue ;
193
209
}
194
210
211
+ // adjust loudness by envelope
212
+ uint16_t loudness = (ovl_loudness * synth -> envelope_state [chan ].level ) >> 16 ;
213
+
195
214
uint32_t dds_rate ;
196
215
const int16_t * waveform = synth -> waveform ;
197
216
uint32_t waveform_length = synth -> waveform_length ;
198
- mp_obj_t note_obj = synth -> span .note_obj [chan ];
199
217
if (mp_obj_is_small_int (note_obj )) {
200
218
uint8_t note = mp_obj_get_int (note_obj );
201
219
uint8_t octave = note / 12 ;
0 commit comments