Prefered method for looping sound flash as3

16,868

Solution 1

The most reliable method, if you can use Flash Player 10, is to use the new SampleDataEvent.SAMPLE_DATA event.

Specifically, what you do is to first instantiate the sound you want, then use the new extract method to convert the sound into raw PCM data encoded in a ByteArray. Then you can create a new Sound object, and setup to listen for it's SampleDataEvent.SAMPLE_DATA event. When that event is called you'll push 2-8k (a lower amount reduces latency, but increases the possibility of audible artifacts) of data from the ByteArray. You'll just make sure that as you run off the end of the ByteArray you'll just loop back to the beginning.

This method ensures that you'll have fully gapless playback.

Solution 2

Gapless looping of mp3's is not trivial due to the way the format works. To simplify a bit; the sound is fitted to a number of frames, this number cannot be chosen arbitrarily, instead some padding (with silence) is required. Mp3 has no way of storing how much padding was added, so this information is lost once the file is encoded.

The flash IDE get's around this by embedding this metadata, and you can too. You just need to know how much delay is added by the encoder.

Andre Michelle explains this way better than I can on his blog.

Solution 3

According to this guy, you have to import the music loop as a wav, and have the Flash IDE itself compress to mp3. Having Flash use imported mp3 data means that it won't know how to loop it properly.

Solution 4

Here is how id did it, with no noticeable delay. Main app:

package {

import flash.display.MovieClip; 
import flash.events.*;
import flash.utils.*;

public class MainApp extends MovieClip {
  private var player:Player;
  ..........

  public function MainApp() {
      .......
      player = new Player();
      player.addEventListener(Player.EVENT_SOUND_COMPLETED, handleSoundCompleted);
      ......
  }

  private function handleSoundCompleted(event:Event):void {
      player.setPosition(0);
      player.play();
  }

  .................

Player class:

package {

import flash.events.*;
import flash.media.*;
import flash.net.*;

public class Player extends EventDispatcher {

    private var sound:Sound;
    private var channel:SoundChannel;
    private var position:Number;

    static const SOUND_VOLUME:Number = 0.75;
    static const EVENT_SOUND_COMPLETED:String = "SOUND_COMPLETED";

    public function Player() {

        // init
        sound = new ThemeSong();
        position = 0;

        // listeners
        sound.addEventListener(IOErrorEvent.IO_ERROR, function(event:Event){trace(event)});

        trace("Player initialized...");
    }

    public function play():void {
        channel = sound.play(position);
        channel.soundTransform = new SoundTransform(SOUND_VOLUME);
        channel.addEventListener(Event.SOUND_COMPLETE, function(event:Event){dispatchEvent(new Event(EVENT_SOUND_COMPLETED));});
        trace("Player playing..");
    }

    public function pause():void {
        if (channel != null) {
            channel.stop();
            position = channel.position;
        }
        trace("Player paused..");
    }

    public function setPosition(pos:Number):void {
        position = pos;
    }

    public function getPosition():Number {
        if (channel == null) {
            return 0;
        } else {
            return channel.position;
        }
    }
}
}

You did say that the mp3 file has no delay at beginning/end, but I suggest opening it with audacity, and make sure there is no delay.

Solution 5

I use this great tool: http://www.compuphase.com/mp3/mp3loop.zip

You give it a WAV file and it returns an MP3 file which can be perfectly (and gaplessly!) played using Sound's standard play method - e.g. :

var manyLoops:int = 1000*1000; // a Million is a lot :)
mySound.play(0, manyLoops); 

You can also take the output MP3 file and re-convert it to a WAV (using AudioCity for example) - then you have a gapless WAV (which can work great inside your FLA file)

Hope it helps

Share:
16,868
BefittingTheorem
Author by

BefittingTheorem

Updated on June 04, 2022

Comments

  • BefittingTheorem
    BefittingTheorem almost 2 years

    I'm having some issues with looping a sound in flash AS3, in that when I tell the sound to loop I get a slight delay at the end/beginning of the audio.

    The audio is clipped correctly and will play without a gap on garage band.

    I know that there are issues with sound in general in flash, bugs with encodings and the inaccuracies with the SOUND_COMPLETE event (And Adobe should be embarrassed with their handling of these issues)

    I have tried to use the built in loop argument in the play method on the Sound class and also react on the SOUND_COMPLETE event, but both cause a delay.

    But has anyone come up with a technique for looping a sound without any noticeable gap?

  • Juan Pablo Califano
    Juan Pablo Califano almost 15 years
    This is a cool feature and it's made possible some awesome stuff (like hobnox), but it's a shame one must resort to low level byte manipulation just to play a sound loop smoothly. The audio support in the player and the sound API suck big time.
  • Tyler Egeto
    Tyler Egeto almost 15 years
    It is too bad, but these problems all lie in the fact that the Flash Player sound engine is really old, and simply needs an update, which should be coming in player 11.
  • BefittingTheorem
    BefittingTheorem almost 15 years
    Hey there Mercer, this is essentially the approach I've been using, expect it do not re-position the audio each time the sounds completes. I'll give that a go and see how it works out. Thanks
  • BefittingTheorem
    BefittingTheorem almost 15 years
    Certainly is more involved than calling play() :) But sounds like a deterministic solution. I'll give it a try Brandon and get back to you on it.
  • aaaidan
    aaaidan almost 14 years
    Hey Mercer, I've tried this just now and the gap is too noticeable for looping music. Thanks for sharing your code, tho!
  • aaaidan
    aaaidan almost 14 years
    Man, that gets me so pissed off that you have to resort to this! Such a ludicrously CPU and memory intensive thing to do just to get music to loop seamlessly!
  • aaaidan
    aaaidan almost 14 years
    Oh actually, reverse that. It may be that this method works. The sound I was using had tiny gaps at the start and end. Cheers
  • Sonaten
    Sonaten about 12 years
    @Branden Hall, I'm looking to apply your method for looping a multitude of sound clips (running parallel with eachother), and I would like it if I could see an example of how the algorithm can be done. Sample-code, pseudo-code/algorithm, anything would be appreciated.
  • mika
    mika over 10 years
    you can use int.MAX_VALUE