AEJoy —— 表达式之音频节拍计数器【JS】

370 阅读2分钟

效果图

0.gif

想法

在处理音频时,你可能希望每个节拍都能产生独特的反应。对于本例,我们将研究一种方法,使每个节拍上出现一个新层。

设计

《AEJoy —— 表达式之音频触发动画》中,我们着眼于检测最近的节拍并使用它来驱动动画的方法。这里我们需要的是非常相似的(事实上,我们将从前面的主题中借用很多代码)。在前面的例子中,我们的代码从当前合成时间开始(往后)循环,直到找到一个 “节拍” (从阈值以下到阈值以上的转换)。但这一次,我们需要从当前的合成时间一直循环到时间 0 ,并在此过程中计算节拍数。

所以这个过程本质上和前面的例子是一样的,除了不是计算从最近的过渡到现在有多长时间,而是计算总共有多少个过渡。我们将在一个应用于空层的滑块控件的表达式中执行这个计算。在这个例子中,我们将空层命名为 control 。我们将使用滑块控件表达式 “发布” 节拍计数结果,用于应用到我们其他图层的不透明度属性的表达式。

不透明度表达式将检查滑块控件提供的当前节拍数,并将该信息与该层在层堆栈中的索引结合使用,以确定该层在当前时间是否应该可见。不透明度表达式将检查节拍数是否等于或超过参与的层数(本例中为 6 )减去该层自己的层索引。这样做的结果是,图层将从下到上一个接一个地弹出到视图中。

不透明度表达式看起来像这样:

n = 6;
slider = thisComp.layer("control").effect("Slider Control")("Slider");
if (slider > (n - index)){ 100 }else{ 0 } 

注意,这个简单的不透明度表达式对应用它的图层做了一些假设。一个假设是,这些层将在同一个合成中(合并为 “控制” 层)。另一个假设是,这些层位于层堆栈的顶部(也就是说,它们是层 1 到层 n (在本例中是 6 )。如果你想要层在一个不同的合成,或在其他地方,而不是层堆栈的顶部,你将不得不修改表达式。

下图说明了当音频振幅超过阈值时,节拍计数器如何增加 1 。

image.png

下面是计算转换次数的表达式(将应用于滑块控件):

表达式代码

threshold = 10.0;

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

above = false;
frame = Math.round(time / thisComp.frameDuration);
n = 0; ///< 用于存储过渡的个数
while (frame >= 0) {
    t = frame * thisComp.frameDuration;
    if (above) {
        if (audioLev.valueAtTime(t) < threshold) {
            above = false;
        }

    } else if (audioLev.valueAtTime(t) >= threshold) {
        above = true;
        n++; ///< 找到过渡则 +1
    }
    frame--
}
 
n ///< 输出过渡的个数

(完)