Player Effects

Introduction

Effects can be added to a Player in the same way that its attributes are changed; using keyword arguments. Just as with the Player attributes, these can be a single value, or a sequence. This page contains descriptions of the different effects available in FoxDot and how to apply them.

Most effects are applied using a single value, such as pan, but some have a single “parent” and one or more “child” effect. One example is slide, which is the parent, and slidedelay is the child. If the parent effect is set to 0, then the effect is not applied. Child values of 0 are still applied if the parent is nonzero

# Slide effect added
p1 >> pluck(dur=4, slide=1, slidedelay=0.5)
 
# Slide effect not added
p1 >> pluck(dur=4, slide=0, slidedelay=0.5)
 
# Slide effect added, with zero delay
p1 >> pluck(dur=4, slide=1, slidedelay=0)

Sustain

Keywords: sus, blur=1

The keyword argument sus is used to set the “sustain” of a note, which means how long the sound of the note lasts. By default this is the same as the note’s duration (set using the dur keyword) and is a value measured in terms of “beats”. The following code will play a 1-beat note one repeat with a half-beat sustain:

# One beat duration, half-beat duration
p1 >> pluck(dur=1, sus=1/2)

Use blur to create a “legato” effect (a word which means “tied together” in Italian). This is a musical term that refers to how smoothly notes follow on from one another, or blur together. The sus value is multiplied by the current blur value such that the following code doubles the length of every other note’s sustain:

# Doubles the length of every other note
p1 >> pluck(dur=PDur(3,8), blur=[1, 2])

Stereo Panning

Keywords: pan

Panning (in audio) is the distribution of sound across multiple speakers. Currently FoxDot only uses two output channels (for the left and right speaker) but there are plans to expand this for multiple speakers. To change the panning of a sound, use the pan and set the value between -1 (hard left) and 1 (hard right). A pan value of 0 sends the audio signal out of both speakers equally.

# Alternate between left, center, and right
p1 >> pluck(pan = [-1, 0, 1])
 
# Play two notes at the same time, but in different speakers
p1 >> pluck((0, 4), pan=(-1,1))
 
# Gradually move the sound's panning from left to right using a "linvar"
p1 >> pluck([0, 2, 4, 7], dur=1/4, pan=linvar([-1,1],8))

Frequency Modifier

Keywords: fmod

This adds a value to the frequency used to generate a note, but only in one of the channels. For example, starting a player with no instructions will continually play a note on middle C, which is 261.6 Hz, through both speaker channels. Using fmod = 10 will play the note at 261.6 Hz in one channel, and 271.6 Hz in the other. This creates a noticeable “dissonance” or an “atonal” sound because the frequencies are so close together. Using a smaller value, such as 2, creates a sort of flanger effect:

# Simple flanger effect
p1 >> pluck(fmod = 2)
 
# Vary the effect over time
p1 >> pluck(fmod=linvar([-10,10],8), dur=1/4, sus=1)

Vibrato

Keywords: vib, vibdepth = 0.02

Vibrato is a musical term that refers to a continual modulation of pitch i.e. changing over time. You can set the rate of the vibrato of a note by using the vib keyword and the depth (the size of the modulation) of the vibrato by using the vibdepth keyword. The depth defaults to 0.02, which means the vibrato fluctuates between +/- the note’s frequency multiplied by 0.02. You can also think of it as fluctuating between 99% and 101% of the frequency value.

p1 >> pads(dur=4, vib=4)
 
p1 >> pads(dur=4, vib=4, vibdepth=0.1)
 
p1 >> pads(dur=4, vib=4, vibdepth=1)

Slide

Keywords: slide, slidedelay = 0

This is used to change a note’s frequency over time. The frequency “slides” to (1 + n) * freq where n is the value supplied to the slide keyword. For example, a slide value of 1 will slide the frequency to twice its original value (one octave up). A slide value of -1 will slide to a frequency of 0.

