问题
I've found some excellent demos of how to mix together sound objects together for live playback. See the working example bellow...
But can it be done programmatically without any playback so I can just output the mixed file? Also I'll be adding some volume change info along the way so it'll need to be added in small chunks like how the play buffer works.
[Embed(source = "audio/track01.mp3")]
private var Track1:Class;
[Embed(source = "audio/track02.mp3")]
private var Track2:Class;
[Embed(source = "audio/track03.mp3")]
private var Track3:Class;
[Embed(source = "audio/track04.mp3")]
private var Track4:Class;[Embed(source = "AudioMixerFilter2.pbj",mimeType = "application/octet-stream")]
private var EmbedShader:Class;
private var shader:Shader = new Shader(new EmbedShader());
private var sound:Vector.<Sound> = new Vector.<Sound>();
private var bytes:Vector.<ByteArray> = new Vector.<ByteArray>();
private var sliders:Vector.<Number> = new Vector.<Number>();
private var sliderVol:int = 1;
private var BUFFER_SIZE:int = 0x800;
public var playback:Sound = new Sound();
public function startAudioMixer(event:FlexEvent):void{
sound.push(new Track1(), new Track2(), new Track3(), new Track4());
sliders.push(sliderVol,sliderVol,sliderVol,sliderVol);
playback.addEventListener(SampleDataEvent.SAMPLE_DATA, onSoundData);
playback.play();
}
private function onSoundData(event:SampleDataEvent):void {
for(var i:int = 0; i < sound.length; i++){
bytes[i] = new ByteArray();
bytes[i].length = BUFFER_SIZE * 4 * 2;
sound[i].extract(bytes[i], BUFFER_SIZE);
var volume:Number = 0;
bytes[i].position = 0;
for(var j:int = 0; j < BUFFER_SIZE; j++){
volume += Math.abs(bytes[i].readFloat());
volume += Math.abs(bytes[i].readFloat());
}
volume = (volume / (BUFFER_SIZE * .5)) * sliderVol; // SLIDER VOL WILL CHANGE
shader.data['track' + (i + 1)].width = BUFFER_SIZE / 1024;
shader.data['track' + (i + 1)].height = 512;
shader.data['track' + (i + 1)].input = bytes[i];
shader.data['vol' + (i + 1)].value = [sliders[i]];
}
var shaderJob:ShaderJob = new ShaderJob(shader,event.data,BUFFER_SIZE / 1024,512);
shaderJob.start(true);
}
回答1:
Easiest way would be to just forget about the Pixel Bender stuff.
Once the Sounds are loaded, use an ENTER_FRAME that uses Sound.extract to get a smallish ByteArray from each Sound, then read through all four extracted ByteArrays doing some basic math to arrive at the 'mixed' values for the left & right signals. Write those values to the "final/mixed/output" ByteArray. Repeat the process each frame until you're at the end of the sounds. If the Sounds aren't all the identical length, you'll need to figure out how to handle that as well.
If you need to perform a mix where the amplitude of each track changes over time, it'd be a good challenge, but would take time to set up.
While you're at it, check out Andre Michelle's Tonfall project... It's a complex but great place to start with understanding the ins/outs of audio in AS3.
来源:https://stackoverflow.com/questions/3570708/programmatically-mixdown-of-audio-tracks-no-playback