Skip to content

Commit 3ca111b

Browse files
committed
add video for audio effects demo
1 parent 02fa198 commit 3ca111b

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

6_audio_effects/code_demo.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
# 6_audio_effects/code_demo.py -- show off some audio effects
2+
# part of todbot circuitpython synthio tutorial
3+
# 20 Apr 2025 - @todbot / Tod Kurt
4+
#
25
import time, audiofilters, audiodelays, audiocore, synthio
36
from synth_setup import mixer, BUFFER_SIZE, CHANNEL_COUNT, SAMPLE_RATE
47
cfg = { 'buffer_size': BUFFER_SIZE,
58
'channel_count': CHANNEL_COUNT,
69
'sample_rate': SAMPLE_RATE }
710
effects = (
8-
audiofilters.Filter(**cfg, mix=1.0,
11+
audiofilters.Filter(**cfg, mix=1.0, # mostly no filtering, pass-through
912
filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
1013
frequency=20000, Q=0.8)),
1114
audiofilters.Filter(**cfg, mix=1.0,
1215
filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
1316
frequency=200, Q=1.2)),
14-
audiodelays.Chorus(**cfg, mix = 1.0,
15-
max_delay_ms = 50,
16-
delay_ms = synthio.LFO(rate=0.3, offset=30, scale=15),
17-
voices = 3),
17+
audiodelays.Chorus(**cfg, mix = 0.6,
18+
max_delay_ms = 150, voices = 3,
19+
delay_ms = synthio.LFO(rate=0.6, offset=10, scale=5)),
1820
audiodelays.Echo(**cfg, mix = 0.6,
19-
max_delay_ms = 330,
20-
delay_ms = 330,
21-
decay = 0.6),
21+
max_delay_ms = 330, delay_ms = 330, decay = 0.6),
2222
audiofilters.Distortion(**cfg, mix = 1.0,
2323
mode = audiofilters.DistortionMode.OVERDRIVE,
24-
soft_clip = True,
25-
pre_gain = 30,
26-
post_gain = -20),
24+
soft_clip = True, pre_gain = 40, post_gain = -20),
2725
audiodelays.PitchShift(**cfg, mix=1.0,
28-
semitones = synthio.LFO(rate=1/3.5, scale=6)),
26+
semitones = synthio.LFO(rate=2/3.5, scale=6)),
2927
)
3028

3129
mixer.voice[0].level = 1.0
@@ -35,8 +33,8 @@
3533
while True:
3634
effect = effects[i] # pick a new effect
3735
print(i, effect)
38-
mixer.voice[0].play(effect)
39-
effect.play(mywav, loop=True)
40-
time.sleep(3.5)
41-
#time.sleep(3.5/2)
36+
mixer.voice[0].play(effect) # plug effect into mixer
37+
effect.play(mywav, loop=True) # plug wavfile into effect
38+
time.sleep(3.5) # loop is 3.5/2 seconds long
4239
i = (i+1) % len(effects)
40+

README-6-Audio-Effects.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ In CircuitPython 10+, there are multiple core libraries for audio effects:
2929
- [`audiofreeverb`](https://docs.circuitpython.org/en/latest/shared-bindings/audiofreeverb)
3030
-- Reverb effect
3131

32-
These are not specific to `synthio` and can be used on other sources of audio
33-
like playing WAV files or MP3 files.
32+
Note that these apply to the entire audio output of a `synthio.Synthesizer`,
33+
not on a per-note basis. In fact, these effects are not specific to `synthio`
34+
at all and can be used on other sources of audio like playing WAV files or MP3 files.
35+
This is really cool as we can apply these effects to sample-based instruments
36+
like drum machines or to incoming audio from a microphone.
3437

3538
## Which chips/boards can run audio effects?
3639

@@ -42,7 +45,8 @@ Also note that you must be running CircuitPython version 10+.
4245
## Quick Demo
4346

4447
Since we can use any audio source, let's use the partial Amen Break from before
45-
(but a stereo 44.1k version) and run it through a some various effects to see how it sounds.
48+
(but a stereo 44.1k version) and run it through some various effects to see how
49+
the different effects sound.
4650

4751
```py
4852
# 6_audio_effects/code_demo.py -- show off some audio effects
@@ -52,22 +56,22 @@ cfg = { 'buffer_size': BUFFER_SIZE,
5256
'channel_count': CHANNEL_COUNT,
5357
'sample_rate': SAMPLE_RATE }
5458
effects = (
55-
audiofilters.Filter(**cfg, mix=1.0, # no filtering, just pass-through
59+
audiofilters.Filter(**cfg, mix=1.0, # mostly no filtering, pass-through
5660
filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
5761
frequency=20000, Q=0.8)),
5862
audiofilters.Filter(**cfg, mix=1.0,
5963
filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
6064
frequency=200, Q=1.2)),
65+
audiodelays.Chorus(**cfg, mix = 0.6,
66+
max_delay_ms = 150, voices = 3,
67+
delay_ms = synthio.LFO(rate=0.6, offset=10, scale=5)),
6168
audiodelays.Echo(**cfg, mix = 0.6,
6269
max_delay_ms = 330, delay_ms = 330, decay = 0.6),
63-
audiodelays.Chorus(**cfg, mix = 1.0,
64-
voices = 3, max_delay_ms = 50,
65-
delay_ms = synthio.LFO(rate=0.3, offset=30, scale=15)),
6670
audiofilters.Distortion(**cfg, mix = 1.0,
6771
mode = audiofilters.DistortionMode.OVERDRIVE,
68-
soft_clip = True, pre_gain = 30, post_gain = -20),
72+
soft_clip = True, pre_gain = 40, post_gain = -20),
6973
audiodelays.PitchShift(**cfg, mix=1.0,
70-
semitones = synthio.LFO(rate=1/3.5, scale=6)),
74+
semitones = synthio.LFO(rate=2/3.5, scale=6)),
7175
)
7276

7377
mixer.voice[0].level = 1.0
@@ -76,21 +80,26 @@ i = 0
7680
while True:
7781
effect = effects[i] # pick a new effect
7882
print(i, effect)
79-
mixer.voice[0].play(effect)
80-
effect.play(mywav, loop=True)
81-
time.sleep(3.5)
82-
#time.sleep(3.5/2)
83+
mixer.voice[0].play(effect) # plug effect into mixer
84+
effect.play(mywav, loop=True) # plug wavfile into effect
85+
time.sleep(3.5) # loop is 3.5/2 seconds long
8386
i = (i+1) % len(effects)
8487
```
8588
> [6_audio_effects/code_demo.py](./6_audio_effects/code_demo.py)
8689
87-
> [watch demo video](https://www.youtube.com/watch?v=xxx)
90+
> [watch demo video](https://www.youtube.com/watch?v=nyv7XlQ1d00)
8891
89-
{% include youtube.html id="xxx" alt="code_demo demo" %}
92+
{% include youtube.html id="nyv7XlQ1d00" alt="code_demo demo" %}
9093

9194

9295
## How effects work in CircuitPython
9396

97+
From our experience with `audiomixer.Mixer`, we've seen how the flow of audio
98+
is like a chain: plug the mixer into the audio output, plug the synth into the mixer.
99+
100+
The audio effects work the exact same way. To use an effect, insert it into
101+
the chain where you want the effect to occur. In the above example,
102+
we keep re-plug a new effect in between the mixer and the WaveFile.
94103

95104
## How to chain effects
96105

0 commit comments

Comments
 (0)