Envelope Generator

Source code available here
Note: This example uses Minimal Comps by Keith Peters

Today I worked on an example of an envelope generator for creating an ADSR like effect. It was a good lesson in not only amplitude but also in how to manipulate specific samples in a buffer over time.

The Demo

The intent of an envelope generator is to fine tune the amplitude or “volume” of an audio signal over time. This is an important component in many audio tools. This demo features a three phases in amplitude change, they are:

Attack – The amount of time it takes for the sound to reach it’s full amplitude potential.

Decay/Sustain – The amount of time it takes for the sound to fall to it’s sustaining amplitude. Sustain does not control a parameter of time. It sets the amplitude of the sound when it is sustained. This amplitude is reached after the period of time set by the Decay parameter. On a typical synthesizer with keys the sustain amplitude would be held for as long as a key is held down, hence the term sustain. In this demo, as soon as the amplitude falls to the sustain amplitude the Release phase begins.

Release- The amount of time it takes for the amplitude of the sound to decrease to zero after the sustain phase has ended.

Some Theory

Generally, the amplitude of a digital audio sample can be changed with simple multiplication. This is demonstrated in the following snippet, where amplitude is a floating point number between zero and one.

sample *= amplitude;
event.data.writeFloat( sample );

One great thing about writing audio samples to a buffer is that you actually have very precise control over when exactly you want something to happen to the sound. We know that Flash uses a sample rate of 44.1k. This means that 44,100 samples are needed for every second of audio. So if we want the sound to fade in for 1.5 seconds we can determine exactly how many samples that is and increase the amplitude until we reach the sample at 1.5 seconds. This might look something like the following pseudo code.

protected var _amplitude:Number = 0;
protected function onSampleData( event:SampleDataEvent ):void
{
	var sample:Number;
	var position:Number;
			
	for( var i:int = 0; i < 8192; i++ )
	{
		position = i + event.position;
		sample = Math.sin(  Math.PI * 2 * FREQ * position / SAMPLE_RATE );
				
		// -- attack
		if( position < attack ) {
			_amplitude = position / attack; 
		}
				
		sample *= _amplitude;
			
		event.data.writeFloat( sample );
                event.data.writeFloat( sample );
	}
}

This same approach can be used for the Decay/Sustain & Release phases of the envelope generator. However, there are differences in the equations so be sure to check out the source code linked to above for complete examples.

Posted in Actionscript, Audio | Tagged , , , , , , , , , , , , , , , | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>