Skip to content

Commit 0831eb4

Browse files
committed
show example of changing Envelope mid-Note
1 parent 4206210 commit 0831eb4

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# 2_modulation/code_envelope_change.py
2+
# part of todbot circuitpython synthio tutorial
3+
# 28 Mar 2026 - @todbot / Tod Kurt
4+
import time, random
5+
import synthio
6+
from synth_setup import synth, knobA, knobB
7+
tempo = 3
8+
note_duration = 2
9+
note_on_time = 0
10+
note_off_time = note_duration
11+
midi_note = 48
12+
note = synthio.Note(synthio.midi_to_hz(midi_note))
13+
while True:
14+
amp_env = synthio.Envelope(attack_time = 1 * (knobA.value/65535),
15+
release_time = 1 * (knobB.value/65535))
16+
note.envelope = amp_env # update the envelope
17+
now = time.monotonic()
18+
if now > note_on_time:
19+
note_on_time = now + tempo
20+
note_off_time = now + note_duration
21+
print("note_on: attack/release_time:", amp_env.attack_time, amp_env.release_time)
22+
mynote = synthio.Note(synthio.midi_to_hz(midi_note), envelope=amp_env)
23+
synth.press(note)
24+
25+
if now >= note_off_time:
26+
synth.release(note)
27+
28+
envelope_state, env_value = synth.note_info(note)
29+
if envelope_state is not None and envelope_state == synthio.EnvelopeState.RELEASE:
30+
print("release_time:", amp_env.release_time)
31+
32+
time.sleep(0.1)
33+

README-2-Modulation.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
<!--ts-->
55
* [About Envelopes](#about-envelopes)
6+
* [Envelope Use](#envelope-use)
7+
* [Changing Envelopes](#changing-envelopes)
68
* [About LFOs](#about-lfos)
79
* [LFO scale &amp; offset](#lfo-scale--offset)
810
* [LFO waveform](#lfo-waveform)
@@ -72,6 +74,8 @@ synthio.Envelope(attack_time = 0.1,
7274
sustain_level = 0.8)
7375
```
7476

77+
### Envelope Use
78+
7579
Some examples of amplitude envelopes you might see:
7680
```py
7781
# gentle rise & fall, like a string section
@@ -84,9 +88,12 @@ synth.envelope = synthio.Envelope(attack_time=0, decay_time=0, release_time=0.5,
8488
synth.envelope = synthio.Envelope(attack_time=0, decay_time=0.05, release_time=0, attack_level=1, sustain_level=0)
8589
```
8690

91+
8792
Here's an example of showing how to use an Envelope.
8893
Notice that an Envelope's parameters are read-only once created.
89-
The `attack_time` and `release_time` are the two most common ones used.
94+
Think of Envelope more like a `namedtuple` than an object.
95+
96+
The `attack_time` and `release_time` are the two most common parameters ones used.
9097
Use the knobs to play around with different attack and release times to get different effects:
9198

9299
```py
@@ -117,6 +124,48 @@ while True:
117124
{% include youtube.html id="CAu_C-53MBk" alt="code_envelope demo" %}
118125

119126

127+
### Changing Envelopes
128+
129+
With the Envelope parameters being read-only, you may wonder how to change
130+
a Note's Envelope while it's playing. Thankfully you can reassign to `Note.envelope`
131+
for a playing Note.
132+
133+
This example shows the `note.envelope` property being continuously changed
134+
on a note that is sounding. Change the `release_time` value after the note is
135+
pressed and see how the new value is used when the note is released.
136+
137+
```py
138+
import time, random
139+
import synthio
140+
from synth_setup import synth, knobA, knobB
141+
tempo = 3
142+
note_duration = 2
143+
note_on_time = 0
144+
note_off_time = note_duration
145+
midi_note = 48
146+
note = synthio.Note(synthio.midi_to_hz(midi_note))
147+
while True:
148+
amp_env = synthio.Envelope(attack_time = 1 * (knobA.value/65535),
149+
release_time = 1 * (knobB.value/65535))
150+
note.envelope = amp_env # update the envelope
151+
now = time.monotonic()
152+
if now > note_on_time:
153+
note_on_time = now + tempo
154+
note_off_time = now + note_duration
155+
print("note_on: attack/release_time:", amp_env.attack_time, amp_env.release_time)
156+
mynote = synthio.Note(synthio.midi_to_hz(midi_note), envelope=amp_env)
157+
synth.press(note)
158+
159+
if now >= note_off_time:
160+
synth.release(note)
161+
162+
envelope_state, env_value = synth.note_info(note)
163+
if envelope_state is not None and envelope_state == synthio.EnvelopeState.RELEASE:
164+
print("release_time:", amp_env.release_time)
165+
time.sleep(0.1)
166+
```
167+
> [2_modulation/code_envelope_change.py](./2_modulation/code_envelope_change.py)
168+
120169

121170
## About LFOs
122171

0 commit comments

Comments
 (0)