我試圖在Flash中創建參數均衡器。我一直在尋找一種方式來讀取音頻數據,並在Flash動態播放它們之前處理樣本。在一個Sound對象中加載聲音並使用Sound.extract()來讀取數據,處理它,然後播放第二個空的Sound對象並將數據寫入其sampleData事件似乎是實現它的方式(請糾正我如果我錯了或者有更好的方法)。AS3需要幫助Sound.extract()
當Sound對象仍在加載聲音文件時,有沒有辦法使用Sound.extract()?我不想在播放之前等待整個聲音文件加載。不幸的是,無論何時在Sound對象仍在加載時使用Sound.extract(),它都會返回一個零長度的字節數組。
有沒有辦法在玩之前等待足夠的樣本加載?我想,當Flash影片吃完所有加載的樣本,而聲音文件仍在加載時,我會再次遇到同樣的問題。
這裏是我的代碼的簡化版本。它工作到目前爲止,但只有當我等待Sound對象觸發Event.COMPLETE事件。
var inputSound:Sound = new Sound();
inputSound.load("somefile.mp3");
inputSound.addEventListener(Event.COMPLETE, loadComplete);
var outputSound:Sound = new Sound();
outputSound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSamples);
var sc:SoundChannel;
/*if I called ouputSound.play() right now, it wouldn't work.*/
function loadComplete(e:Event) : void
{
sc = outputSound.play();
}
function processSamples(e:SampleDataEvent) : void
{
var samples:ByteArray = new ByteArray();
var len:int = snd.extract(samples, 8192);
var sample:Number;
var i:int = 0;
trace(len.toString());
samples.position = 0;
//TODO: Sound Processing here
//The following code plays a sine wave over the input sound as a test
while (samples.bytesAvailable)
{
i++;
sample = samples.readFloat();
sample += Math.sin(i * Math.PI/256) * 0.5;
e.data.writeFloat(sample);
sample = samples.readFloat();
sample += Math.sin(i * Math.PI/256) * 0.5;
e.data.writeFloat(sample);
}
}
編輯:如果我嘗試使用進度事件,我將需要做更多的低層次的東西來實現緩衝和諸如此類的東西(什麼我需要考慮?)。有人能幫我解決嗎?另外,有沒有辦法以毫秒爲單位來說明樣本的位置?我是否必須假設所有聲音文件都是44.1 kHz立體聲(它們可能不是),還是有更好的方法?
我已經通過檢查解決我的問題的主要部分,如果有加載到填充樣品緩衝足夠的數據,如果沒有,則等待直到5000毫秒的音頻可用並輸出沉默。 但是,我現在正在做的事情是否可以安全地假設一切都會以44.1 kHz編碼?聲音文件將被用戶選擇。如果這樣做不安全,是否有一種簡單的方法可以找到採樣率,並且是否有方法來改變空聲音對象的採樣率,或者我將不得不插入並隨時將其轉換爲44.1 kHz ? – 2010-07-19 17:35:03
90%的時間你會發現一個MP3編碼爲44.1,但事實並非總是如此。當你加載它時,你可以讀取mp3頭,並確定安全的編碼率。 – dubbeat 2010-07-20 12:54:39
acual是alwys 44100 Hz立體聲和32位採樣率。 Sund.excrt()使它變成這樣。 dolan http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#extract() – 2012-07-02 10:23:02