ulfben icon

SoundManager

ulfben | PRO | 12/03/11 12:26:38 PM UTC | 0 ⭐ | 10976 👁️ | Never ⏰ | []
ActionScript |

9.01 KB

|

None

|

0 👍

/

0 👎

/*
 * SoundManager
 * Loads a tracklist and handles all SFX and music needs for our games.
 *  see tracklist.xml (http://pastebin.com/1imV9pM0) for examples of all the features:
 *  track stitching, looping, offsets, volume, fadein/out, audio position with owner movieclips etc.
 *
 * The "event" system is an idea borrowed from FMOD.
 *
 * Ulf Benjaminsson, 2009-06-15
 * */
 
import com.ulfben.noname.utils.SuperSound;
import com.ulfben.noname.utils.TextLoader;
import com.ulfben.noname.utils.Utils;
 
 class com.ulfben.noname.utils.SoundManager extends com.ulfben.noname.utils.Broadcaster {
    private var _tracklistURL:String = "xml/tracklist.xml";
    private var _tracks:Object;
    private var _basedir:String;
    private var _owners:Array;
    private var _playCount:Object;
    public static var DEFAULT_OWNER:MovieClip;
 
    public function SoundManager() {
        _global["SoundManager"] = this;
        _root["SoundManager"] = this;
        _basedir = "";
        _playCount = { };
        DEFAULT_OWNER = _root.createEmptyMovieClip("soundman", _root.getNextHighestDepth());
        var tl:TextLoader = new TextLoader(_tracklistURL);
        tl.addEventListener("onLoad", this, "onTrackListAvaliable");
        tl.loadFile();
    }
 
    public static function get():SoundManager{
        if (_global["SoundManager"] == undefined) {
            _global["SoundManager"] = new SoundManager();
        }
        return SoundManager(_global["SoundManager"]);
    }
 
    public function playEvent(name:String, owner:MovieClip):Void {
        if (!canPlayMore(name)) { return; }
        if (owner == undefined) { owner = DEFAULT_OWNER; }
        var event:Object = getEventForOwner(name, owner);
        var s:SuperSound = event._s;
        if (s == undefined) { return; }
        replaces(name, owner); //stop all events this one replaces.
        if (event._stream && _tracks[name][owner]._offset == 0) {
            s.setLoopsForStream(event._loops);
            s.loadSound(true);//stream whenever we can; offsets (somewhat...) our lack of preloading.
        }else {
            if (!s.isLoaded()) { //if it hasn't made it to the cache yet
                s.loadSound(false); //request it again.
            }
            s.setOffset(event._offset);
            s.start(event._loops); //push the button and pray it is in place and will play.
        }
        if (event._maxcount > 0 && s.isPlaying()) {
            _playCount[name] = isNaN(_playCount[name]) ? 1 : _playCount[name] += 1;
        }
        if(event._fadein > 0) {
            fadeIn(name, owner, event._volume, event._fadein);
        }else{
            s.setVolume(event._volume);
        }
        if(event._follow) {
            s.panWith(owner);
        }
        if(event._leadsto != "") { //stitch events together
            s.addEventListener("onSoundComplete", this, "playNextInQue");
        }
        if(event._maxcount > 0) {
            s.addEventListener("onSoundComplete", this, "decreasePlayCount");
            s.addEventListener("onSoundStop", this, "decreasePlayCount");
        }
    }
 
    public function stopAll():Void {
        for (var i:Number = 0; i < _tracks.length; i++) {
            var event:String = _tracks[DEFAULT_OWNER]._name;
            for (var j in _tracks) {
                stopEvent(event, j);
            }
        }
        _playCount = { };
    }
 
    public function stopEvent(name:String, owner:MovieClip):Void {
        if (owner == undefined) {
            for (var i:Number = _owners.length; i >= 0; i--) {
                if (_owners == undefined) { continue;}
                stopEvent(name, _owners);
            }
            stopEvent(name, DEFAULT_OWNER);
        }
        var s:SuperSound = _tracks[name][owner]._s;
        s.removeEventListener("onSoundComplete", this, "playNextInQue");
        s.removeEventListener("onSoundComplete", this, "decreasePlayCount");
        if (_tracks[name][owner]._fadeout == 0) {
            s.stop();   //calls decreasePlayCount for us
        }else {
            fadeOutAndStop(name, owner, _tracks[name][owner]._fadeout);
        }
    }   
 
    public function unregisterAllOwners():Void {
        for (var i:Number = _owners.length; i >= 0; i--) {
            unregisterMe(_owners, i);
        }
        _owners = [];
    }
 
    public function unregisterMe(owner:MovieClip, pruneIndex:Number):Void {
        if (owner == DEFAULT_OWNER || owner == undefined) { return; }
        if(pruneIndex == undefined){
            pruneIndex = Utils.Find(owner, _owners);
        }
        if (owner == _owners[pruneIndex]) {
            _owners.splice(pruneIndex, 1);
        }
        for (var i:Number = 0; i < _tracks.length; i++) {
            _tracks[owner] = undefined;
        }
    }   
 
    public function fadeOutAndStop(name:String, owner:MovieClip, time:Number):Void {
        if (time == undefined) { time = 0.5; }
        if (owner == undefined) { owner = DEFAULT_OWNER; }
        _tracks[name][owner]._s.fadeTo(0, time, true);
    }
 
    public function fadeIn(name:String, owner:MovieClip, target:Number, time:Number):Void {
        if (time == undefined) { time = 0.5; }
        var event:Object = _tracks[name][owner];
        event._s.setVolume(0);
        event._s.fadeTo(target, time, false);
    }   
 
    public function fadeTo(name:String, owner:MovieClip, target:Number, time:Number) {
        _tracks[name][owner]._s.fadeTo(target, time, false);
    }   
 
    public function playEventDelayed(name:String, owner:MovieClip, delay:Number):Void {
        _global.setTimeout(this, "playEvent", delay, name);//todo, how do we pass owner?
    }
 
    private function getEventForOwner(name:String, owner:MovieClip):Object {
        if (owner == undefined) { owner = DEFAULT_OWNER;}
        var event:Object = _tracks[name][owner];
        if (event != undefined) {
            return event;
        }
        if (_tracks[name][DEFAULT_OWNER] == undefined) { return; } //don't load events we haven't defined.
 
        var newEvent:Object = cloneEvent(_tracks[name][DEFAULT_OWNER]);
        _owners.push(owner);
        newEvent._owner = owner;
        newEvent._s = new SuperSound(newEvent._name, _basedir + newEvent._file, owner);
        _tracks[name][owner] = newEvent;
        return newEvent;
    }
 
    private function canPlayMore(name:String):Boolean {
        var max:Number = _tracks[name][DEFAULT_OWNER]._maxcount;
        if (max == 0) { return true; }
        if (isNaN(_playCount[name])) { _playCount[name] = 0; }
        return (_playCount[name] < max);
    }
 
    private function decreasePlayCount(s:SuperSound):Void {
        s.removeEventListener("onSoundComplete", this, "decreasePlayCount");
        s.removeEventListener("onSoundStop", this, "decreasePlayCount");
        if(isNaN(_playCount[s.getName()])) { _playCount[s.getName()] = 0; }
        if(_playCount[s.getName()] > 0){
            _playCount[s.getName()]--;
        }
    }
 
    private function replaces(name:String, owner:MovieClip):Void {
        var replaces:Array = _tracks[name][owner]._ends.split("|");
        for (var i:Number = 0; i < replaces.length; i++) {
            if (replaces == "") { continue; }
            stopEvent(replaces, owner);
        }
    }   
 
    private function playNextInQue(s:SuperSound) {
        s.removeEventListener("onSoundComplete", this, "playNextInQue");
        var next:String = validateOrDefaultString(_tracks[s.getName()][s.getOwner()]._leadsto);
        if (next == "") { return; }
        playEvent(next, s.getOwner());
    }       
 
    private function cloneEvent(o:Object):Object {
        var event:Object = { };
        for (var i in o) {
            event = o;
        }
        event._s = null;
        return event;
    }
 
    private function onTrackListAvaliable(tl:TextLoader):Void {
        if(!tl.isLoaded()){
            trace("SoundManager: could not load tracklist.");
            return;
        }
        _tracks = { };
        _owners = [];
        var tracklist:Object = tl.getDataObject().tracklist;
        _basedir = Utils.isValidString(tracklist.attributes.basedir) ? tracklist.attributes.basedir : _basedir;
        for (var i:Number = 0; i < tracklist.track.length; i++) {
            var attr:Object = tracklist.track.attributes;
            if (_tracks[attr.eventname] != undefined) {
                continue; //duplicate
            }
            _tracks = _tracks[attr.eventname] = {};
            _tracks[DEFAULT_OWNER] = {
                _name: validateOrDefaultString(attr.eventname),
                _file: validateOrDefaultString(attr.file),
                _volume: validateOrDefaultNumber(attr.volume,100),
                _loops: validateOrDefaultNumber(attr.loops,1),
                _fadein: validateOrDefaultNumber(attr.fadein,0),
                _fadeout: validateOrDefaultNumber(attr.fadeout,0),
                _ends: validateOrDefaultString(attr.ends),
                _leadsto: validateOrDefaultString(attr.leadsto),
                _offset: validateOrDefaultNumber(attr.offset,0),
                _follow: validateOrDefaultBool(attr.followowner,false),
                _stream: validateOrDefaultBool(attr.stream,true),
                _maxcount: validateOrDefaultNumber(attr.maxcount,0),
                _owner: DEFAULT_OWNER
            };
            _tracks[DEFAULT_OWNER]._loops = _tracks[DEFAULT_OWNER]._loops > 0 ? _tracks[DEFAULT_OWNER]._loops : 10000; //loop indefinetly if 0 or less
            _tracks[DEFAULT_OWNER]._s = new SuperSound(_tracks[DEFAULT_OWNER]._name, _basedir + _tracks[DEFAULT_OWNER]._file, _tracks[DEFAULT_OWNER]._owner);
            _tracks[DEFAULT_OWNER]._s.loadSound(false); //"preload"
        }
        _tracks.length = tracklist.track.length;
    }
 
    private function validateOrDefaultBool(s:String, d:Boolean):Boolean {
        if (s == undefined || s.length == 0) { return d; }
        s = s.toLowerCase();
        return (s == "true" || s == "yes" || s =="y") ? true : false;
    }
 
    private function validateOrDefaultNumber(s:String, d:Number):Number {
        var n:Number = Number(s);
        if (!isNaN(n)) {
            return n;
        }
        if(d == undefined){
            return 0;
        }
        return d;
    }
 
    private function validateOrDefaultString(s:String):String {
        if(s != undefined && s != "undefined" && s != null) {
            return s;
        }
        return "";
    }
 }

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  • Asithaza icon
    04/02/26 04:23:23 PM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  • Rteuixl icon
    04/02/26 04:26:13 PM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.@xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400
     Remove the @ 
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