Let's say we've developed an expression to animate a particular property. We've set it up so that the animation begins at time zero and uses the global object time in the calculation. What we would like to do is trigger this expression whenever an audio level crosses a certain threshold. For example, let's say we have the following expression which creates a decaying wobble when applied to a layer's scale property:

``````
amp = 25;
freq = 5;
decay = 4.0;

angle = freq * 2 * Math.PI * time;
wobble = 1 + amp * Math.sin(angle) / Math.exp(decay * time) / 100;
[value[0] * wobble, value[1] / wobble]
``````

The expression, as written, will cause the layer to wobble once, beginning at time zero. What we actually want is to have the wobble expression execute only when an audio level crosses a threshold.

The technique we'll use here works well for expressions (such as the one above) that calculate their results based on the global object time (which represents the current comp time).

Our basic plan of attack will be fairly simple in concept (but the details will be a little tricky). First, we need to add a "beat detector" to our expression. To do this, we'll add some code that starts at the current frame and moves backwards in time, examining the audio amplitude frame by frame, looking for the most recent transition where the amplitude goes from below the threshold to above the threshold. Once we find this transition, we will set variable t to the amount of time (in seconds) that has elapsed since the transition occurred.

Then all we have to do is to modify the original wobble expression code so that any reference to time is replaced with a reference to our new variable t. This should cause the wobble code to begin executing any time there is a transition.

``````
threshold = 10.0;

audioLev = thisComp.layer("Audio Amplitude").effect("Both Channels")("Slider");

above = false;
frame = Math.round(time / thisComp.frameDuration);
while (true){
t = frame * thisComp.frameDuration;
if (above){
if (audioLev.valueAtTime(t) < threshold){
frame++;
break;
}
}else if (audioLev.valueAtTime(t) >= threshold){
above = true;
}
if (frame == 0){
break;
}
frame--
}
if (! above){
t = 0;
}else{
t = time - frame * thisComp.frameDuration;
}

amp = 25;
freq = 5;
decay = 4.0;

angle = freq * 2 * Math.PI * t;
wobble = 1 + amp * Math.sin(angle) / Math.exp(decay * t) / 100;
[value[0] * wobble, value[1] / wobble]
``````

A wobble animation is triggered each time the audio amplitude exceeds a threshold value.

To make this work, you first need to convert your audio track to keyframes. If you're not familiar with how to do that, take a look at Basic Audio Animation.