7
votes

Méthode préférée pour la boucle Son Flash AS3

J'ai des problèmes avec une boucle en boucle d'un son dans Flash AS3, dans ce que, lorsque je dis au son de la boucle, je reçois un léger délai à la fin / début de l'audio.

L'audio est correctement coupé et jouera sans écart sur bande de garage.

Je sais qu'il existe des problèmes avec le son en général en général, des bugs avec des codages et des inexactitudes avec l'événement Sound_Compléte (et Adobe devraient être gênés avec leur manipulation de ces problèmes)

J'ai essayé d'utiliser l'argument de boucle intégré dans la méthode de lecture sur la classe sonore et de réagir sur l'événement Sound_Compléte, mais ces deux causent un délai.

Mais quelqu'un a-t-il proposé une technique pour boucler un son sans écart perceptible?


4 commentaires

Hé, Brian, je vois que vous avez accepté la réponse de Branden, mais pourriez-vous me dire si la solution de Mercer a fonctionné? Est-ce que tu l'as essayé? Je préfère ne pas recourir à l'événement Sample_Data si je peux l'aider ...


Hmm, je peux répondre à ma question: non. Calling Play dans un événement Event.Sound_Compléte Manutention n'élimine pas l'écart, du moins sur OS X, FP10.


En fait, la méthode événementielle Event.Sound_Complet peut réellement fonctionner. Le fichier que j'utilisais avait de petites lacunes au début et à la fin.


@aaaidan dans mon expérience La solution proposée par @mercer a toujours de bonnes chances d'avoir des retards notables. Il semble que @grapefrukt et Youseld ait frappé des problèmes importants concernant des métadonnées supplémentaires pour aider avec boucle.


6 Réponses :


1
votes

Voici comment identifiant l'identifiant, sans retard notable. Application principale:

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


3 commentaires

Hé, Mercer, c'est essentiellement l'approche que j'ai utilisée, vous attendez pas à ne pas ré-positionnez l'audio chaque fois que les sons complètent. Je vais donner ça aller et voir comment ça marche. Merci


Hey Mercer, j'ai essayé ceci juste maintenant et l'écart est trop perceptible pour la musique en boucle. Merci d'avoir partagé votre code, Tho!


Oh en fait, inverser ça. Il se peut que cette méthode fonctionne. Le son que j'utilisais avait de minuscules lacunes au début et à la fin. Acclamations



7
votes

La méthode la plus fiable, si vous pouvez utiliser Flash Player 10, il est d'utiliser le nouvel événement SamplateAtevent.sample_Data.

Spécifiquement, ce que vous faites est de créer d'abord le son souhaité, puis utilisez la nouvelle méthode d'extrait pour convertir le son en données PCM brutes codées dans un byTareRay. Ensuite, vous pouvez créer un nouvel objet sonore et configurer pour écouter son événement SampleDatevent.sample_Data. Lorsque cet événement est appelé, vous appuyez sur 2-8K (une quantité inférieure réduit la latence, mais augmente la possibilité d'artefacts audibles) des données de la byearray. Vous vous assurerez que lorsque vous courez la fin de la byTeArray, vous ferez une boucle au début.

Cette méthode garantit que vous aurez une lecture entièrement sans défaut.


5 commentaires

Ceci est une caractéristique fraîche et il est possible de faire quelques trucs impressionnants (comme Hobnox), mais il est dommage qu'il faut recourir à la manipulation d'octets de niveau basse pour jouer une boucle sonore sans heurts. Le support audio dans le joueur et l'API sonore sucent BIG TIME.


C'est dommage, mais ces problèmes sont tous réalisés dans le fait que le moteur de son Flash Player est vraiment ancien et a simplement besoin d'une mise à jour, qui devrait venir dans le joueur 11.


Est certainement plus impliqué que d'appeler la lecture () :) mais sonne comme une solution déterministe. Je vais lui donner un try brandon et vous recontacterai dessus.


Homme, ça me fait chier tellement énervé que vous devez recourir à cela! Un tel objet de la CPU et de la mémoire de manière rigoureuse à faire juste pour faire boucle de musique de manière transparente!


@Branden Hall, je cherche à appliquer votre méthode pour boucler une multitude de clips sonores (en cours d'exécution parallèlement à chaque fois), et je l'aimerais si je pouvais voir un exemple de la manière dont l'algorithme peut être fait. Code de l'échantillon, pseudo-code / algorithme, tout serait apprécié.



3
votes

Selon Ce gars , vous devez importer La boucle de musique en tant que WAV et que l'IDE flash elle-même comprime en mp3. Avoir une utilisation flash importée des données MP3 importées signifie qu'il ne saura pas la boucle correctement.


0 commentaires

5
votes

La boucle sans défaut de MP3 n'est pas triviale en raison de la manière dont le format fonctionne. Pour simplifier un peu; Le son est monté sur un certain nombre de cadres, ce nombre ne peut pas être choisi arbitrairement, à la place d'un rembourrage (avec silence) est requis. MP3 n'a aucun moyen de stocker combien de remplissage a été ajouté. Cette information est donc perdue une fois que le fichier est codé.

L'IDE Flash Get est autour de cela en incorporant cette métadonnée et vous pouvez aussi. Vous avez juste besoin de savoir combien de temps est ajouté par le codeur.

André Michelle explique ainsi mieux que je ne peux que sur son blog < / a>.


0 commentaires

1
votes

J'utilise ce grand outil: http://www.cofuphase.com/mp3/mp3loop.zip

vous Donnez-lui un fichier WAV et renvoie un fichier MP3 qui peut être parfaitement (et sans erreur!) Joué à l'aide de standard STANDARD Play : xxx

Vous pouvez également prendre le fichier MP3 de sortie et le reconstituer à un WAV (à l'aide de l'audiocity par exemple) - alors vous avez une solution sans manche (qui peut fonctionner bien Dans votre fichier FLA)

espère qu'il aide


1 commentaires

Vous pouvez utiliser int.max_value



0
votes

Je voulais créer une bibliothèque pour boucler audio qui ne s'appuie pas sur des événements complets. J'ai décidé de créer mon propre Library de Permwave3 Addons . Découvrez l'original Projetwave3 Projet de MAXL0RD . Les miens un travail en cours et le travail fait le travail, au niveau des octets de cette affaire (pas de minuterie de boucle ni rien). Cela fonctionne en prenant un son avec des points de boucle de début et de fin. Ensuite, il close de l'échantillon de boucle un tas de fois en fonction du temps prévu en quelques secondes. Il devrait être simple à utiliser. Ceci est le code de la classe principale.As dans le Fichier "Looping" dans le dossier "Exemples":

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.

        }

    }

}


0 commentaires