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. 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
lpf
cutoff
Applies the cutoff frequency of the low-pass filter.
- frequency (number|Pattern): audible between 0 and 20000
s("bd sd,hh*3").lpf("<4000 2000 1000 500 200 100>")
lpq
resonance
Controls the low-pass q-value.
- q (number|Pattern): resonance factor between 0 and 50
s("bd sd,hh*4").lpf(2000).lpq("<0 10 20 30>")
hpf
hcutoff
Applies the cutoff frequency of the high-pass filter.
- frequency (number|Pattern): audible between 0 and 20000
s("bd sd,hh*4").hpf("<4000 2000 1000 500 200 100>")
hpq
hresonance
Controls the high-pass q-value.
- q (number|Pattern): resonance factor between 0 and 50
s("bd sd,hh*4").hpf(2000).hpq("<0 10 20 30>")
bpf
bandf
Sets the center frequency of the band-pass filter.
- frequency (number|Pattern): center frequency
s("bd sd,hh*3").bpf("<1000 2000 4000 8000>")
bpq
bandq
Sets the band-pass q-factor (resonance)
- q (number|Pattern): q factor
s("bd sd").bpf(500).bpq("<0 1 2 3>")
vowel
Formant filter to make things sound like vowels.
- vowel (string|Pattern): You can use a e i o u.
note("c2 <eb2 <g2 g1>>").s('sawtooth') .vowel("<a e i <o u>>")
Amplitude Envelope
The amplitude envelope controls the dynamic contour of a sound. Strudel uses ADSR envelopes, which are probably the most common way to describe an envelope:
attack
Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset.
- attack (number|Pattern): time in seconds.
note("c3 e3").attack("<0 .1 .5>")
decay
Amplitude envelope decay time: the time it takes after the attack time to reach the sustain level. Note that the decay is only audible if the sustain value is lower than 1.
- time (number|Pattern): decay time in seconds
note("c3 e3").decay("<.1 .2 .3 .4>").sustain(0)
sustain
Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset.
- gain (number|Pattern): sustain level between 0 and 1
note("c3 e3").decay(.2).sustain("<0 .1 .4 .6 1>")
release
Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero.
- time (number|Pattern): release time in seconds
note("c3 e3 g3 c4").release("<0 .1 .4 .6 1>/2")
Dynamics
gain
Controls the gain by an exponential amount.
- amount (number|Pattern): gain.
s("hh*8").gain(".4!2 1 .4!2 1 .4 1")
velocity
Sets the velocity from 0 to 1. Is multiplied together with gain.
s("hh*8") .gain(".4!2 1 .4!2 1 .4 1") .velocity(".4 1")
Panning
jux
The jux function creates strange stereo effects, by applying a function to a pattern, but only in the right-hand channel.
s("lt ht mt ht hh").jux(rev)
juxBy
juxby
Jux with adjustable stereo width. 0 = mono, 1 = full stereo.
s("lt ht mt ht hh").juxBy("<0 .5 1>/2", rev)
pan
Sets position in stereo.
- pan (number|Pattern): between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel)
s("[bd hh]*2").pan("<.5 1 .5 0>")
Waveshaping
coarse
fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers
- factor (number|Pattern): 1 for original 2 for half, 3 for a third and so on.
s("bd sd,hh*4").coarse("<1 4 8 16 32>")
crush
bit crusher effect.
- depth (number|Pattern): between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction).
s("<bd sd>,hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>")
shape
Wave shaping distortion. CAUTION: it might get loud
- distortion (number|Pattern): between 0 and 1
s("bd sd,hh*4").shape("<0 .2 .4 .6 .8>")
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
An orbit
is a global parameter context for patterns. Patterns with the same orbit will share the same global effects.
- number (number|Pattern):
stack( s("hh*3").delay(.5).delaytime(.25).orbit(1), s("~ sd").delay(.5).delaytime(.125).orbit(2) )
delay
Sets the level of the delay signal.
- level (number|Pattern): between 0 and 1
s("bd").delay("<0 .25 .5 1>")
delaytime
Sets the time of the delay effect.
- seconds (number|Pattern): between 0 and Infinity
s("bd").delay(.25).delaytime("<.125 .25 .5 1>").slow(2)
delayfeedback
Sets the level of the signal that is fed back into the delay. Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it
- feedback (number|Pattern): between 0 and 1
s("bd").delay(.25).delayfeedback("<.25 .5 .75 1>").slow(2)
room
Sets the level of reverb.
- level (number|Pattern): between 0 and 1
s("bd sd").room("<0 .2 .4 .6 .8 1>")
roomsize
size
Sets the room size of the reverb, see room.
- size (number|Pattern): between 0 and 10
s("bd sd").room(.8).roomsize("<0 1 2 4 8>")
Next, we’ll look at strudel’s support for Csound.