AS3 Sound.extract()需要帮助

J.M*_*elo 2 flash actionscript-3 flash-cs4

我正在尝试在Flash中创建参数均衡器.我一直在寻找一种方法来读取音频数据,并在Flash动态播放之前弄乱样本.在一个Sound对象中加载声音并使用Sound.extract()读取数据,处理它,然后播放第二个空的Sound对象并将数据写入其sampleData事件似乎是这样做的方法(请更正我如果我错了或有更好的方法).

有没有办法在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果我尝试使用PROGRESS事件,我将需要做更多的低级别的东西来实现缓冲和诸如此类的东西(我需要考虑的任何其他东西?).有人可以帮我解决这个问题吗?另外,有没有办法告诉样本的位置(以毫秒为单位)?我是否必须假设所有声音文件都是44.1 kHz立体声(它们可能不是),还是有更好的方法?

dub*_*eat 5

在这里查看这篇文章中的解决方案

如何从滚动条计算视口?

您不需要将整个轨道提取到bytearray中.您只需要在需要时获得所需的物品.

如果你真的想一次性提取曲目,你可以使用

sound.extract(yourbytearray,sound.lenght*44.1)

// lenght *44.1 gives you the number of samples if the mp3 is encoded at 44100
Run Code Online (Sandbox Code Playgroud)

一个你有你所有的pcm数据,在你的processsamples处理程序而不是调用声音提取你会做类似的事情

if(yourbytearray.bytesAvailable==0)
{
  yourbytearray.position==0
}

var left:Number = youbytearray.readFloat

var right:Number = youbytearray.readFloat

//process the left with eq

//process the right with eq

event.data.writeFloat(left);
event.data.writeFloat(right);
Run Code Online (Sandbox Code Playgroud)

一次提取所有音频可能是最简单的,但是对于超过8分钟的mp3,你会遇到内存问题.

整个样品毫秒的事.....

bytearray.position/bytearray.lenght为您提供歌曲中的位置.

除以44100,它将给你毫秒数.

如果您需要我清除任何问题,请提出更多问题