By default the slide effect starts immediately after the note begins. To delay the start of the slide, you can use the slidedelay keyword. This should be a value between 0 (the start of the note) and 1 (the end of the note).

# Slide one octave up
p1 >> pluck(dur=4, slide=1)
 
# Slide to 0
p1 >> pluck(dur=4, slide=-1)
 
# Delay the slide effect to start half way through the note
p1 >> pluck(dur=4, slide=0.5, slidedelay=0.5)

Slide from

Keywords: slidefrom, slidedelay = 0

Similar to slide, this effect also changes a note’s frequency over time, but you specify where the slide starts. The frequency “slides” from (1 + n) * freq where n is the value supplied to the slidefrom keyword and finishes at the note’s frequency.

For example, a slidefrom value of 1 will slide the frequency from twice its original value (one octave up). A slidefrom value of -1 will slide from a frequency of 0. By default the slide effect starts immediately after the note begins. To delay the start of the slide, you can use the slidedelay keyword. This should be a value between 0 (the start of the note) and 1 (the end of the note).

# Slide from one octave up
p1 >> pluck(dur=4, slidefrom=1)
 
# Slide from 0
p1 >> pluck(dur=4, slidefrom=-1)
 
# Delay the slide effect to start half way through the note
p1 >> pluck(dur=4, slidefrom=0.5, slidedelay=0.5)

Pitch bend

Keywords: bend, benddelay = 0

Another effect similar to slide, pitch bend changes the frequency of a note over a time but also returns to its original frequency by the end of the note. Other than that it works exactly the same as slide.

# Bends one octave up and back again
p1 >> pluck(dur=4, bend=1)
 
# Bend to 0 and back again
p1 >> pluck(dur=4, bend=-1)
 
# Delay the bend effect to start half way through the note
p1 >> pluck(dur=4, slide=0.5, bend=0.5)

Chop

Keywords: chop

This “chops” the audio signal into “n” parts, where “n” is the value you supply to the keyword argument. It uses the sustain of the note (set using sus) to determine the size of the parts, so you can also combine chop and sus to create interesting effects.

# Chop a sound into 4 parts
p1 >> pluck([0,1,2,3], dur=4, chop=4)
 
# If the duration varies, the sizes of chop will vary too
p1 >> pluck([0,[4,6,7]], dur=PDur(3,8), chop=4)
 
# Changing a single value for "sus" evens out the sizes and creates a nice overlapping echo effect
p1 >> pluck([0,[4,6,7]], dur=PDur(3,8), chop=4, sus=2)

Coarse

Keywords: coarse

This is similar to “chop” but differs in that the audio signal isn’t being “chopped” up, the control rate (the frequency of notes / the playback rate for samples) is. This can be useful in several situations.

The first is when playing samples using the play synth: Using chop essentially only plays half the audio as the other half is being muted by the “chop” effect. Using coarse will essentially pause the sound and resume it after a slight delay. It does this by setting the playback rate to 0 whereas chop would set the amplitude to 0. Listen to the difference by running the code below in FoxDot:

# Using chop
c1 >> play("C", dur=4, chop=16, coarse=0)
 
# Using coarse
c1 >> play("C", dur=4, coarse=16, chop=0)

Another use for coarse would be for when you get “clipping” sounds when using chop. This occurs when an amplitude goes to 0 very quickly and sounds like a tiny “pop”. Run these lines of code in FoxDot and listen to the differences:

b1 >> bass(dur=2, chop=4, coarse=0)
 
b1 >> bass(dur=2, coarse=4, chop=0)

The line using coarse = 4 sounds that little bit cleaner. Unfortunately this doesn’t always happen and the coarse can’t always be applied to some synths, for example klank.

High-pass filter

Keywords: hpf, hpr = 1

