I worked on a similar system for a while, I will do my best to give you some direction:
Your sample code does not actually mix MP3s - it creates 2 more sounds to play downloaded MP3s through SampleDataEvent. What you need to do is create only one “output” sound file that will hold / play the resulting mixed sound. You can easily save this data as it happens, and subsequently save this 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 mp3s are fully loaded, or run the input frame to determine when both sounds are no longer buffered (Sound.isBuffering)
when mp3 is 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 limit the possible output to -1/1. Do it. This is not highly optimized!
Ok so the easy part! The hard part really converts the final byteArray to MP3. Sound exists in Flash as PCM / uncompressed data, MP3 is obviously a compressed format. This "answer" is already too long, and I gathered all this information from several very smart people.
You can easily adapt "MicRecorder" to a universal sound recorder: http://www.bytearray.org/?p=1858
converting to MP3 will be a bitch: Thibault has another record on ByteArray.org - search for LAME MP3.
Great example / resource: http://www.anttikupila.com/flash/soundfx-out-of-the-box-audio-filters-with-actionscript-3/
Check out the open source André Michel project "Tonfall" in Google code.
Check out Kevin Goldsmith's blog and lab - he got a great example of using Pixel Bender with all this frenzy.
hope this helps!
PS - taking a replica from Andre, the optimal length of the sound buffer should be 3072. Try it on your computer!