flash - AS3 Sound.extract() 需要帮助

标签 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);
    }
}

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

最佳答案

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

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,即可得到毫秒数。

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

关于flash - AS3 Sound.extract() 需要帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3267055/

相关文章:

android - Flash 未在 Android 的 Web View 中加载

apache-flex - 我应该扩展到 Flex 还是 Flash?

xml - 您是否有任何想法可以让本类(class)的每次点击都播放一个新的音频文件?

actionscript-3 - 错误 1131 : Classes Must Not Be Nested

.net - Silverlight 与 Flex

html - 在 flash 顶部带有菜单下拉菜单的 iframe 使 flash 不可点击

flash - 如何在AS3中创建预加载器

flash - 当输入很大时,字符串连接非常慢

actionscript-3 - Flash AS3 加载最佳实践

xml - 在运行时将 xml 配置文件动态加载到 Flex4/Flash 影片中的最佳方法?