Skip to content

Commit 30f0d7a

Browse files
committed
add 3_filters videos to all examples but sample-and-hold
1 parent 865e47e commit 30f0d7a

File tree

2 files changed

+64
-33
lines changed

2 files changed

+64
-33
lines changed

3_filters/code_filter_lerp.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@
77
filter_attack_time = 0.1 # some example values to start out with
88
filter_release_time = 0.6 # change them to see how it affects the sound
99
filter_min_freq = 100
10-
filter_max_freq = 4000
10+
filter_max_freq = 2000
1111

12-
# this LFO will automatically run the lerp position from 0 to 1 over a given timea
12+
# this LFO will automatically run the lerp position from 0 to 1 over a given time
1313
lerp_pos = synthio.LFO(once=True, waveform=np.array((0,32767), dtype=np.int16))
1414

1515
# this MathOperation will range from "start_val" to "end_val" over "lerp_time"
1616
# where "start_val" is our starting frequency and "end_val" is our hold frequency)
1717
filter_env = synthio.Math(synthio.MathOperation.CONSTRAINED_LERP,
1818
filter_min_freq, filter_max_freq, lerp_pos)
1919

20-
def set_filter_lerp(fstart, fend, ftime):
20+
def set_filter_env(fstart, fend, ftime):
2121
filter_env.a = fstart
2222
filter_env.b = fend
2323
lerp_pos.rate = 1 / ftime
2424
lerp_pos.retrigger() # must make sure to retrigger the positioner
2525

26-
# nice little saw wave oscillator sounds better than default sqaure
26+
# nice little saw wave oscillator sounds better than default square
2727
wave_saw = np.linspace(32000, -32000, num=128, dtype=np.int16)
2828

2929
while True:
@@ -33,11 +33,11 @@ def set_filter_lerp(fstart, fend, ftime):
3333
note.filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
3434
frequency=filter_env, Q=1.8)
3535
# press the note, e.g. set up the attack lerp vals and retriggering
36-
set_filter_lerp(filter_min_freq, filter_max_freq, filter_attack_time)
36+
set_filter_env(filter_min_freq, filter_max_freq, filter_attack_time)
3737
synth.press(note)
3838
time.sleep(filter_attack_time)
3939

4040
# release the note, e.g. set up the release lerp vals and retriggering
41-
set_filter_lerp(filter_max_freq, filter_min_freq, filter_release_time)
41+
set_filter_env(filter_max_freq, filter_min_freq, filter_release_time)
4242
synth.release(note)
4343
time.sleep(filter_release_time)