A non-trivial sound is made up of a combination of sound waves vibrating at various frequencies and amplitudes, and some of these can be “filtered out” from a signal using a filter. This is often known as subtractive synthesis. A high pass filter will remove parts of a signal that are *below* a certain frequency i.e. only lets frequencies through that are higher than the threshold. This can be applied in FoxDot simply by setting the hpf (short for high-pass filter) value:

# Set the high pass filter cutoff to 2000 Hz
d1 >> play("x-o-", hpf=2000)
 
# Set the cutoff to change over time using a linvar
d1 >> play("x-o-", hpf=linvar([0,2000],32))

You can also set the high-pass resonance for the filter using the hpr keyword. This is sometimes referred to as “rq” or “hpq”. As this value decreases, the overtones near the cutoff value are boosted – a value close to 0 will sound like a sine wave oscillating at the value set using hpf. Be careful of very small and very large values as you might get very loud sounds!

# Set the high pass filter cutoff to 2000 Hz
d1 >> play("x-o-", hpf=2000)
 
# Set the resonance to 0.2 - can you hear the difference?
d1 >> play("x-o-", hpf=2000, hpr=0.2)
 
# Set the cutoff *and* resonance to change over time using linvar
d1 >> play("x-o-", hpf=linvar([0,2000],32), hpr=linvar([1,0.1],28))

Low-pass filter

Keywords: lpf, lpr = 1

Just as the high pass filter only allows through frequencies within an audio signal above a certain cutoff, the low pass filter only allows through frequencies within an audio signal below a certain cutoff. The low pass resonance, lpr, works in the same way that the high pass resonance does too.

# Set the low pass filter cutoff to 400 Hz
d1 >> play("x-o-", lpf=400)
 
# Changing the resonance - can you hear the difference?
d1 >> play("x-o-", lpf=400, lpr=0.2)
 
# Use a linvar to vary both values over time
d1 >> play("x-o-", lpf=linvar([500,5000],32), lpr=linvar([1,0.1],28))

Bitcrush

Keywords: crush, bits = 8

Bitcrushing is a distortion effect created by reducing both the sample rate of an audio signal and the bandwidth. A crush value of 1 will reduce the bit-rate of the signal to the value of bits, which is 8 by default. Every increment to crush thereafter reduces the sample rate of the signal (starting at 44.1 KHz) by half. The bitcrush effect requires the SC3 Plugins to be installed to work.

# Apply the bit-crusher effect
d1 >> play("X O ", crush=4)
 
# Reduce the number of bits for more distortion
d1 >> play("X O ", crush=4, bits=4)
 
# Or reduce the sample rate for a different style of distortion!
d1 >> play("X O ", crush=32, bits=8)

Distortion

Keywords: dist

This requires the SC3 Plugins to be installed. This should be a value between 0 and 1 and distorts the audio signal.

# Add distortion to both sample and synth players
d1 >> play("x * ", dist=0.2)
 
p1 >> dirt([0,5], dist=0.3, dur=8) + (0,4)

Wave-shape distortion

Keywords: shape

This is another type of distortion that affects the shape of the audio signal’s waveform. This value should be between 0 and 1, but larger values are also accepted (be careful with headphones!). This distortion effect does not require any extra installation.

# Add distortion to both sample and synth players
d1 >> play("x * ", shape=0.5)
 
p1 >> dirt([0,5], shape=0.5, dur=8) + (0,4)

Overdrive distortion

Keywords: drive

A distortion created by amplifying the sound then clipping it at a much more “normal” amplitude. Values should be between 0 and 1 but larger values are accepted.

# Add overdrive distortion
p1 >> dirt(dur=1/2, drive=1)

Reverb

Keywords: room, mix = 0.1

Use the room keyword to add reverb to a sound. This emulates the effect of playing the sound in a room and can be on a scale from dry (0% mix of the reverberated sound) to wet (100% mix of the reverberated sound). The room keyword sets the size of the room to emulate reverb in, and mix is the percent mix as a fraction (i.e. 0.1 is 10%).

# Emulate playing the sounds in a small room
p1 >> play("x o ", room=0.25)
 
