2009-08-04 6 views
7

Ich habe einige Probleme mit dem Loopen eines Sounds in Flash AS3, in dem, wenn ich den Sound zu loop ich bekomme eine leichte Verzögerung am Ende/Anfang des Audios.Bevorzugte Methode für looping Sound Flash as3

Das Audio wird korrekt abgeschnitten und spielt ohne Lücke auf dem Garagenband.

Ich weiß, dass es Probleme mit Ton im Allgemeinen in Flash, Bugs mit Kodierungen und die Ungenauigkeiten des SOUND_COMPLETE Ereignis (Und Adobe sollte mit ihrem Umgang mit diesen Fragen peinlich sein)

Ich habe versucht, das zu verwenden, Eingebautes Schleifenargument in der Wiedergabemethode der Sound-Klasse und reagiert ebenfalls auf das SOUND_COMPLETE-Ereignis, aber beide verursachen eine Verzögerung.

Aber hat irgendjemand eine Technik entwickelt, mit der man einen Sound ohne spürbare Lücke durchschleifen kann?

+0

Hey, Brian, ich sehe Sie haben Branden 'Antwort akzeptiert, aber könnten Sie mir sagen, ob Mercers Lösung funktioniert hat? Hast Du es versucht? Ich möchte lieber nicht auf das SAMPLE_DATA-Ereignis zurückgreifen, wenn ich ihm helfen kann ... – aaaidan

+0

Hmm, ich kann meine Frage beantworten: Nein. Das Aufrufen von Play in einem Event.SOUND_COMPLETE-Event-Handler beseitigt die Lücke zumindest auf OS X, FP10 nicht. – aaaidan

+0

Tatsächlich kann die Event.SOUND_COMPLETE-Ereignismethode tatsächlich funktionieren. Die Datei, die ich benutzte, hatte kleine Lücken am Anfang und am Ende. – aaaidan

Antwort

7

Wenn Sie Flash Player 10 verwenden können, verwenden Sie am besten das neue SampleDataEvent.SAMPLE_DATA-Ereignis.

Insbesondere, was Sie tun, ist zunächst den gewünschten Sound instanziieren, dann verwenden Sie die neue Methode extrahieren, um den Sound in rohe PCM-Daten in einem ByteArray codiert. Dann können Sie ein neues Sound-Objekt erstellen und auf sein SampleDataEvent. SAMPLE_DATA-Ereignis warten. Wenn dieses Ereignis aufgerufen wird, drücken Sie 2-8k (ein geringerer Wert verringert die Latenz, erhöht jedoch die Wahrscheinlichkeit hörbarer Artefakte) von Daten aus dem ByteArray. Sie werden nur sicherstellen, dass Sie, wenn Sie am Ende des ByteArray ablaufen, einfach zum Anfang zurückspringen.

Diese Methode stellt sicher, dass Sie eine lückenlose Wiedergabe haben.

+1

Dies ist eine coole Funktion und es ist möglich, einige tolle Sachen (wie Hobnox), aber es ist eine Schande, man muss auf Low-Level-Byte-Manipulation zurückgreifen, nur um eine Sound-Loop reibungslos zu spielen. Die Audio-Unterstützung im Player und die Sound-API saugen viel Zeit in Anspruch. –

+1

Es ist schade, aber diese Probleme liegen alle in der Tatsache, dass die Flash Player Sound Engine wirklich alt ist und einfach ein Update benötigt, das in Player 11 kommen sollte. –

+0

Sicher ist mehr beteiligt als play() aufrufen :) Aber klingt wie eine deterministische Lösung. Ich werde es Brandon versuchen und darauf zurückkommen. –

1

Hier ist, wie id es tat, ohne merkliche Verzögerung. Haupt 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(); 
    } 

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

Spielerklasse:

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; 
     } 
    } 
} 
} 

Sie hat gesagt, dass die MP3-Datei keine Verzögerung am Anfang/Ende hat, aber ich schlage vor dem Öffnen mit audacity, und stellen Sie sicher, es gibt keine Verzögerung .

+0

Hey Mercer, das ist im Wesentlichen der Ansatz, den ich verwendet habe, erwarte, dass es das Audio nicht jedes Mal neu positioniert, wenn die Sounds vollständig sind. Ich werde das ausprobieren und sehen, wie es funktioniert. Danke, –

+0

Hey Mercer, ich habe das gerade jetzt versucht und die Lücke ist zu auffällig für das Looping von Musik. Vielen Dank für die Freigabe Ihres Codes, tho! – aaaidan

+0

Oh, eigentlich, das Gegenteil. Es kann sein, dass diese Methode funktioniert. Der Sound, den ich benutzte, hatte am Anfang und Ende winzige Lücken. Cheers – aaaidan

