【发布时间】: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