# Emulate playing the sounds in a larger room
p1 >> play("x o ", room=0.8)
 
# Make the signal more 'wet'
p1 >> play("x o ", room=0.8, mix=0.8)

Echo

Keywords: echo, echotime = 1

This effect often goes under the name of “Comb Delay” but applying it to a single sound will give it the effect of echoing in a room. Use the echo keyword to define the duration (in beats) between each repeated sound. The following code plays a single note on repeat but we hear it echoed back to us after 1 beat.

p1 >> blip(dur=4, echo=1)

NOTE: You may sometimes have to add reverb using the room keyword argument to hear the echo effect. This is because a sound is stopped by SuperCollider once it is detected as being silent. If the echo would occur after a period of silence, you will need to add reverb to keep the sound “alive” as it were. Here is an example:

# We don't hear any echo effect
d1 >> play("x-o-", dur=1, echo=0.75)
 
# Add reverb and we do
d1 >> play("x-o-", dur=1, echo=0.75, room=0.5)

By default you will probably only hear one echo of the original sound. To hear more echoes, increase the echotime duration:

# Only hear one echo
p1 >> blip(dur=4, echo=1)
 
# Now we hear several
p1 >> blip(dur=4, echo=1, echotime=8)
 
# We can use echo to make drum loops more interesting too
d1 >> play("(x )( x)o ", room=0.1, echo=0.75/2, echotime=4)

Be careful of using too much echo on too many players as it uses a large amount of CPU and can cause SuperCollider to crash.

Pan spin

Keywords: spin

This effect continually pans the sound from left to right, and back again, ‘n’ number of times, where ‘n’ is the value given to the spin keyword. This is dependant on the sustain of the note (given using the sus keyword).

# Move the pan left to right 4 times across 4 beats
p1 >> pads(dur=4, spin=4)
 
# Move the pan left to right 4 times across 1 beat
p1 >> pads(dur=4, sus=1, spin=4)

Cut

Keywords: cut

To stop a sound abruptly (as opposed to just using a shorter sus) you can use the cut keyword. This is especially useful when playing samples using the play SynthDef as sus has no effect on the sound itself. The duration at which the sound is stopped is the cut value as a proportion of the sus value i.e. a cut of 0.5 will stop the sound half way through.

# Stop a sound immediately instead of it's natural decay
p1 >> pads(dur=4, cut=0.75)
 
# Shorten samples to a tenth of their normal length
d1 >> play("x-o-", cut=0.1)

Formant filtter

Keywords: formant

This uses SuperCollider’s Formlet class to add a very simple resonance filter to the sound, not dissimilar to TidalCycles “vowel” effect. The values should be between 1 and 7.

# Loop through the different levels we can apply the filter
p1 >> pluck(formant=P[:8])

Tremolo

Keywords: tremolo

Tremolo is the modulation of amplitude, which is done in FoxDot using a sine wave. This oscillates a note’s amplitudes ‘n’ times per beat, where ‘n’ is the input given to the tremolo argument.

p1 >> pads(dur=4, tremolo=2)

Pitch shift

Keywords: pshift

The shifts the pitch of a note by pshift number of semitones up or down. This also works for samples being used by the play SynthDef.

# Shift a synth's pitch
p1 >> pads(pshift=[0,1,2,3])

# Shift a sample's pitch
p2 >> play("C", dur=2, pshift=[0,1,2,3])

# Can be used to make chords
p2 >> play("C", dur=2, pshift=[0, (0,4,7)], sample=3)

Glide

Keywords: glide, glidedelay = 0.5

Glide, sometimes known as glissando, is very similar to the “slide” effect except that you specify the number of semitones to slide instead of the frequency multiplier. In future this may be replaced by the number of steps in the scale for consistency.

# Glide to and from the 5th note in the scale (7th semitone)
p1 >> pluck([0, 4], dur=4, glide=[7,-7])