开发者

actionscript - syncronizing 2 sound channels?

I am using 2 sound channels to play 2 separate, externally loaded mp3 files at the same time. Right now I have the play button tied to a function that starts the first mp3, then the 2nd. The problem is - the 2nd mp3 starts a few milliseconds after the first. Is there a way that I can make sure these 2 start playing at the exact same time?

function playMusic(evt:MouseEvent):void
{

    channel = myMusic.play(songPosition);
    channel2 = myMusic2.play(songPosition);
    myTimer.start();
    btnPlay.mouseEnabled = false;
}

Edit: I found a clumsy workaround that matches the TIMER for the 2 audio sources. It works, but now I have a hiccup at the beginning while i tries to ma开发者_StackOverflow中文版tch:

    function updateTime(evt:TimerEvent):void
    {
        lblSongTime.text = convertTime(channel.position);
        if(channel.position!=channel2.position){   
 trace("out of sync")                
 SoundMixer.stopAll()
    channel = myMusic.play();
    channel2 = myMusic2.play(channel.position);

        }
    }


If you're targeting flash player 10+, then you can use the sampleData event and extract method of the sound class to combine the two sounds.

Basically, you'll want to make a Sound subclass that handles the sampleData event by passing the position to the extract method of each of the two sounds you want to play. Then, you'll combine the two ByteArrays and insert that into the event's data member.

The main thing to be careful about is that you can only give a maximum of 8k of data (if I remember correctly) to the sampleData event at a time. You'll also probably want to average the two sounds, or at least reduce the volume when combining the sounds.

It's been a little while since I've written actionscript, so it'd take me a little time to write up some code for you, but if you still need help, let me know and I'll try to give you more info or some code.

EDIT

Here's a minimal class that'll do what you want. You should add error checking and you may need to add stuff to handle sound transforms (e.g. volume adjustment) as using the sample data event may ignore a sound transform you apply at play (I don't remember, but it shouldn't be too hard for you to figure that out ^_^)...

import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.utils.ByteArray;

public class DualSound extends Sound {
    private var sa:Sound;
    private var sb:Sound;

    public function DualSound(a:Sound, b:Sound) {
        super();

        sa = a;
        sb = b;

        addEventListener(SampleDataEvent.SAMPLE_DATA, handleSampleData);
    }

    private function handleSampleData(e:SampleDataEvent):void {
        var ba:ByteArray, bb:ByteArray;

        ba = new ByteArray();
        bb = new ByteArray();

        sa.extract(ba, 8 << 10, e.position);
        sb.extract(bb, 8 << 10, e.position);
        ba.position = 0;
        bb.position = 0;

        while(ba.bytesAvailable > 0 && bb.bytesAvailable > 0) {
            e.data.writeFloat((ba.readFloat() + bb.readFloat()) / 2);
        }
        if(ba.bytesAvailable > 0) {
            e.data.writeBytes(ba, ba.position, ba.bytesAvailable);
        } else if(bb.bytesAvailable > 0) {
            e.data.writeBytes(bb, bb.position, bb.bytesAvailable);
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