Introduction to Effects
In music production, a variety of effects can be added to a track in order to change the way a section of audio sounds. Effects are an important part of making electronic music. Electronics, from the simple transistor to the computer, has given musicians another tool to shape, process, manipulate, and change sound. Modern music production relies on effects to create mood, excitement, and style from basic samples. Effects also change the music in ways that is non-destructive, only affecting the audio stream from a sample, rather than the sample itself. Samples can have effects added and removed from them without changing the underlying file at all. This is really useful in a production environment. It lets the musician try out various effects or combinations of effects without having to worry about the messing up the samples themselves. EarSketch supports the most common effects used in music production: delay, low-pass filter, distortion, pitch shift, and volume/panning. Each of these effects are further explained below.
Just to know what we're starting with, here's a reference sound. This sound will have various effects applied to it.
Delay: A delay effect plays back the original audio as well as a delayed, quieter version of the original that sounds like an echo. After the first echo it plays an echo of the echo (even quieter), then an echo of the echo of the echo (still quieter), and so on until the echo dies out to nothing. With the delay effect, we can control how much time passes between each echo (delay time). If we set the delay time to match the length of a beat, we can create rhythmic effects with delay.
Filter: the low-pass filter effect allows low frequency audio to pass through unchanged, while changing the amplitude of the higher frequency depending on how many frequencies are filtered out. This gives the audio a “darker” sound. This effect shown in the graphic equalizer below. Each bar on the equalizer represents a frequency. These frequencies are arranged lowest to highest from left to right. The height of each bar corresponds to the strength of that particular frequency in the sound file. Notice how the heights of the higher bars change once the low-pass filter is in place upon the audio file, while the lower bars maintain a similar height in both images.
Distortion: This effect produces a “dirty” or “fuzzy” sound to your audio. Distortion is frequently created tby some amplifiers in conjunction with an instrument like an electric guitar. Though that distortion is sometimes unwanted, modern music sometimes uses distortion to add a grungy or gitty effect or feel to the composition.
Pitch Shift: This effect simply lowers or raises the sound by a specific pitch interval. It can be useful in helping multiple sound files sound better together or, contrastingly, to add a little bit of dissonance, if desired.
Volume/Panning: The volume effect allows for the changing of the volume of an audio clip. Panning affects the audio mix between the left and right channels. For example, if you were wearing headphones, changing the panning would affect whether you heard something from the left earcub or the right.
Effects terms in the DAW
Envelope: the envelope is a description of how a particular parameter of an effect (like distortion gain or panning amount) changes over time. On the timeline in Reaper, it is represented by a series of connected line segments that show the effect parameter’s value over time. The graph that represents the envelope can be directly manipulated via clicking and dragging points to change the values over time.
Points: points describe a point in time where an effect envelope has a defined value. Reaper draws smooth lines between points, creating the line segments defining the envelope. Gradually changing the effect value between defined points is called ramping.
Using effects in the DAW
Like on the first day, the first thing to do with Reaper is to drag an audio file onto the timeline. Here, we’ve added
JAZZ_SESSIONS_GUITAR2_2M onto track 1, and used the handle on the right of the clip to make it fill 8 measures. Now we’ve got a single track with no effect:
Let’s spice this up a bit by adding an effect! Click on the green button on the bottom left of the track control. You’ll see a pop-up that has a number of effects you can add.
Click on “Volume”:
This will add a new effects layer to the track. Now you can close this window and have the effects track ready to play with.
To create a new point on the envelope, you can shift-click on it and a new point will appear. You can drag this point to shape the envelope however you please. On a Mac, it’s possible to “draw” shapes in the envelope by holding down the command key and clicking and dragging around in the envelope area. On a PC, you can do the same thing while holding the “control” key. If you want to hide the envelope, or just clear the envelope entirely and start over, clicking on the little envelope button next to the green button will open a dropdown that gives you these options.
It’s also possible to manually add multiple effects to a single track. This time, repeat the steps that you took to add a single effects layer, but select “Pan” instead of “Volume.”
This will add a second effects layer (shown here in orange) to your track, allowing you to manipulate the volume of the sample in the left or right channel. By adding points to the envelope in the same way as above (and a little bit of dragging them around), you can set up the panning layer to make the audio in the track play in the left ear for one measure, then the right ear, back to the left ear, and so on:
Introduction to programing effects
The EarSketch API lets you as a programmer apply effects to your work using the
setEffect() function. Each effect can be adjusted within the parameters of the function. While
setEffect() can be used with many parameters to control different aspects of effects, let’s get started with a very simple example.
Basic programmatic effects
First, let’s create a very simple implementation of an effect.
from earsketch import * init() setTempo(120) fitMedia(JAZZ_SESSIONS_GUITAR2_2M, 1, 1, 9) setEffect(1, VOL_PAN, VOL_PAN_VOL, -10) finish()
This is a simple use of effects in the EarSketch environment. This script puts eight measures of
JAZZ_SESSIONS_GUITAR2_2M on the timeline at track one, then adds a volume effect to that track. The result is that the sample should be quieter than it was without the effect. To really hear it work, it can be useful to turn effects off (called bypassing the effect) for a track, and then turn it back on. To do this, click the button labelled FX that has a power symbol next to it.
The syntax here is fairly straightforward. The first parameter tells Reaper which track the effect will be added to. The second is the name of the effect (in this case
VOL_PAN, for overall volume and panning, which can be thought of as volume control between channels). The third parameter is the constant for the particular effect parameter, in this case
VOL_PAN_VOL, selecting overall volume as the particular effect we’re looking to add. Finally, the last parameter tells Reaper how much you want to change the volume on track one.
Programming effects with envelopes
Programmatically setting effects isn’t just limited to track-wide changes, however. Like when interacting directly with the DAW, we can create envelopes using Python as well. Here’s the same code as above, but with more and different parameters to create an effect envelope.
from earsketch import * init() setTempo(120) fitMedia(JAZZ_SESSIONS_GUITAR2_2M, 1, 1, 9) setEffect(1, VOL_PAN, VOL_PAN_VOL, -60, 1, 0, 3) finish()
In this script, the track fades in from silence to normal volume over the course of the first two measures. Like using a DAW, setting an effect using Python requires points to be defined. In this case, we’re defining a pair of points: one with a value of
-60 at measure 1, and another with a value of
0 at measure three. Defining two points will make the DAW ramp between them, creating a smooth volume change. In this case, the track will fade in over two measures from silence at measure one, to regular volume at measure three.
Here’s a breakdown of the parameters that
setEffect(trackNumber, FXName, parameter, effectStartValue, effectStartLocation, effectEndValue, effectEndLocation)
and listed below with definitions:
|trackNumber||chooses the track to put the effect on|
|effectType||a constant that selects the effect name|
|effectParameter||a constant that selects the parameter of the effect to be configured|
|effectStartValue||the initial value of the effect parameter|
|effectStartLocation||the measure that the effect begins on (where the first point is)|
|effectEndValue||the ending value of the effect|
|effectEndLocation||the ending measure for the effect (the location of the second point)|
Defining more complex envelopes
Using multiple calls to setEffect(), making more complex envelopes becomes fairly simple. Because each effect call is creating a pair of points that exist on their own, Reaper will smoothly connect any different values. Here, for example, is a more complicated call that builds on the script above. After the fade in, there’s a crescendo (meaning that the volume is increasing) from measures 4 to 6, a decrescendo (where the volume decreases), and finally, a fade out:
from earsketch import * init() setTempo(120) fitMedia(JAZZ_SESSIONS_GUITAR2_2M, 1, 1, 9) setEffect(1, VOL_PAN, VOL_PAN_VOL, -60, 1, 0, 3) setEffect(1, VOL_PAN, VOL_PAN_VOL, 0, 4, 12, 6.5) setEffect(1, VOL_PAN, VOL_PAN_VOL, 12, 7, 0, 8.5) setEffect(1, VOL_PAN, VOL_PAN_VOL, 0, 8.5, -60, 9) finish()
A couple of things are important to note here. One is that the points defined by
setEffect() do not need to be the same between calls: the ramping that the DAW provides will create a smooth line between any defined point. That is to say, the first value of the pair defined by
setEffect() does not need to be the same as the last point in the previous call. Also, points can be defined to be anywhere inside a measure, just like other timeline functions. Using decimal places allow you to place points exactly where you want them to be.
Stacking effects on a single track
It’s possible to create tracks that have multiple effects with the EarSketch API as well. Here’s an example of a track that has both volume and panning:
from earsketch import * init() setTempo(120) fitMedia(JAZZ_SESSIONS_GUITAR2_2M, 1, 1, 9) setEffect(1, VOL_PAN, VOL_PAN_VOL, -60, 1, 0, 3) setEffect(1, VOL_PAN, VOL_PAN_VOL, 0, 4, 12, 6.5) setEffect(1, VOL_PAN, VOL_PAN_VOL, 12, 7, 0, 8.5) setEffect(1, VOL_PAN, VOL_PAN_VOL, 0, 8.5, -60, 9) setEffect(1, VOL_PAN, VOL_PAN_PAN, -100, 0, 100, 9) finish()
This script takes the previous script and adds a pan to the audio: it starts entirely in the left channel, and slowly moves to the right.
Using beat patterns with effects
Finally, we can also pass a
makeBeat()-style string to the
setEffect() function, allowing us to control effect envelopes in a more convenient way than manually setting values with multiple individual
setEffect() calls. In order to use effects in this way, we need to use a new function called
rhythmEffects(). The format for
rhythmEffects() is as follows:
rhythmEffects(trackNumber, FXname, parameter, valueList, measure, string)
And again, in more detail:
|trackNumber||selects a track|
|effectType||is an effect|
|effectParameter||is the specific type of effect||valueList||is a list containing numerical values that set effects points|
|measure||is where you want the effect to start|
|rhythmString||is the string denoting which values you want from
You may use “0, 1, 2, 3, 4, 5, 6, 7, 8, 9” to draw from the list.
“+” indicates extending the block of time for the envelope
“-” will ramp between defined effect values
Consider the following example with distortion and panning effects:
In order to do this by hand, we would have to spend a long time creating points and dragging them onto the correct values at the correct time. To do this with the
setEffect() function would be tough as well, requiring a new call every time the value changes. Using
rhythmEffect() and for loops allows us to make this kind of repeating pattern of effect envelopes very simple.
# Distortion demo with rhythmic effects from earsketch import * setTempo(120) init() drums = TECHNO_WARPEDDRUMS_2M fitMedia(drums, 1, 1, 9) distortValues = [0, 20, 40] distortString = "1+++0+++202020++" panValues = [0, -100, 100] panString = "0+++0+++1+++2+0+" for measure in range(1,9): rhythmEffects(1, DISTORTION, DISTO_GAIN, distortValues, measure, distortString) rhythmEffects(1, VOL_PAN, VOL_PAN_PAN, panValues, measure, panString) finish()See this example on the social network
Here’s a breakdown of what the code is doing here:
- Line 11 creates a list distortValues that stores 0, 20, and 40.
- Line 12 creates a list distortString that stores the pattern that will “pull” corresponding effect values
- Lines 14 and 15 do the same for the list and string we will use for the pan effects.
- Lines 17 to 19 use a loop to put the effects on each measure.
- Line 18:
rhythmEffects(DISTORTION, DISTO_GAIN, DistortValues, 1, measure, DistortString)
creates the following effect envelope:
- Line 19 performs a similar action with the list
panValuesand the string
Questions and Exercises #1:
Given the following example, write a section of code that adds distortion to highlight or emphasize the drums on track 1. Add another track with music or bass to complement track 1.
# Day 4 Exercise 1 Code from earsketch import * # Make Music init() setTempo(110) djDrums = TECHNO_DRUNKDJDRUMS_4M fitMedia(djDrums, 1, 1, 9) # Insert Effects Here # Finish finish()
- Given the following code, use the pitch effect to increase tension over the 16 measure example.
# Day 4 Exercise 2 Code from earsketch import * # Music Sources latinDrum1 = LATIN_PERCLOOP1_2M latinDrum2 = LATIN_PERCLOOP3_2M flute = LATIN_FLUTE1_2M latinKeys = LATIN_KEYBOARD2_2M # Functions for Section def SectionA(start, end): fitMedia(latinDrum1, 1, start, end) fitMedia(latinDrum2, 2, start, end) fitMedia(flute, 3, start, end) fitMedia(latinKeys, 4, start, end) # Make Music init() setTempo(140) SectionA(1, 17) # Insert Effects Here # Finish finish()
- Download a remix from the social network. Select 8 measures and use effects to change the sound and feel of the remix.
Sectional form, musical structure
Every song can be broken down into distinct sections of sound. These sections form the patterns that we discussed, such as ABA form. Effects such as a pitch shift can be used to alter a section in order to make it sound slightly different, while also adding a rhythmic feel. Most popular music genres use the Verse1-Chorus-Verse2-Chorus-Bridge-Chorus-Chorus form (ABABCAA).
While an intro can be extremely simple, we will focus on a more complex intro method that implements an additive structure. An additive structure is one that begins with minimal tracks and, as the intro progresses, more and more tracks are added in various time increments. A good example of this is from Kanye West’s song POWER: in the introduction, listen as the different tracks are added and the sound becomes more complex and intense.
Below is an example of how an additive introduction (using a list and for loop) could be implemented in EarSketch.
# Introduction example from earsketch import * drum1 = HIP_HOP_PROGDRUMS11_2M drum2 = SOUL_TAMBOURINE_4M bass = TECHNO_DEEPTOUCHBASS_2M music = TECHNO_BLISSEQSYNTH_2M IntroList = [drum1, drum2, bass, music] init() setTempo(92) # Intro generator for track in range(1, 5): # make a new list index that is 0-based mediaIndex = track - 1 # make a measure variable that skips every other measure # this one will have values 1, 3, 5, 7, 9 measure = (track * 2) - 1 fitMedia(IntroList[mediaIndex], track, measure, 9) finish()See this example on the social network
A bridge in popular music is a contrasting section that prepares for the return to the original audio section. If we remember how fills work to break up specific measures, for instance having a fill every fourth measure, bridges have a similar function relative to entire sections of music. There are several common ways to approach the creation of a bridge. One of which is to use the same additive structure that we described for use as an introduction. This creates a sort of build up to emphasize the coming change. A second approach to use would be the pitch shift effect. Continually change the pitch over the course of a bridge to segue into the new section. An additional approach is to use
makeBeat() and create new rhythmic ideas with preexisting material within the remix.
Example chorus and bridge
(Chorus: measures 1 - 8, bridge, measures 9 - 12, pitch-shifted chorus 13 to 20)
# Chorus and bridge example from earsketch import * drums = HIP_HOP_BEATBOX1_2M drums2 = HIP_HOP_JAZZDRUMS1_4M music = HIP_HOP_KEYBOARDMELODY6_2M MusicList = [drums, drums2, music] # Functions for sections of music def chorus(start, end): for music in range(0, len(MusicList)): tracks = music + 1 fitMedia(MusicList[music], tracks, start, end) def bridge(start, end): beat1 = "0++0++1+1++1+0++" beat2 = "2+++" for measure in range(start, end): makeBeat(MusicList, 1, measure, beat1) makeBeat(MusicList, 2, measure, beat2) fitMedia(HIP_HOP_JAZZDRUMS2_4M, 3, start, end) # Setup remix init() setTempo(92) # Chorus (measures 1 - 9) chorus(1, 9) # Bridge (measures 9 to 13) bridge(9, 13) # Return to chorus - modulated up a semitone (music only) chorus(13, 21) # Modulation setEffect(3, PITCHSHIFT, PITCHSHIFT_SHIFT, 0, 1, 0, 13) setEffect(3, PITCHSHIFT, PITCHSHIFT_SHIFT, 1, 13, 1, 21) finish()See this example on the social network
Transitions between sections are very useful to create good musical style. A transition could be something simple like creating a beat with the
makeBeat()function, or it could be more complex with the use of effects. One effect that can be used in a transition is the pan effect. With this effect, we can implement something called ping-pong panning. In ping-pong panning, the audio oscillates back and forth from the left side to the right side, producing a bouncing sound. The speed of the back and forth panning could be increased as a part of the transition. Also, we could use pitch shift and raise pitches to build tension within a transition to lead into a new section. For example, in Rhianna’s We Found Love, this technique is used to transition from the chorus to another section of the song.
A common effect used to end a song is the fade out. During a fade, audio becomes gradually quieter until it’s no longer audible To do this, we would use the volume effect and set it to gradually decrease over the course of several measures.
Example fade out
# Fade Out Example from earsketch import * drums = ELEKTRO_HOUSE_DRUMS4_2M music = ELEKTRO_HOUSE_SYNTH3_1M scratch = HIP_HOP_DJSCRATCH1_2M bass = HIP_HOP_BASS2_2M musicList = [drums, music, scratch, bass] init() setTempo(110) # Create 4 Tracks of Music for track in range(1, 5): Index = track - 1 fitMedia(musicList[Index], track, 1, 9) # Fade Out # Fade out all Tracks with For Loop for track in range(1, 5): setEffect(track, VOL_PAN, VOL_PAN_VOL, 10, 1, -60, 9) finish()See this example on the social network
A complete song
Here’s an example of all these things working together to create a complete piece of music:
# Form Full Example from earsketch import * # Intro Content drum1 = HIP_HOP_PROGDRUMS11_2M drum2 = SOUL_TAMBOURINE_4M bass = TECHNO_DEEPTOUCHBASS_2M music = TECHNO_BLISSEQSYNTH_2M introList = [drum1, drum2, bass, music] # Verse Content drum5 = ELEKTRO_HOUSE_DRUMS4_2M music3 = ELEKTRO_HOUSE_SYNTH3_1M scratch = HIP_HOP_DJSCRATCH1_2M bass1 = HIP_HOP_BASS2_2M lerseList = [drum5, music3, scratch, bass1] # Chorus Content drum3 = HIP_HOP_BEATBOX1_2M drum4 = HIP_HOP_JAZZDRUMS1_4M music1 = HIP_HOP_KEYBOARDMELODY6_2M ChorusList = [drum3, drum4, music1] # Functions for Sections of Music def intro(list): for track in range(1, 5): mediaIndex = track - 1 measure = (track * 2) - 1 fitMedia(list[mediaIndex], track, measure, 9) def verse(list, start, end): for index in range(0, len(list)): track = index + 1 fitMedia(list[index], track, start, end) for measure in range(start, end): track = len(list) + 1 makeBeat(drum5, track + 1, measure, "0+----0+0+--0+--") if measure % 4 == 0: makeBeat(drum5, track, measure, "0+-000-00+++00-0") def chorus(list, start, end): for music in range(0, len(list)): tracks = music + 1 fitMedia(list[music], tracks, start, end) def bridge(list, start, end): beat1 = "0++0++1+1++1+0++" beat2 = "2+++" panValues = [0, -100, 100] for measure in range(start, end): makeBeat(list, 1, measure, beat1) makeBeat(list, 2, measure, beat2) rhythmEffects(VOL_PAN, VOL_PAN_PAN, panValues, 1, measure, beat1) fitMedia(HIP_HOP_JAZZDRUMS2_4M, 3, start, end) setEffect(1, VOL_PAN, VOL_PAN_PAN, 0, end, 0, end) def fadeOut(start, end): for track in range(1, 7): setEffect(track, VOL_PAN, VOL_PAN_VOL, 0, start, -60, end) # Setup Remix init() setTempo(92) # Music intro(verseList) verse(verseList, 9, 17) chorus(chorusList, 17, 25) verse(verseList, 25, 33) chorus(chorusList, 33, 41) bridge(chorusList, 41, 49) chorus(chorusList, 49, 57) chorus(chorusList, 57, 65) fadeOut(57, 65) setEffect(3, PITCHSHIFT, PITCHSHIFT_SHIFT, 0, 1, 0, 49) setEffect(3, PITCHSHIFT, PITCHSHIFT_SHIFT, 1, 49, 1, 65) finish()See this example on the social network
Questions and Exercises #2:
- Write an “Intro Generator” that takes 4 music tracks and layers them in over the course of 16 measures. For an extra challenge - use lists and randomness to have the computer decide which tracks will make up the introduction.
rhythmEffects()to create 8 measures of music that use the “PingPong” technique.
- Download a remix from the social network. Use a for loop to fade out the last 8 measures of the remix.
- Download a remix from the social network. Using the existing music selections and rhythmic ideas, create a bridge for this remix and then re-introduce one of the original musical ideas.
Answers to Questions and Exercises
Questions and Exercises #1
- Possible answer:
# Day 4 Exercise 1 Code from earsketch import * # Make Music init() setTempo(110) djDrums = TECHNO_DRUNKDJDRUMS_4M fitMedia(djDrums, 1, 1, 9) # Insert Effects Here values = [0, 30, 15] rhythm = "1+01+0++2+0+2+0+" for measure in range(1, 10): rhythmEffects(1, DISTORTION, DISTO_GAIN, values, measure, rhythm) fitMedia(HIP_HOP_PROGSYNTH2_2M, 2, 1, 9) # Finish finish()
- Possible answer:
# Day 4 Exercise 2 Code from earsketch import * # Music Sources latinDrum1 = LATIN_PERCLOOP1_2M latinDrum2 = LATIN_PERCLOOP3_2M flute = LATIN_FLUTE1_2M latinKeys = LATIN_KEYBOARD2_2M # Functions for Section def sectionA(start, end): fitMedia(latinDrum1, 1, start, end) fitMedia(latinDrum2, 2, start, end) fitMedia(flute, 3, start, end) fitMedia(latinKeys, 4, start, end) # Make Music init() setTempo(140) sectionA(1, 17) # Insert Effects Here value = 0 for measure in range(6, 17): setEffect(3, PITCHSHIFT, PITCHSHIFT_SHIFT, value, measure, value+1, measure+1) setEffect(4, PITCHSHIFT, PITCHSHIFT_SHIFT, value, measure, value+1, measure+1) value = value +1 # Finish finish()
- This question depends on social media content.
Questions and Exercises #2
- Possible answer:
from earsketch import * from random import randint #setUp init() setTempo(100) #generate 16 measure additive intro based off of a list of audio clips def introGenerator(musicList, numElements): track = 1 measure = 1 for count in range(4): randIndex = randint(0, numElements-1) randMusic = musicList[randIndex] fitMedia(randMusic, track, measure, 16) track = track + 1 measure = measure + 4 #List declaration and function call myMusicList = [ELEKTRO_HOUSE_SYNTH6_2M, HIP_HOP_DRUMLOOP11_2M, HIP_HOP_DRUMS2_2M, HIP_HOP_VIBRAPHONEMELODY1_1M] introGenerator(myMusicList, 4) finish()
- Possible answer:
from earsketch import * #setUp init() setTempo(100) #insert 8 measures of media fitMedia(ELEKTRO_HOUSE_SYNTH6_2M, 1, 1, 8) #determine effect values and the effect string values = [-100, 100] effectString = "0+++0+++1+++1+++" #place effect string pattern on each measure of the composition for measure in range(8): rhythmEffects(VOL_PAN, VOL_PAN_PAN, values, 1, measure, effectString) finish()
- This question depends on social media content.
- This question depends on social media content.