README-3-Filters.md

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ while True:
7373
```
7474
> [3_filters/code_filter_tryout.py](./3_filters/code_filter_tryout.py)
7575
76-
```
77-
[ ... TBD video of code_filter_tryout.py TBD ... ]
78-
```
76+
<a href="https://www.youtube.com/watch?v=oo35ITF87BY" target="_blank">
77+
<img alt="code_filter_tryout demo" width=640 height=360
78+
src="https://img.youtube.com/vi/oo35ITF87BY/maxresdefault.jpg"></a>
79+
80+
[youtube video](https://www.youtube.com/watch?v=oo35ITF87BY)
81+
7982

8083
## Changing filter parameters with Python
8184

@@ -114,9 +117,11 @@ while True:
114117
```
115118
> [3_filters/code_filter_handmod.py](./3_filters/code_filter_handmod.py)
116119
117-
```
118-
[ ... TBD video of code_filter_handmod.py TBD ... ]
119-
```
120+
<a href="https://www.youtube.com/watch?v=ggCszD6noBo" target="_blank">
121+
<img alt="code_filter_handmod demo" width=640 height=360
122+
src="https://img.youtube.com/vi/ggCszD6noBo/maxresdefault.jpg"></a>
123+
124+
[youtube video](https://www.youtube.com/watch?v=ggCszD6noBo)
120125

121126
## Changing filter with knobs
122127

@@ -151,9 +156,11 @@ while True:
151156
```
152157
> [3_filters/code_filter_knobmod.py](./3_filters/code_filter_knobmod.py)
153158
154-
```
155-
[ ... TBD video of code_filter_knobmod.py TBD ... ]
156-
```
159+
<a href="https://www.youtube.com/watch?v=RSFnHbDJWf4" target="_blank">
160+
<img alt="code_filter_knobmod demo" width=640 height=360
161+
src="https://img.youtube.com/vi/RSFnHbDJWf4/maxresdefault.jpg"></a>
162+
163+
[youtube video](https://www.youtube.com/watch?v=RSFnHbDJWf4)
157164

158165

159166
## Changing filter with LFO
@@ -196,9 +203,11 @@ while True:
196203
```
197204
> [3_filters/code_filter_lfomod.py](./3_filters/code_filter_lfomod.py)
198205
199-
```
200-
[ ... TBD video of code_filter_lfomod.py TBD ... ]
201-
```
206+
<a href="https://www.youtube.com/watch?v=Ez8TSuOGduc" target="_blank">
207+
<img alt="code_filter_lfomod demo" width=640 height=360
208+
src="https://img.youtube.com/vi/Ez8TSuOGduc/maxresdefault.jpg"></a>
209+
210+
[youtube video](https://www.youtube.com/watch?v=Ez8TSuOGduc)
202211

203212
## Creating filter envelope with LFOs
204213

@@ -258,9 +267,11 @@ while True:
258267
```
259268
> [3_filters/code_filter_lfoenv.py](./3_filters/code_filter_lfoenv.py)
260269
261-
```
262-
[ ... TBD video of code_filter_lfoenv.py TBD ... ]
263-
```
270+
<a href="https://www.youtube.com/watch?v=KoIuInQ0yR8" target="_blank">
271+
<img alt="code_filter_lfoenv demo" width=640 height=360
272+
src="https://img.youtube.com/vi/KoIuInQ0yR8/maxresdefault.jpg"></a>
273+
274+
[youtube video](https://www.youtube.com/watch?v=KoIuInQ0yR8)
264275

265276
## Creating filter envelope with lerp LFOs
266277

@@ -269,7 +280,23 @@ trick for a bend-in pitch envelope using `MathOperation.CONSTRAINED_LERP` can
269280
be used to make an AHR filter envelope.
270281

271282
The benefit of this technique is the same object is used for `note.frequency.filter`,
272-
no reassignment needed.
283+
no reassignment needed. So it's more efficient (for CircuitPython)
284+
and easier to think about (for us).
285+
286+
Finally we have a pretty usable AHR-like filter envelope in `synthio`.
287+
All it took was a one-shot `synthio.LFO` controlling a `synthio.MathOperation`
288+
CONSTRAINED_LERP that we retrigger on both `synth.press()` and `synth.release()`!
289+
Yes, okay, actually this is a lot of components we have to hook together, but
290+
the semi-modular nature of `synthio` means we have a lot of power to hook things
291+
up differently to create other kinds of sounds.
292+
293+
In the example below, the four main parameters of the filter envelope are brought
294+
out as variables. Try changing them to see how it affects the sound. The main
295+
`while`-loop triggers notes chosen by knobA and makes sure to sleep long enough
296+
between `synth.press()` and `synth.release()` so you can hear the filter attack.
297+
In the demo video, you can see me editing some of these values and reloading.
298+
299+
It's starting to sound like a real synth!
273300

274301
```py
275302
# 3_filters/code_filter_lerp.py
@@ -281,23 +308,23 @@ from synth_setup import synth, knobA
281308
filter_attack_time = 0.1 # some example values to start out with
282309
filter_release_time = 0.6 # change them to see how it affects the sound
283310
filter_min_freq = 100
284-
filter_max_freq = 4000
311+
filter_max_freq = 2000
285312

286-
# this LFO will automatically run the lerp position from 0 to 1 over a given timea
313+
# this LFO will automatically run the lerp position from 0 to 1 over a given time
287314
lerp_pos = synthio.LFO(once=True, waveform=np.array((0,32767), dtype=np.int16))
288315

289316
# this MathOperation will range from "start_val" to "end_val" over "lerp_time"
290317
# where "start_val" is our starting frequency and "end_val" is our hold frequency)
291318
filter_env = synthio.Math(synthio.MathOperation.CONSTRAINED_LERP,
292319
filter_min_freq, filter_max_freq, lerp_pos)
293320

294-
def set_filter_lerp(fstart, fend, ftime):
321+
def set_filter_env(fstart, fend, ftime):
295322
filter_env.a = fstart
296323
filter_env.b = fend
297324
lerp_pos.rate = 1 / ftime
298325
lerp_pos.retrigger() # must make sure to retrigger the positioner
299326

300-
# nice little saw wave oscillator sounds better than default sqaure
327+
# nice little saw wave oscillator sounds better than default square
301328
wave_saw = np.linspace(32000, -32000, num=128, dtype=np.int16)
302329

303330
while True:
@@ -307,19 +334,23 @@ while True:
307334
note.filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
308335
frequency=filter_env, Q=1.8)
309336
# press the note, e.g. set up the attack lerp vals and retriggering
310-
set_filter_lerp(filter_min_freq, filter_max_freq, filter_attack_time)
337+
set_filter_env(filter_min_freq, filter_max_freq, filter_attack_time)
311338
synth.press(note)
312339
time.sleep(filter_attack_time)
313340

314341
# release the note, e.g. set up the release lerp vals and retriggering
315-
set_filter_lerp(filter_max_freq, filter_min_freq, filter_release_time)
342+
set_filter_env(filter_max_freq, filter_min_freq, filter_release_time)
316343
synth.release(note)
317344
time.sleep(filter_release_time)
318345
```
346+
> [3_filters/code_filter_lfoenv.py](./3_filters/code_filter_lerp.py)
347+
348+
<a href="https://www.youtube.com/watch?v=VubIJVZqy8E" target="_blank">
349+
<img alt="code_filter_lerp demo" width=640 height=360
350+
src="https://img.youtube.com/vi/VubIJVZqy8E/maxresdefault.jpg"></a>
351+
352+
[youtube video](https://www.youtube.com/watch?v=VubIJVZqy8E )
319353

320-
```
321-
[ ... TBD video of code_filter_lerp.py TBD ... ]
322-
```
323354

324355
## Fun with filters: sample & hold filter envelope
325356

@@ -365,6 +396,6 @@ while True:
365396

366397
## Next steps
367398

368-
Filters are a key way to sculpt a sound, but in `synthio` we have an even
369-
more powerful technique for sound sculpting:
399+
Filters are a key way to sculpt a sound, and we can do a lot now.
400+
But in `synthio` we have an even more powerful technique for sound sculpting:
370401
[Oscillators and Wavetables](README-4-Oscillators-Wavetables.md).

0 commit comments

Comments
 (0)