【问题标题】:Help needed with AS3 Sound.extract()AS3 Sound.extract() 需要帮助
【发布时间】:2010-07-16 16:36:41
【问题描述】:

我正在尝试在 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);
    }
}

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

【问题讨论】:

    标签: flash actionscript-3 flash-cs4


    【解决方案1】:

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

    How to compute viewport from scrollbar?

    您不需要将整个音轨提取到字节数组中。您只需要在需要时获得所需的东西。

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

    sound.extract(yourbytearray,sound.lenght*44.1)
    
    // lenght *44.1 gives you the number of samples if the mp3 is encoded at 44100
    

    如果你有你所有的 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);
    

    一次提取所有音频可能是最简单的方法,但对于 8 分钟以上的 mp3,您会遇到内存问题。

    关于整个样本毫秒的事情.....

    bytearray.position / bytearray.lenght 告诉你你在歌曲中的位置。

    将其除以 44100 得到毫秒数。

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

    【讨论】:

    • 我已经通过检查是否有足够的数据加载来填充样本缓冲区来解决我的问题的主要部分,如果没有,它会等到 5000 毫秒的音频可用并改为输出静音。但是,假设所有内容都将像我目前所做的那样以 44.1 kHz 编码是否安全?声音文件将由用户选择。如果这样做不安全,是否有一种简单的方法可以找到采样率,是否有方法可以更改空声音对象的采样率,或者我是否必须即时插值并将其转换为 44.1 kHz ?
    • 90% 的情况下,您会发现 mp3 编码为 44.1,但并非总是如此。您可以在加载时读取 mp3 标头并确定那里的编码率是安全的
    • 实际上总是 44100 Hz 立体声和 32 位采样率。 Sund.excrt() 就是这样。多兰help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/…
    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多