2012-11-25 27 views
2

我做了一個簡單的正弦波音發生器。問題在於,當播放音調時可以聽到強烈的咔嗒聲,並且我需要實施快速淡入(發作時間)以避免這種情況發生。如何爲聲音對象編碼音頻信封(啓動時間,淡入)?

我嘗試使用補間(如tweenmax),但它會導致音頻失真(也許在補間步驟?)。我在這個主題上發現了一些模糊的教程,但沒有具體針對攻擊時間。

我該怎麼做?

回答

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。

+0

第一個代碼是作品!謝謝! – deval