混合 ByteArray 中的 2 个声音

发布于 2024-10-27 07:27:56 字数 1347 浏览 1 评论 0原文

我已经构建了一个混音器并将所有序列保存在一个数组中,然后再次播放,现在我想将混音保存为 MP3,我已经寻找任何方法来保存混音,答案是将声音加载为 byteArrays (sound.extract)我已经完成了这一点,但我真的不知道如何将所有声音存储在一个 ByteArray 中以便将其另存为 MP3,我得到了这段代码,例如,加载 2 个音频文件并将它们存储在单独的 ByteArray,并播放每种声音,有人知道如何将 2 个 byteArray 存储在一个中吗?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陪你搞怪i 2024-11-03 07:27:56

我已经在类似的系统上工作了一段时间,我会尽力为您提供一些指导:

您的示例代码并没有真正混合 MP3 - 它创建了另外 2 个声音来通过 SampleDataEvent 播放加载的 MP3。您需要做的就是创建一个“输出”声音文件,该文件将保存/播放生成的混合声音。您可以轻松地保存该数据,然后将该文件另存为新的 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 完全加载,要么运行输入帧来确定当

mp3 准备好时两个声音何时不再缓冲 (Sound.isBuffering ):

// 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。做吧。这是极其未优化的!

好的。这就是最简单的部分!困难的部分是将最终的 byteArray 转换为 MP3。音频以 PCM/未压缩数据形式存在于 Flash 中,MP3 显然是一种压缩格式。这个“答案”已经太长了,所有这些信息都是我从几个非常聪明的人那里收集的。

您可以轻松地将“MicRecorder”改编为通用声音数据记录器:
http://www.bytearray.org/?p=1858

转换为 MP3 将是婊子:Thibault 在 ByteArray.org 上还有另一篇文章 - 搜索 LAME MP3。

优秀的例子/资源:
http://www. anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/

在 Google 代码上查找 Andre Michelle 的开源“Tonfall”项目。

查阅 Kevin Goldsmith 的博客和实验室 - 他有关于利用 Pixel Bender 进行疯狂操作的绝佳示例。

希望这有帮助!

PS - 根据 Andre 的提示,音频缓冲区的最佳长度应该是 3072。在您的机器上尝试一下!

been working on a similar system for a while, I'll do my best to give you some direction:

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();

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 )

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++;

  }
}

Yes - you should really cap the possible output at -1/1. Do it. This is extremely un-optimized!

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.

You can easily adapt 'MicRecorder' to be a generic Sound data recorder:
http://www.bytearray.org/?p=1858

converting to MP3 will be a bitch: Thibault has another post on ByteArray.org - search for LAME MP3.

Excellent example/resource:
http://www.anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/

Look up Andre Michelle's open source 'Tonfall' project on Google code.

Look up Kevin Goldsmith's blog and labs - he's got great example on utilizing Pixel Bender with all this madness.

hope this helps!

PS - taking a cue from Andre, the optimal length of the audio buffer should be 3072. Give it a try on your machine!

何必那么矫情 2024-11-03 07:27:56

如果我正确理解您的问题,您需要读取每个样本的浮点数据,对它们求和,然后将结果值写入新的音频流中。这将给出完全 50/50 的混合。

我现在无法访问带有编译器的机器,但它应该是这样的(假设 bytes1 和 bytes2 是两个长度相等的 ByteArray 对象):

for (int bcnt = bytes1.size(); bcnt; bcnt--)
    bytes1.setByte(bcnt - 1, bytes2.getByte(bcnt - 1) + bytes1.getByte(bcnt - 1));

当然,您可能想要进行某种溢出检查,但这应该足以让您走上正轨。

If I understand your question properly, you need read the floating point data for each sample, sum them, and write the resulting value into your new audio stream. This would give a stright 50/50 mix.

I don't have access to a machine with a compiler right now, but it should be something like this (assuming bytes1 and bytes2 are two ByteArray objects of equal length):

for (int bcnt = bytes1.size(); bcnt; bcnt--)
    bytes1.setByte(bcnt - 1, bytes2.getByte(bcnt - 1) + bytes1.getByte(bcnt - 1));

Of course, you would probably want to do some sort of overflow check, but that should be enough to put you on the right track.

为你拒绝所有暧昧 2024-11-03 07:27:56

如果您有未压缩音频,则只需将 ByteArray 中各个数组元素的值相加即可。但您还必须处理最大/最小值的上限(无溢出)。可以肯定的是,没有任何东西可以与混合 MP3 等效 - 因此您可能必须再次解码、混合并编码为 MP3。

if you have uncompressed audio, you can just add up the values of individual array elements in your ByteArray's. But you also have to handle capping for max/min values (no overflows). Pretty sure there is nothing equivalent for mixing MP3s - so you might have to decode, mix, and encode to MP3 again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文