mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-14 07:08:34 +00:00
315 lines
6.5 KiB
Plaintext
315 lines
6.5 KiB
Plaintext
---
|
|
title: Audio effects
|
|
layout: ../../layouts/MainLayout.astro
|
|
---
|
|
|
|
import { MiniRepl } from '../../docs/MiniRepl';
|
|
import { JsDoc } from '../../docs/JsDoc';
|
|
|
|
# Audio Effects
|
|
|
|
Whether you're using a synth or a sample, you can apply any of the following built-in audio effects.
|
|
As you might suspect, the effects can be chained together, and they accept a pattern string as their argument.
|
|
|
|
# Filters
|
|
|
|
Filters are an essential building block of [subtractive synthesis](https://en.wikipedia.org/wiki/Subtractive_synthesis).
|
|
Strudel comes with 3 types of filters:
|
|
|
|
- low-pass filter: low frequencies may _pass_, high frequencies are cut off
|
|
- high-pass filter: high frequencies may _pass_, low frequencies are cut off
|
|
- band-pass filters: only a frequency band may _pass_, low and high frequencies around are cut off
|
|
|
|
Each filter has 2 parameters:
|
|
|
|
- cutoff: the frequency at which the filter starts to work. e.g. a low-pass filter with a cutoff of 1000Hz allows frequencies below 1000Hz to pass.
|
|
- q-value: Controls the resonance of the filter. Higher values sound more aggressive. Also see [Q-Factor](https://en.wikipedia.org/wiki/Q_factor)
|
|
|
|
## lpf
|
|
|
|
<JsDoc client:idle name="lpf" h={0} />
|
|
|
|
## lpq
|
|
|
|
<JsDoc client:idle name="lpq" h={0} />
|
|
|
|
## hpf
|
|
|
|
<JsDoc client:idle name="hpf" h={0} />
|
|
|
|
## hpq
|
|
|
|
<JsDoc client:idle name="hpq" h={0} />
|
|
|
|
## bpf
|
|
|
|
<JsDoc client:idle name="bpf" h={0} />
|
|
|
|
## bpq
|
|
|
|
<JsDoc client:idle name="bpq" h={0} />
|
|
|
|
## ftype
|
|
|
|
<JsDoc client:idle name="ftype" h={0} />
|
|
|
|
## vowel
|
|
|
|
<JsDoc client:idle name="vowel" h={0} />
|
|
|
|
# Amplitude Envelope
|
|
|
|
The amplitude [envelope](<https://en.wikipedia.org/wiki/Envelope_(music)>) controls the dynamic contour of a sound.
|
|
Strudel uses ADSR envelopes, which are probably the most common way to describe an envelope:
|
|
|
|

|
|
|
|
[image link](https://commons.wikimedia.org/wiki/File:ADSR_parameter.svg)
|
|
|
|
## attack
|
|
|
|
<JsDoc client:idle name="attack" h={0} />
|
|
|
|
## decay
|
|
|
|
<JsDoc client:idle name="decay" h={0} />
|
|
|
|
## sustain
|
|
|
|
<JsDoc client:idle name="sustain" h={0} />
|
|
|
|
## release
|
|
|
|
<JsDoc client:idle name="release" h={0} />
|
|
|
|
## adsr
|
|
|
|
<JsDoc client:idle name="adsr" h={0} />
|
|
|
|
# Filter Envelope
|
|
|
|
Each filter can receive an additional filter envelope controlling the cutoff value dynamically. It uses an ADSR envelope similar to the one used for amplitude. There is an additional parameter to control the depth of the filter modulation: `lpenv`|`hpenv`|`bpenv`. This allows you to play subtle or huge filter modulations just the same by only increasing or decreasing the depth.
|
|
|
|
<MiniRepl
|
|
client:idle
|
|
tune={`note("[c eb g <f bb>](3,8,<0 1>)".sub(12))
|
|
.s("<sawtooth>/64")
|
|
.lpf(sine.range(500,3000).slow(16))
|
|
.lpa(0.005)
|
|
.lpd(perlin.range(.02,.2))
|
|
.lps(perlin.range(0,.5).slow(3))
|
|
.lpq(sine.range(2,10).slow(32))
|
|
.release(.5)
|
|
.lpenv(perlin.range(1,8).slow(2))
|
|
.ftype('24db')
|
|
.room(1)
|
|
.juxBy(.5,rev)
|
|
.sometimes(add(note(12)))
|
|
.stack(s("bd*2").bank('RolandTR909'))
|
|
.gain(.5)`}
|
|
/>
|
|
|
|
There is one filter envelope for each filter type and thus one set of envelope filter parameters preceded either by `lp`, `hp` or `bp`:
|
|
|
|
- `lpattack`, `lpdecay`, `lpsustain`, `lprelease`, `lpenv`: filter envelope for the lowpass filter.
|
|
- alternatively: `lpa`, `lpd`, `lps`, `lpr` and `lpe`.
|
|
- `hpattack`, `hpdecay`, `hpsustain`, `hprelease`, `hpenv`: filter envelope for the highpass filter.
|
|
- alternatively: `hpa`, `hpd`, `hps`, `hpr` and `hpe`.
|
|
- `bpattack`, `bpdecay`, `bpsustain`, `bprelease`, `bpenv`: filter envelope for the bandpass filter.
|
|
- alternatively: `bpa`, `bpd`, `bps`, `bpr` and `bpe`.
|
|
|
|
## lpattack
|
|
|
|
<JsDoc client:idle name="lpattack" h={0} />
|
|
|
|
## lpdecay
|
|
|
|
<JsDoc client:idle name="lpdecay" h={0} />
|
|
|
|
## lpsustain
|
|
|
|
<JsDoc client:idle name="lpsustain" h={0} />
|
|
|
|
## lprelease
|
|
|
|
<JsDoc client:idle name="lprelease" h={0} />
|
|
|
|
## lpenv
|
|
|
|
<JsDoc client:idle name="lpenv" h={0} />
|
|
|
|
# Pitch Envelope
|
|
|
|
You can also control the pitch with envelopes!
|
|
Pitch envelopes can breathe life into static sounds:
|
|
|
|
<MiniRepl
|
|
client:idle
|
|
tune={`n("<-4,0 5 2 1>*<2!3 4>")
|
|
.scale("<C F>/8:pentatonic")
|
|
.s("gm_electric_guitar_jazz")
|
|
.penv("<.5 0 7 -2>*2").vib("4:.1")
|
|
.phaser(2).delay(.25).room(.3)
|
|
.size(4).fast(.75)`}
|
|
/>
|
|
|
|
You also create some lovely chiptune-style sounds:
|
|
|
|
<MiniRepl
|
|
client:idle
|
|
tune={`n(run("<4 8>/16")).jux(rev)
|
|
.chord("<C^7 <Db^7 Fm7>>")
|
|
.dict('ireal')
|
|
.voicing().add(note("<0 1>/8"))
|
|
.dec(.1).room(.2)
|
|
.segment("<4 [2 8]>")
|
|
.penv("<0 <2 -2>>").patt(.02)`}
|
|
/>
|
|
|
|
Let's break down all pitch envelope controls:
|
|
|
|
## pattack
|
|
|
|
<JsDoc client:idle name="pattack" h={0} />
|
|
|
|
## pdecay
|
|
|
|
<JsDoc client:idle name="pdecay" h={0} />
|
|
|
|
## prelease
|
|
|
|
<JsDoc client:idle name="prelease" h={0} />
|
|
|
|
## penv
|
|
|
|
<JsDoc client:idle name="penv" h={0} />
|
|
|
|
## pcurve
|
|
|
|
<JsDoc client:idle name="pcurve" h={0} />
|
|
|
|
## panchor
|
|
|
|
<JsDoc client:idle name="panchor" h={0} />
|
|
|
|
# Dynamics
|
|
|
|
## gain
|
|
|
|
<JsDoc client:idle name="gain" h={0} />
|
|
|
|
## velocity
|
|
|
|
<JsDoc client:idle name="velocity" h={0} />
|
|
|
|
## compressor
|
|
|
|
<JsDoc client:idle name="compressor" h={0} />
|
|
|
|
## postgain
|
|
|
|
<JsDoc client:idle name="postgain" h={0} />
|
|
|
|
## xfade
|
|
|
|
<JsDoc client:idle name="xfade" h={0} />
|
|
|
|
# Panning
|
|
|
|
## jux
|
|
|
|
<JsDoc client:idle name="jux" h={0} />
|
|
|
|
## juxBy
|
|
|
|
<JsDoc client:idle name="juxBy" h={0} />
|
|
|
|
## pan
|
|
|
|
<JsDoc client:idle name="pan" h={0} />
|
|
|
|
# Waveshaping
|
|
|
|
## coarse
|
|
|
|
<JsDoc client:idle name="coarse" h={0} />
|
|
|
|
## crush
|
|
|
|
<JsDoc client:idle name="crush" h={0} />
|
|
|
|
## shape
|
|
|
|
<JsDoc client:idle name="shape" h={0} />
|
|
|
|
# Global Effects
|
|
|
|
## Local vs Global Effects
|
|
|
|
While the above listed "local" effects will always create a separate effects chain for each event,
|
|
global effects use the same chain for all events of the same orbit:
|
|
|
|
## orbit
|
|
|
|
<JsDoc client:idle name="orbit" h={0} />
|
|
|
|
## Delay
|
|
|
|
### delay
|
|
|
|
<JsDoc client:idle name="delay" h={0} />
|
|
|
|
### delaytime
|
|
|
|
<JsDoc client:idle name="delaytime" h={0} />
|
|
|
|
### delayfeedback
|
|
|
|
<JsDoc client:idle name="delayfeedback" h={0} />
|
|
|
|
## Reverb
|
|
|
|
### room
|
|
|
|
<JsDoc client:idle name="room" h={0} />
|
|
|
|
### roomsize
|
|
|
|
<JsDoc client:idle name="roomsize" h={0} />
|
|
|
|
### roomfade
|
|
|
|
<JsDoc client:idle name="roomfade" h={0} />
|
|
|
|
### roomlp
|
|
|
|
<JsDoc client:idle name="roomlp" h={0} />
|
|
|
|
### roomdim
|
|
|
|
<JsDoc client:idle name="roomdim" h={0} />
|
|
|
|
### iresponse
|
|
|
|
<JsDoc client:idle name="iresponse" h={0} />
|
|
|
|
Next, we'll look at strudel's support for [Csound](/learn/csound).
|
|
|
|
## Phaser
|
|
|
|
### phaser
|
|
|
|
<JsDoc client:idle name="phaser" h={0} />
|
|
|
|
### phaserdepth
|
|
|
|
<JsDoc client:idle name="phaserdepth" h={0} />
|
|
|
|
### phasercenter
|
|
|
|
<JsDoc client:idle name="phasercenter" h={0} />
|
|
|
|
### phasersweep
|
|
|
|
<JsDoc client:idle name="phasersweep" h={0} />
|