3

Laut this guy müssen Sie die Musikschleife als WAV importieren und die Flash IDE selbst in MP3 komprimieren lassen. Wenn Flash importierte MP3-Daten verwendet, bedeutet das, dass es nicht weiß, wie es richtig zu loopen ist.

5

Lückenloses Looping von MP3s ist nicht trivial, da das Format funktioniert. Um ein bisschen zu vereinfachen; der Sound ist an eine Anzahl von Frames angepasst, diese Nummer kann nicht beliebig gewählt werden, stattdessen ist ein Padding (mit Stille) erforderlich. Mp3 kann nicht speichern, wie viel Padding hinzugefügt wurde, daher gehen diese Informationen verloren, sobald die Datei codiert ist.

Die Flash-IDE wird durch das Einbetten dieser Metadaten umgehen, und Sie können auch. Sie müssen nur wissen, wie viel Verzögerung der Encoder hinzugefügt hat.

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

1

Ich benutze dieses große Werkzeug: http://www.compuphase.com/mp3/mp3loop.zip

Sie geben eine WAV-Datei und es gibt eine MP3-Datei, die perfekt sein kann gespielt Sound ‚s Standard play Methode - zum Beispiel (und spaltfrei!):

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

Sie auch die Ausgabe MP3-Datei nehmen und es in eine WAV (mit Traildevils zum Beispiel) erneut konvertieren - dann haben Sie eine lückenlose WAV (die großen innerhalb der FLA-Datei arbeiten kann)

Ich hoffe, es hilft

+0

können Sie int.MAX_VALUE verwenden – mika

0

Ich wollte eine Bibliothek für das Schleifen von Audio erstellen, die sich nicht auf COMPLETE-Ereignisse verlassen. Ich entschied mich, meine eigene standingwave3 addons library zu erstellen. Überprüfen Sie das Original standingwave3 project by MaxL0rd. Meiner Arbeit ist im Gange und es macht die Arbeit erledigt, auf der Byte-Ebene für diese Angelegenheit (Keine Schleifen-Timer oder irgendetwas). Es funktioniert, indem ein Sound mit Anfangs- und Endpunkten aufgenommen wird. Dann klont es die Schleife mehrmals basierend auf der Zeit in Sekunden. Es sollte einfach zu verwenden sein. Dies ist der Code für die Main.as Klasse in der "Looping" Datei im "Beispiele" -Ordner:

package 
{ 

    // Imports. 
    import com.greensock.events.LoaderEvent; 
    import com.greensock.loading.LoaderMax; 
    import com.greensock.loading.MP3Loader; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import com.greensock.TweenMax; 
    import com.SW3.gadget.LoopGadget; 
    import flash.media.Sound; 


    // Class. 
    public class Main extends Sprite 
    { 

     // Vars. 
     private var loader:LoaderMax;// Using LoaderMax for ease of use. 


     // Constructor. 
     public function Main() 
     { 

      trace("Main"); 

      loader = new LoaderMax({ name:"audio", onComplete:onSoundsLoaded }); 
      loader.append(new MP3Loader("assets/Beat.mp3", { autoPlay:false })); 
      loader.append(new MP3Loader("assets/Clap.mp3", { autoPlay:false })); 
      loader.append(new MP3Loader("assets/Boom.mp3", { autoPlay:false })); 
      loader.load(); 

     } 


     private function onSoundsLoaded(e:LoaderEvent):void 
     { 

      trace("onSoundsLoaded"); 
      var looping:LoopGadget = new LoopGadget; 
      looping.addLoopSound("Beat", e.currentTarget.content[ 0 ] as Sound, 0, 10); 
      looping.addLoopSound("Clap", e.currentTarget.content[ 1 ] as Sound, 0, 10); 
      //looping.addLoopSound("Boom", e.currentTarget.content[ 2 ] as Sound, 0, 10); // Commented out to test possible error. 

      looping.playLoop("Beat");// Play the "Beat" loop. 
      looping.playLoop("Clap");// Play the "Clap" loop. 
      looping.stopLoop("Beat");// Stop the "Beat" loop. 
      looping.playLoop("Beat");// Play the "Beat" loop. 
      looping.playLoop("Beat");// Play the "Beat" loop again to test if it would error out.. 

      looping.stopAllLoops();// Stop all the loops. 
      looping.playLoops([ "Beat", "Clap", "Boom" ]);// Play all the loops. Test to see if "Boom" will error out. 

     } 

    } 

} 

Schauen Sie sich die Quelldateien hier: https://github.com/charlesclements/standingwave3-addons