如何为Sound对象编写音频包络(攻击时间,淡入)?

时间:2012-11-25 02:48:11

标签: actionscript-3 api audio sound-synthesis

我做了一个简单的正弦波音调发生器。问题是,当播放音调时,可以听到强烈的咔嗒声,我需要实现快速淡入(攻击时间)以避免这种情况。

我尝试使用补间(如tweenmax)但它会导致音频失真(可能是补间中的步骤?)。我发现了一些关于这个主题的模糊教程,但没有具体涉及攻击时间。

我该怎么做?

1 个答案:

答案 0 :(得分:2)

对于淡入淡出的声音,它必须在每个样本的基础上增加,在合成循环内。补间引擎可能每秒更新很多次,但您的耳朵仍然可以听到更改作为点击。

在sampleData事件处理程序中,您必须将各个样本乘以一个体积修改器,范围为0到1,递增每个样本

要快速淡入声音,首先将音量设置为0,然后为每个样本添加一个小值,直到达到1.0。您可以稍后将其扩展为更复杂的包络控制器。

这是你可以开始的一个粗略的例子:

for( i = 0; i < length; i++ ) {
    _count++;
    factor = _frequency * Math.PI * 2 / 4400;
    volume += 1.0 / 4400;
    if( volume > 1.0 ) volume = 1.0; //don't actually do it like this, ok?
    n = Math.sin( (_count) * factor ) * volume;
    _buffer.writeFloat(n); 
    _buffer.writeFloat(n); 
}

注意:我没有测试过此片段,也不建议将其用于制作。这只是向你展示我的意思。

另一种可能对您有用的技巧是对音量进行轻松/延迟。使用总是以特定速度“追逐”目标卷的volumeEase变量。这样可以在更改卷时防止点击,并可用于制作更长的信封:

var volume:Number = 0; // the target volume
var volumeEase:Number = 1.0; // the value to use in the signal math
var volumeEaseSpeed:Number = 0.001; // tweak this to control responsiveness of ease

for( i = 0; i < length; i++ ) {
    _count++;

    // bring the volumeEase closer to the target:
    volumeEase += ( volume - volumeEase ) * volumeEaseSpeed;

    factor = _frequency * Math.PI * 2 / 4400;

    //use volumeEase in the maths, rather than 'volume':
    n = Math.sin( (_count) * factor ) * volumeEase;
    _buffer.writeFloat(n); 
    _buffer.writeFloat(n); 
}

如果您愿意,可以使用线性插值,然后以恒定速度“朝向”目标。

再一次,该代码段未经过测试,因此您可能需要调整volumeEaseSpeed。