Envelope

Envelopes, together with the choice of a sound (loaded as an AudioSample), establish a sound’s individual quality or timbre.

Envelope objects are used to help shape the sound of AudioSample instruments used to play notes.   They utilize four adjustable parameters:

Figure-6.25-Graph-of-ADSR-envelope
  • Attack models the beginning of the sound, i.e, how long it takes for the sound to begin sounding fully, once it has been started.  It is the initial build up of the sound.
  • Decay models the initial loss of energy after the Attack, i.e., how long it takes for the sound to reach its normal level, after the maximum of the initial attack.
  • Sustain models how long the sound maintains its normal level.
  • Release models the end of the sound, i.e., how long it takes for the sound to finish sounding, after it has been stopped.

For more information on Envelopes, see here and here.

Creating an Envelope

An envelope is created as follows:

FunctionDescription
Envelope(attackTimes, attackVolumes, delayTime, sustainVolume, releaseTime)Creates a new envelope, with attackTimes (a list of times in milliseconds, relative from the previous time – initially, from start of sound), attackVolumes (a list of sound volumes between 0.0 and 1.0 to be reached at the corresponding attack time, relative to the max volume of a given note, or sound – this is important), delayTime (how many milliseconds, from the last attack time, to reach the sustain volume), sustainVolume (a sound level between 0.0 and 1.0, which will last – no matter how long the note is – until the end of sound), and releaseTime (how many milliseconds it takes, after the end of sound, for it to end – adds more to the end of sound, in a diminishing volume).

For example,

env = Envelope([100, 200], [0.8, 1.0], 300, 0.6, 1200)

creates an Envelope object env, which may be used to help shape an AudioSample, as follows:

  • Attack has two different times (in milliseconds), namely 100 and 200 (these are relative times).  The corresponding volumes are 0.8 and 1.0 (where 0.0 means silence, and 1.0 means max volume).  
    In other words, it will take 100 milliseconds for the sound to reach 0.8 volume, and then another 200 milliseconds to reach 1.0 (max volume). 
  • Decay time is 300 milliseconds. In other words, it will take 300 milliseconds after the attack, to reach the sustain volume.
  • Sustain volume is 0.6 (relative to max volume).
  • Release time is 1200 milliseconds (beyond the end of sound).
    In other words, the sound will take 1.2 secs to die down, after it was stopped.

Once an Envelope env has been created, the following functions are available:

FunctionDescription
env.getAttackTimesAndVolumes()Retrieve both lists of attack times and volumes of envelope env.
env.setAttackTimesAndVolumes( attackTimes, attackVolumes )Sets both lists of attack times and volumes of envelope env.
env.getSustainVolume()Retrieve the sustain volume of envelope env.
env.setSustainVolume( volume )Set the sustain volume of envelope env.
env.getDelayTime()Retrieve the delay time of envelope env.
env.setDelayTime( time )Set the delay time of envelope env.
env.getReleaseTime()Retrieve the release time of envelope env.
env.setReleaseTime( time )Set the release time of envelope env.

Example

The following demonstrates how to use an envelope to shape the sound of a loop:

# audioLoopWithEnvelope.py
#
# Demonstrates how to create a loop using an audio file and an envelope.
# This may be used for ambient or drone backdrops of sound to build on.
#

from music import *

loopTimes = 4

# load audio instruments
a1 = AudioSample("moondog.Bird_sLament.wav")

# define an envelope
e1 = Envelope([20, 60, 100, 10], [0.0, 0.8, 1.0, 0.8], 30, 0.6, 30)
#e1 = Envelope()

# create musical data structure
score = Score()

part1 = Part(0, 0)

phrase1 = Phrase()

# create musical data
pitches   = [A4] * loopTimes
durations = [4.12152] * loopTimes   # duration is in seconds (assuming 60bpm)
volumes   = [120] * loopTimes
pannings  = [0.5] * loopTimes
lengths   =  durations              # force playing length to be same as noted duration!

phrase1.addNoteList(pitches, durations, volumes, pannings, lengths)

part1.addPhrase(phrase1)

score.addPart(part1)

# play it!
#Play.audio( score, [a1] )
Play.audio( score, [a1], [False], [e1] )