AS3 Sound.extract() 需要帮助
我正在尝试在 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 立体声(可能不是),还是有更好的方法?
I'm trying to create a parametric equalizer in Flash. I've been looking for a way to read audio data and mess around with the samples before Flash plays them on the fly. Loading a sound in one Sound object and using Sound.extract() to read the data, processing it, then play a second second empty Sound object and writing the data to its sampleData event seems to be the way to do it (please correct me if I am wrong or there is a better way).
Is there a way to use Sound.extract() while the Sound object is still loading a sound file? I don't want to have to wait for the entire sound file to load before it plays. Unfortunately, whenever I use Sound.extract() while the Sound object is still loading, it returns a zero-length byte array.
Is there a way to wait for enough samples to load first before playing? I imagine I'd have the same problem again when the Flash movie eats through all the loaded samples while the sound file is still loading.
Here's a simplified version of my code. It's working so far, but only when I wait for the Sound object to fire an Event.COMPLETE event.
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);
}
}
EDIT: If I try using the PROGRESS event, I'm going to need to do a lot more low level stuff to implement buffering and whatnot (anything else I need to account for?). Could someone help me out with that? Also, is there a way to tell the position of a sample in milliseconds? Do I have to assume that all sound files are 44.1 kHz stereo (they may not be), or is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在此处查看这篇文章中的解决方案
如何从滚动条计算视口?
不需要将整个轨道提取到字节数组中。您只需要在需要时获得所需的东西。
如果你真的想一次性提取音轨,你可以使用
一个你拥有所有 pcm 数据的数据,在你的 processsamples 处理程序中,而不是调用声音提取,你会做类似
一次性提取所有音频可能是最简单的事情,但你'播放长度超过 8 分钟的 mp3 时会遇到内存问题。
整个样本毫秒的事情......
bytearray.position / bytearray.lenght 告诉你你在歌曲中的位置。
将其除以 44100,即可得到毫秒数。
如果您需要我解决任何问题,请提出更多问题
check out the solution in this post here
How to compute viewport from scrollbar?
You don't need to extract the entire track into a bytearray. You only really need to get what you need when you need it.
If you really want to extract the track in one go you can use
one you have all your pcm data, in your processsamples handler instead of calling sound extract you would do something like
Extracting all the audio at once would probably be the easiest but you'll run into memory problem for mp3s longer than about 8 minutes.
On the whole samples milliseconds thing.....
bytearray.position / bytearray.lenght gives you where in the song you are.
Divide that by 44100 and it will give you the number of milliseconds.
Ask more questions if you need me to clear anything up