Monday 28 January 2013

Audio Triggers Effect


Audio Triggers Effect

Earlier, you learned about linking an effect to an audio
level. You can take that idea one step further and use audio
to trigger an animated effect. The difference is subtle, but
signifi cant. In the earlier examples, the effect tracked the
audio level precisely, leaving the result at the mercy of the
shape of the audio level’s envelope. Here, you’re going to
use the transitioning of the audio level above some threshold
to trigger an animation. The animation will run until
there is another trigger event, which will cause the animation
to start again from the beginning.
This is a powerful concept and there are many ways to
use it. This example triggers a decaying oscillation that is
actually contained within the expression, but you could
easily adapt this to run a keyframed animation using
valueAtTime() or to run a time remapped sequence.
The heart of this expression is what I would call a “beat
detector.” The expression basically walks backward in time,
frame-by-frame, looking for the most recent event where
the audio level transitioned from below the threshold to
above the threshold. It then uses the difference in time
between the triggering event and the current comp time to
determine how far along it should be in the animation. At
each new beat, this time resets to zero and runs until the
next beat. Take a look at this monster:


threshold = 20.0;
A = thisComp.layer("Audio Amplitude").effect("Both
➥Channels")("Slider");
// beat detector starts here
above = false;
frame = timeToFrames();
while (true){
t = framesToTime(frame);
if (above){
if (A.valueAtTime(t) < threshold){
frame++;
break;
}
}else if (A.valueAtTime(t) >= threshold){
above = true;
}
if (frame == 0){
break;
}
frame--
}
if (! above){
t = 0;
}else{
t = time - framesToTime(frame);
}
// animation starts here
amp = 75;
freq = 5;
decay = 2.0;
angle = freq * 2 * Math.PI * t;
amp * (-Math.cos(angle)+1)/ Math.exp(decay * t);
This expression has three sections. The fi rst section defi nes
the audio level that you want to trigger the animation
and stores it into the variable threshold. It then defines


variable A to use as shorthand notation for the Slider Control
containing the keyframed data for the audio level.
The next section is the actual beat detector. In general, the
expression starts at the current comp time and determines
if the level is currently above the threshold. If it is, the
expression moves backward in time, frame-by-frame until
it fi nds the most recent frame where the audio level was
below the threshold. It then determines that the triggering
event occurred on frame after that (the most recent frame
where the level transitioned from below the threshold to
above it). That transition frame is converted to time using
framesToTime(), that value is subtracted from the current
comp time, and the result (the time, in seconds, since the
triggering event) is stored into variable t.
However, if instead, the audio level at the current comp
time is below the threshold, the expression has more work
to do. It fi rst moves backward from the current comp time,
frame-by-frame until it fi nds a frame where the audio level
is above the threshold. Then it continues on, looking for
the transition from below the threshold to above it. The
elapsed time since the triggering event is then calculated
and stored in variable t.
There are some other things going on in this routine, but
they mostly have to do with special cases, such as the case
where there hasn’t yet been a triggering event (in which
case the animation is held at the fi rst frame), or where the
level is above the threshold but it has been there since the
fi rst frame.
There are some JavaScript elements in this section that you
haven’t seen before. // denotes the start of a comment.
The routine consists mainly of a giant while() loop. This
loop is unusual in that its terminating condition is set to
true, so it will never end on its own. It will continue to loop
until one of the break statements is executed.
When After Effects arrives at the last section of the expression,
variable t contains the necessary information: how
long it has been since the last triggering event. The fi nal
section uses it to drive a decaying oscillation routine with
Math.cos() and Math.exp(). First you defi ne the amplitude

of the oscillation with the variable amp. Then you defi ne the
frequency of the oscillation (oscillations per second) with
the variable freq. Variable decay determines how fast the
oscillation decays (a higher number means a faster decay).
Math.cos() creates an oscillating sine wave with amplitude
amp and frequency freq, then Math.exp() reduces the
amplitude of the oscillating wave at a rate determined by
variable decay.



No comments:

Post a Comment