我正在尝试在 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/