Skip to main content
Participant
January 30, 2023
Answered

Writing an expression to trigger a sound

  • January 30, 2023
  • 2 replies
  • 1167 views

Hi folks—I want to create an expression where a sound is triggered when X happens. Let's say, every time a null gets to a certain point, play from 0-4 seconds on an audio clip.

 

I'm close, but having trouble with the last part. Here's what I have on the Time Remap keyframes for my audio track:

 

countstart = 0;

countend = 0;

if (thisComp.layer("Null 9").transform.xPosition > 1080){

countstart = time;

countend = time+4;

}

linear(time,countstart, countend, 0,4);

 

The problem is that time is re-defined on every frame. So instead of playing from the current time and just running, the "play from" time is always equal to the current time, and it never catches up.

 

I think a solution would be: when the Null reaches X, have the Expression jot down the current time, but only once. Also, do this every time the null crosses X. But I'm stumped on how to do that. Help would be greatly appreciated.

Correct answer Dan Ebberts

It's more complicated than you might think because expressions don't remember anything. It will end up looking something like this:

maxDur = 4;
p = thisComp.layer("Null 9").transform.xPosition;
triggered = p > 1080;
t = time - thisComp.frameDuration;
delta = 0;
while (t >= 0){
  x = p.valueAtTime(t);
  if (triggered){
    if (x <= 1080){
      delta = time - t;
      break;
    }
  }else{
    if (x > 1080){
      triggered = true;
    }
  }
  t -= thisComp.frameDuration
}
Math.min(delta,maxDur)

2 replies

Community Expert
January 31, 2023

Expressions look at the current frame by default. You will have to write a recursive formula that looks back one frame at a time until it reaches the target value, counts those frames, then increases the time value of the time-remapping keyframe for 1 frame (time/thisComp.frameDuration) for each of the frames the recursive expression has to search. The longer the comp, the longer the expression will take to look back and count frames. 

 

I don't have time to write the expression for you, but you might consider another approach.

Dan Ebberts
Community Expert
Dan EbbertsCommunity ExpertCorrect answer
Community Expert
January 31, 2023

It's more complicated than you might think because expressions don't remember anything. It will end up looking something like this:

maxDur = 4;
p = thisComp.layer("Null 9").transform.xPosition;
triggered = p > 1080;
t = time - thisComp.frameDuration;
delta = 0;
while (t >= 0){
  x = p.valueAtTime(t);
  if (triggered){
    if (x <= 1080){
      delta = time - t;
      break;
    }
  }else{
    if (x > 1080){
      triggered = true;
    }
  }
  t -= thisComp.frameDuration
}
Math.min(delta,maxDur)
Participant
January 31, 2023

Wow, a reply from THE Dan Ebberts is pretty exciting. This totally worked, thank you so much. I'm going to take some time to figure out exactly how it works!