混合来自 ByteArray 的 2 个声音 [英] mixing 2 sounds from ByteArray
问题描述
我已经建立了一个混音器并将所有序列保存在一个数组中然后再次播放,现在我想将混音保存为 MP3,我已经寻找任何方法来保存混音,答案是加载听起来像 byteArrays (sound.extract) 我有一个完成,但我真的不知道如何将所有声音存储在一个 ByteArray 中以便将其保存为 MP3,我得到了这段代码,例如,加载 2 个音频文件和将它们存储在单独的 ByteArrays 中,并播放每个声音,有人知道如何将 2 个 byteArrays 存储在一个中吗?
I have build a mixer and save all the sequence in an array and then play it again, now I want to save the mix as an MP3, I have looked for any way to save the mix and the answer is to load the sounds as byteArrays (sound.extract) I have acomplish that but I don't really know how to store all the sounds in just one ByteArray in order to save it as MP3, I got this code just for example, loading 2 audio files and store them in separate ByteArrays, and play each sound, does any body know how to store the 2 byteArrays in just one?
var mySound:Sound = new Sound();
var sourceSnd:Sound = new Sound();
var urlReq:URLRequest = new URLRequest("Track1.mp3");
sourceSnd.load(urlReq);
sourceSnd.addEventListener(Event.COMPLETE, loaded);
function loaded(event:Event):void
{
mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
//mySound.play();
}
var mySound2:Sound = new Sound();
var sourceSnd2:Sound = new Sound();
var urlReq2:URLRequest = new URLRequest("Track2.mp3");
sourceSnd2.load(urlReq2);
sourceSnd2.addEventListener(Event.COMPLETE, loaded2);
function loaded2(event:Event):void
{
mySound2.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound2);
mySound2.play();
mySound.play();
}
function processSound(event:SampleDataEvent):void
{
var bytes:ByteArray = new ByteArray();
sourceSnd.extract(bytes, 8192);
event.data.writeBytes(bytes);
}
function processSound2(event:SampleDataEvent):void
{
var bytes:ByteArray = new ByteArray();
sourceSnd2.extract(bytes, 8192);
event.data.writeBytes(bytes);
}
推荐答案
在类似的系统上工作了一段时间,我会尽力给你一些指导:
been working on a similar system for a while, I'll do my best to give you some direction:
您的示例代码并没有真正混合 MP3 - 它创建了另外 2 个声音来通过 SampleDataEvent 播放加载的 MP3.您需要做的是仅创建一个输出"声音文件,该文件将保存/播放生成的混合声音.您可以轻松保存该数据,然后将该文件保存为新的 WAV/MP3/what-have-you.
Your example code is not really mixing the MP3's - it's creating 2 more sounds to playback the loaded MP3's via the SampleDataEvent. What you need to do is create just one "output" Sound file that will hold/playback the resulting mixed sound. You can easily save that data as it happens and subsequently save that file as a new WAV/MP3/what-have-you.
真实/伪代码(阅读:懒惰):
real/psuedo-code (read:lazy) :
output = new Sound();
output.addEventListener( SampleDataEvent.SAMPLE_DATA , mixAudio );
song1 = new Sound / load the first mp3
song2 = new Sound / load the second mp3
// a byteArray for "recording" the output and subsequent file creation
recordedBytes = new ByteArray();
要么等到两个 mp3 都完全加载完毕,或者运行一个输入帧来确定两个声音何时不再缓冲(Sound.isBuffering)
either wait until both mp3's are completely loaded, or run an enter-frame to determine when both Sounds are no longer buffering (Sound.isBuffering )
当 mp3 准备好时:
when the mp3's are ready:
// numbers to store some values
var left1:Number;
var right1:Number;
var left2:Number;
var right2:Number;
// bytearrays for extracting and mixing
var bytes1:ByteArray = new ByteArray( );
var bytes2:ByteArray = new ByteArray( );
// start the show
output.play();
function mixAudio( e:SampleDataEvent ):void{
//set bytearray positions to 0
bytes1.position = 0;
bytes2.position = 0;
//extract
song1.extract( bytes1, 8192 );
song2.extract( bytes2, 8192 );
// reset bytearray positions to 0 for reading the floats
bytes1.position = 0;
bytes2.position = 0;
// run through all the bytes/floats
var b:int = 0;
while( b < 8192 ){
left1 = bytes1.readFloat(); // gets "left" signal
right1 = bytes1.readFloat(); // gets "right" signal
left2 = bytes2.readFloat();
right2 = bytes2.readFloat();
// mix!
var newLeft:Number = ( left1 + left2 ) * .5;
var newRight:Number = ( right1 + right2 ) * .5;
// write the new stuff to the output sound's
e.data.writeFloat( newLeft );
e.data.writeFloat( newRight );
// write numbers to the "recording" byteArray
recordedBytes.writeFloat( newLeft );
recordedBytes.writeFloat( newRight );
b++;
}
}
是的 - 您确实应该将可能的输出限制在 -1/1.做吧.这是非常未优化的!
Yes - you should really cap the possible output at -1/1. Do it. This is extremely un-optimized!
好的.所以这是最简单的部分!困难的部分是真正将最终的 byteArray 转换为 MP3.音频以 PCM/未压缩数据的形式存在于 Flash 中,MP3 显然是一种压缩格式.这个答案"已经太长了,所有这些信息都是我从几个非常聪明的人那里收集的.
Ok. so that's the easy part! The tough part is really converting the final byteArray to MP3. The audio exists within Flash as PCM/uncompressed data, MP3 is obviously a compressed format. This "answer" is already way too long and all this info I've gleaned from several very smart folks.
您可以轻松地将MicRecorder"改编为通用的声音数据记录器:http://www.bytearray.org/?p=1858
You can easily adapt 'MicRecorder' to be a generic Sound data recorder: http://www.bytearray.org/?p=1858
转换为 MP3 会很麻烦:Thibault 在 ByteArray.org 上有另一篇文章 - 搜索 LAME MP3.
converting to MP3 will be a bitch: Thibault has another post on ByteArray.org - search for LAME MP3.
优秀的例子/资源:http://www.anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/
在 Google 代码上查找 Andre Michelle 的开源Tonfall"项目.
Look up Andre Michelle's open source 'Tonfall' project on Google code.
查找 Kevin Goldsmith 的博客和实验室 - 他有很好的例子,可以疯狂地使用 Pixel Bender.
Look up Kevin Goldsmith's blog and labs - he's got great example on utilizing Pixel Bender with all this madness.
希望这有帮助!
PS - 从 Andre 那里得到提示,音频缓冲区的最佳长度应该是 3072.在您的机器上试一试!
PS - taking a cue from Andre, the optimal length of the audio buffer should be 3072. Give it a try on your machine!
这篇关于混合来自 ByteArray 的 2 个声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!