Git Product home page Git Product logo

soundas's Introduction

SoundAS - AS3 SoundManager

A modern lightweight AS3 SoundManager for Flash and AIR.

The goal of SoundAS is to simplifying playback of your audio files, with a focus on easily transitioning from one to another, and differentiating between SoundFX and Music Loops.

#Features

  • Clean modern API
  • API Chaining: SoundAS.play("music").fadeTo(0);
  • Supports groups of sounds
  • Supports seamless looping
  • Supports workaround for the 'looping bug' (http://www.stevensacks.net/2008/08/07/as3-sound-channel-bug/)
  • Built-in Tweening system, no dependancies
  • Modular API: Use SoundInstance directly and ignore the rest.
  • Non-restrictive and unambigous license

#API Overview

Full documentation can be found here: http://treefortress.com/libs/SoundAS/docs/.

###SoundAS This Class is the main interface for the library. It's responsible for loading and controlling all sounds globally.

Loading / Unloading:

  • SoundAS.addSound(type:String, sound:Sound):void
  • SoundAS.loadSound(url:String, type:String, buffer:int = 100):void
  • SoundAS.removeSound(type:String):void
  • SoundAS.removeAll():void

Playback:

  • SoundAS.getSound(type:String, forceNew:Boolean = false):SoundInstance
  • SoundAS.play(type:String, volume:Number = 1, startTime:Number = 0, loops:int = 0, allowMultiple:Boolean = false, allowInterrupt:Boolean = true, enableSeamlessLoops:Boolean = false):SoundInstance
  • SoundAS.playFx(type:String, volume:Number = 1, startTime:Number = 0, loops:int = 0):SoundInstance
  • SoundAS.playLoop(type:String, volume:Number = 1, startTime:Number = 0, enableSeamlessLoops:Boolean = true):SoundInstance
  • SoundAS.resume(type:String, volume:Number = 1, startTime:Number = 0, loops:int = 0):SoundInstance
  • SoundAS.resumeAll():void
  • SoundAS.pause(type:String):SoundInstance
  • SoundAS.pauseAll():void
  • SoundAS.stopAll():void
  • SoundAS.set masterVolume(value:Number):void
  • SoundAS.fadeFrom(type:String, startVolume:Number = 0, endVolume:Number = 1, duration:Number = 1000)
  • SoundAS.fadeAllFrom(startVolume:Number = 0, endVolume:Number = 1, duration:Number = 1000)
  • SoundAS.fadeMasterFrom(startVolume:Number = 0, endVolume:Number = 1, duration:Number = 1000)
  • SoundAS.fadeTo(type:String, endVolume:Number = 1, duration:Number = 1000):SoundInstance
  • SoundAS.fadeAllTo(endVolume:Number = 1, duration:Number = 1000):SoundInstance
  • SoundAS.fadeMasterTo(endVolume:Number = 1, duration:Number = 1000)

####SoundInstance Controls playback of individual sounds, allowing you to easily stop, start, resume and set volume or position.

  • **play**(volume:Number = 1, startTime:Number = 0, loops:int = 0, allowMultiple:Boolean = true):SoundInstance
    
  • **pause**():SoundInstance
    
  • **resume**(forceStart:Boolean = false):SoundInstance
    
  • **stop**():SoundInstance
    
  • **set volume**(value:Number):void
    
  • **set mute**(value:Boolean):void
    
  • **fadeFrom**(startVolume:Number, endVolume:Number, duration:Number = 1000):SoundInstance
    
  • **fadeTo**(endVolume:Number, duration:Number = 1000):SoundInstance
    
  • **destroy**():void
    
  • **endFade**(applyEndVolume:Boolean = false):SoundInstance
    

#Code Examples

###Loading

//Load sound from an external file
SoundAS.loadSound("assets/Click.mp3", "click");

//Inject an already loaded Sound instance
SoundAS.addSound("click", clickSound);

###Basic Playback

//Play sound.
    //allowMultiple: Allow multiple overlapping sound instances.
    //allowInterrupt: If this sound is currently playing, start it over.
SoundAS.play("click", volume, startTime, loops, allowMultiple, allowInterrupt);

//Shortcut for typical game fx (no looping, allows for multiple instances)
SoundAS.playFx("click");

//Shortcut for typical game music (loops forever, no multiple instances)
SoundAS.playLoop("music");

//Toggle Mute for all sounds
SoundAS.mute = !SoundAS.mute;

//PauseAll / ResumeAll
SoundAS.pauseAll();
SoundAS.resumeAll();
 
//Toggle Pause on individual song
var sound:SoundInstance = SoundAS.getSound("music");
(sound.isPaused)? sound.resume() : sound.pause();

//Fade Out
SoundAS.getSound("click").fadeTo(0);

//Fade masterVolume out
SoundAS.fadeMasterTo(0);

Groups

//Create a group
var musicGroup:SoundManager = SoundAS.group("music");

//Add sound(s) to group
musicGroup.loadSound("assets/TitleMusic.mp3", "titleMusic");
musicGroup.loadSound("assets/GameMusic.mp3", "gameMusic");

//Use entire SoundAS API on Group:
musicGroup.play("titleMusic")
musicGroup.volume = .5;
musicGroup.mute = muteMusic;
musicGroup.fadeTo(0);
//etc...

//Stop All Groups
for(var i:int = SoundAS.groups.length; i--;){
    SoundAS.groups[i].stopAll();
}

###Advanced

//Mute one sound
SoundsAS.getSound("click").mute = true;

//Fade from .3 to .7 over 3 seconds
SoundAS.getSound("click").fadeFrom(.3, .7, 3000);

//Manage a SoundInstance directly and ignore SoundAS
var sound:SoundInstance = new SoundInstance(mySound, "click");
sound.play(volume);
sound.position = 500; //Set position of sound in milliseconds
sound.volume = .5; 
sound.fadeTo(0);

//String 2 songs together
SoundAS.play(MUSIC1).soundCompleted.addOnce(function(si:SoundInstance){
    SoundAS.playLoop(MUSIC2);
}

//Loop twice, and trigger something when all loops are finished.
SoundAS.play(MUSIC1, 1, 0, 2).soundCompleted.add(function(si:SoundInstance){
    if(si.loopsRemaining == -1){
        trace("Loops completed!");
        si.soundCompleted.removeAll();
    }
}

License

WTFPL

soundas's People

Contributors

adolio avatar crashposition avatar esdotdev avatar jlopez avatar kottkrig avatar matulkum avatar treefortress avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

soundas's Issues

IOs 7 issue

Hi everybody,
I have a problem using your AudioAS framework. When i play a sound, the iPhone requires the microphone. Do you know how to solve this bug? Thank you.

SoundInstance.stop does not impact SoundInstance.isPlaying

The SoundInstance.stop function resets the pauseTime and stops the current and old channels, which successfully stops the audio. However, isPlaying does not reflect that since all of it's conditions can still be true.

This only really presents itself with a looping sound, since onSoundComplete seems to adequately clean up the current sound channel.

I think stopChannel needs to clear the current channel and possibly clean up the list of old channels in addition to simply stopping the current channel. But, I'm unsure of the affect of this on other scenarios.

masterVolume is not initialiazed for new SoundInstance

Hi guys,

When I add a new sound, the masterVolume doesn't seem to be initialized for the new SoundInstance.

How to reproduce :

private var sound:Sound;
private var i:int = 0;

public function testMasterVolume():void
{
    sound = ResourcesController.getInstance().getSound("sound_jump");
    var myTimer:Timer = new Timer(1000, 3);
    myTimer.addEventListener(TimerEvent.TIMER, onTime);
    myTimer.start();
}

private function onTime(event:TimerEvent):void 
{
    switch(i)
    {
        case 0:
            SoundAS.addSound("mySound_1", sound);
            SoundAS.masterVolume = 1.0;
            SoundAS.playFx("mySound_1"); // ok
        break;
        case 1:
            SoundAS.masterVolume = 0.5;
            SoundAS.addSound("mySound_2", sound);
            SoundAS.playFx("mySound_2"); // WRONG : still use masterVolume at 1.0
        break;
        case 2:
            SoundAS.masterVolume = 0.5; // update all SoundInstance
            SoundAS.playFx("mySound_2"); // ok
        break;
    }

    ++i;
}

isPlaying is pretty buggy.

Im doing update on enter frame that checks for isPlaying. For the first 3 frames its false even when sound is playing, then it is true for few another frames, and once again after sound loops it gets "false".

Memory Leak when using .stopAll()

I just posted about this on the official starling game engine forum here: http://forum.starling-framework.org/topic/does-anyone-else-use-tree-fortresss-soundas-sound-manager#post-89464 but I'll go ahead and summarize here:

I think I've found a memory leak. If you do something like the following:

SoundAS.play('my_sound').soundCompleted.addOnce(function(si:SoundInstance){
trace('Hello, my name is Mr. Leaky McLeakerson! I'm here to eat your memory.');
}
SoundAS.stopAll();

Using .stopAll() will not remove the callback you just added. The closure hangs around in memory along which whichever class originally added that callback. (In my case, it was the play screen, so needless to say things got out of hand quite quickly.)

I won't rule out that maybe I'm just misunderstanding how SoundAS callbacks are supposed to work. If I'm not understanding the proper way to stop them, I'd love it if you could fill me in.

(Thanks a million for the library BTW, it's been great- save for this one hiccup!)

enableSeamlessLoops resumes play midway through sound on loop

Hi. I read your comments about adding the enableSeamlessLoops flag, and I see that you are aware it is perhaps buggy, but I thought I'd report this in case it is unknown.

My issue is that when I use the playLoop function, the sound loops back to the supplied starting position, not back to the start of the sound, as seems like the expected behaviour. By turning off the enableSeamlessLoops flag it worked fine. It actually only caught me out because the flag is true by default.

So, this loops back to midway through:

SoundAS.playLoop(  'some_music', 1, resumePosition, true );

...and this loops back to the beginning, as expected:

SoundAS.playLoop(  'some_music', 1, resumePosition, false);

Thanks :)

Stopping one sound out of multiple playing sounds with the same type

In my game I have the following scenario:

Multiple instances of an enemy all have the same looping sound started via:

_loopingSound = SoundManager.play("howl", 1, 0, 999, true);

(_loopingSound is a private SoundInstance contained inside each enemy instance.)

Now let's say one of the enemies is killed and I want to stop his sound:

_loopingSound.stop();

This causes ALL the other enemies looping sounds to suddenly stop.

Ideally by stopping one enemy's sound the others would still keep playing.

Am I missing something, or is this behaviour not currently supported?

If so it would be a great option to have.

SoundAS with AIR for iOS

Hi guys.

I'm just playing around with your awesome SoundAS framework, but I have some trouble with using it on the iPad.

Sounds load and play correctly when running the Air application on the desktop (actually when testing in the Flash SDK), but as soon as I port it to the iPad, all sounds are gone.
Is this something you can help me solve?

Thanks in advance guys. :)

SoundInstance.fadeTo Bug

Assume you have 2 instances of the same sound

var si_1:SoundInstance = SoundAS.getSound("somesfx",true);
var si_2:SoundInstance = SoundAS.getSound("somesfx",true);

now if both sounds are playing and you wanted to fade out one of them the SoundInstance.fadeTo method doesn't actually fade that instance .. it calls the SoundManager.addTween with the "type" of sound .. many instances are playing having the same type! .. in this case the addTween method call the getSound() method that throws a stack overflow error .

SoundInstance.pauseTime variable not being reset after sound completes causing errors on resumeAll

When pausing an already completed sound instance (or using pauseAll as I am in this case), a TypeError #1009 (Cannot access a property or method of a null object reference) is triggered after attempting to execute resume (or resumeAll) on that instance.

TypeError:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at treefortress.sound::SoundInstance/play()[F:\development_libs\SoundAS\lib\src\treefortress\sound\SoundInstance.as:98]

This SoundInstance has actually completed. The startTime and pauseTime values equal the length of the sound property, and the channel property has been set to null.

Yet, because resume only checks for isPaused or forceStart, and isPaused only checks the pauseTime value, which is greater than 0, it attempts to resume the sound. Which fails.

Presumably, it fails because this line in the play method is not returning a value for the channel when the startTime = sound.length.

channel = sound.play(startTime, 0);

This invalid channel variable is what is then being accessed on the line indicated in the error message.

Possible solutions are either to include a check for a valid channel variable in the isPaused property and/or reset the pauseTime variable in onSoundComplete.

Stack overflow on trying to play a sound that is not loaded

If a group is created using

SoundAS.group("name");

and you try to play a sound that is lot loaded, the getSound() function in SoundManager.as goes into infinite recursion on following lines:

//If instance was not found, check out parent manager;
if(!si && parent){ si = parent.getSound(type); }

//Still not found, check the children.
if(!si && groups){
    for(var i:int = groups.length; i--;){
        si = groups[i].getSound(type);
        if(si){ break; }
    }
}

having a group, causes the check in children to run, which in turn checks the parent, which in turn again the children - and lo infinite recursion!

An easy solution would be to not check the parent for the sound.
If I am requesting a sound in a group I surely don't want it from another group or the parent.

How to check that sound is already load?

Hi, noobs here!

question is... How to check that sound is already load?
so i can just play if sound already load...
far as i try is

var si:SoundInstance = SoundAS.getSound("somesound");

but at present it will throw error if it not exist, i did expected null for first load then call SoundAS.loadSound if si is null e.g.

if(!si)
    SoundAS.loadSound("somesound.mp3", "somesound");

and if i load sound via SoundAS.loadSound again without check for existing
SoundAS.loadCompleted is seem to be never fire for second load same url and type.

btw, i don't think it's a good idea to try catch there. "null for non exist SoundAS.getSound" should be better there.

Thanks

soundInstance.fadeTo() jumps to full volume before fading.

Hi,

I have found that when calling fadeTo() to fade out a SoundInstance with a volume of less than 1.0, the volume of that instance jumps up to 1.0 before fading back down to zero.

_currentSoundInstance.volume = _globalVolume; // 0.3 - just making sure it is set
_currentSoundInstance.fadeTo( 0, fadeTime, true );

If I step through the SoundAS code, the volume jumps in SoundTween, at line 45:

sound.volume = easeOutQuad(t - startTime, startVolume, endVolume - startVolume, duration);

The volume gets set to 1.0 regardless of the startVolume. (Which in this case is 0.3).

Thanks.

Feature request: group.playRandom()

This is a handy utility class! One nice feature would be a group.playRandom() function. For example, I may have a group of punch "swooshes" or VO queues that get played when the hero accomplishes something awesome, but I don't want to play the exact same sound every time. It would be nice to be able to create a group of sounds, and then just .playRandom() on that group.

Thanks!

How to Load sound from an SWC?

I'm confused on how I could load a Soundfile from an SWC library.

I started of my using:
private var SoundAS:SoundManager;

and thought I could then add the MP3 from my SWC like so:
SoundAS.addSound("found", mp3found);

But that didnt worked. Any tips?

cannot play loop seamlessly

SoundAS cannot play loops seamlessly, even the loop sound is gap-less and embedded inside flash ide.. which means it can be played back in seamless loop by using sound.play(0, int.MAX_VALUE)

hopefully it can be fixed.

SoundAS.getSound() returns SoundInstance object w type = null when forceNew is true

Code:

SoundAS.addSound("sample",new samplesound());
var snd:SoundInstance = SoundAS.getSound("sample",false);
trace('getSound("sample",false).type='+snd.type);
var snd:SoundInstance = SoundAS.getSound("sample",true);
trace('getSound("sample",true).type='+snd.type);

Output:
getSound("sample",false).type=sample
getSound("sample",true).type=null

Presumably, the "si = si.clone()" is failing.

A quick review turns up this likely culprit:

public function clone():SoundInstance {
var si:SoundInstance = new SoundInstance(sound);
return si;
}

The new instance is not being passed the existing type parameter in it's constructor, thus resulting in a null value.

fadeToMaster bug

I'm trying to use fadeMasterTo on groups, like this:
SoundAS.group(Configuration.musicGroup).fadeMasterTo(0);
but it doesn't change masterVolume value. Setter works properly.
SoundAS.group(Configuration.musicGroup).masterVolume = 0;
Can you confirm this?

Thanks
Vjeko

Firing onComplete when sound fails to load

I'm waiting on a sound to complete with soundCompleted firing a function.

However, if the sound fails to load, that function never gets called.

Is there a way to fire the function even if the sound fails to load, so at least the rest of the program can continue on its merry way?

Cheers

Destroy of SoundInstance fails after soundCompleted

I do this:

_scenarioSounds.play("audioStart").soundCompleted.addOnce(startSoundComplete);

and in the next function I try to tidy up and release the memory used by the sound:

private function startSoundComplete(si:SoundInstance):void
{
trace("startSound complete");
si.soundCompleted.removeAll();

                    //cleanup methods I tried.

        //1: _scenarioSounds.removeSound(si.type);
        //2: si.destroy();
    }

Both fail, I presume because of the last line in the destroy function:

fade.end(false);

Since fade is already null this won't work like it's supposed to.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.