Reputation: 73
So I'm making a simple flash game. Basically I have a turntable that goes on for 30 seconds with a couple of sample music that adds up together in multiple layers of sound to form a final song.
Now I would like to be able to record and play the sounds at the end of the game.
I've created a SoundFx class that takes mp3 audio and turns it into byteArrays with the hope to mix the audios in to the same Sound channel.
Now I've reached a certain impass since I cannot properly mix the bytearrays. I'm starting to think it's not possible to encode the byte Arrays as you add the channels to the mix.
I'd love to be guided in the right direction. I'm not sure if the best way to proceed from here, even just the playback would be nice. Creating a button log would probably fix the playback and mixing the audio in a second run to go straight to the file. but it sure seems like a long path to achieve this.
Many thanks and apologies for my crappy english in advance
David R.
some code on the matter:
private var srcSound:Sound;
private var sound1:Sound;
private var sound2:Sound;
private var soundChannel:SoundChannel;
private var bytes:ByteArray;
private var incbytes:ByteArray;
private var mixedBytes:ByteArray;
public var pitchShiftFactor:Number;
public var position:Number;
public var AddSound:Boolean = false;
public var incremental:Number;
public var left1:Number;
public var left2:Number;
public var right1:Number;
public var right2:Number;
public var mixedBytes1:Number;
public var mixedBytes2:Number;
public function SoundFx() {
}
public function playFx(srcSound:Sound):void{
this.srcSound = srcSound;
position = 0;
var morphedSound:Sound = new Sound();
morphedSound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler);
soundChannel = morphedSound.play();
}
public function addSound(sound1:Sound , sound2:Sound):void{
this.sound1 = sound1;
this.sound2 = sound2;
sound1.addEventListener(SampleDataEvent.SAMPLE_DATA, addSampleData);
position = 0;
soundChannel = sound1.play();
soundChannel = sound2.play();
AddSound = true;
}
private function addSampleData(event:SampleDataEvent):void{
position = 0;
var incbytes:ByteArray = new ByteArray();
position += sound1.extract(incbytes, 4096, position);
var bytes:ByteArray = new ByteArray();
position += sound2.extract(bytes, 4096, position);
event.data.writeBytes(mixBytes(bytes, incbytes));
}
private function sampleDataHandler(event:SampleDataEvent):void
{
var bytes:ByteArray = new ByteArray();
position += srcSound.extract(bytes, 4096, position);
event.data.writeBytes(editBytes(bytes));
}
private function mixBytes(bytes1:ByteArray , bytes2:ByteArray ):ByteArray{
bytes.position = 0;
incbytes.position = 0;
var returnBytes:ByteArray = new ByteArray();
while(bytes1.bytesAvailable > 0)
{
left1 = bytes1.readFloat();
left2 = bytes2.readFloat();
right1 = bytes1.readFloat();
right2 = bytes2.readFloat();
mixedBytes1 = left1 + left2;
mixedBytes2 = right1 + right1;
mixedBytes.writeFloat(mixedBytes1);
mixedBytes.writeFloat(mixedBytes2);
}
return mixedBytes;
}
private function editBytes(bytes:ByteArray):ByteArray{
//var skipCount:Number = 0;
var returnBytes:ByteArray = new ByteArray();
bytes.position = 0;
while(bytes.bytesAvailable > 0)
{
//skipCount++;
returnBytes.writeFloat(bytes.readFloat());
returnBytes.writeFloat(bytes.readFloat());
}
return returnBytes;
}
}
Upvotes: 1
Views: 303
Reputation: 6417
i think i get your idea,hope i did.
You should try to pass all of your SoundChannel classes (sound layers being added) to a SoundMixer class (there is plenty of info on this in adobe site),like a funnel,and then add a SAMPLEDATA event listener to that soundmixer, and capture the byte array of that sound mixer,it is like getting the byte array of the final mixdown...then encode those bytes to wav or mp3
.
Sorry i can not write that code down for you,i am not very good with the code yet, but im good at mixing sounds.
Here is an example form adobe site itself:
function loaded(event:Event):void
{
outputSnd.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound);
outputSnd.play();
}
Useful link: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html
soundmixer class link: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundMixer.html
Upvotes: 2
Reputation: 4434
experimenting with stratus (cirrus) internet radio i used SoundMixer.computeSpectrum()
on the server side and passed that data to the client side with NetStream.send()
for drawing and playback.
It worked, but was very ram hungry with client and server on one computer (and with several songs loaded and converted to raw audio data :)
so, try computeSpectrum()
, it seems perfect for creating an "audio log"
Upvotes: 0