Some of you might have seen my previous post on SoundLoop2 that you can see in action here. But it had some timing inconsistencies, due in big part to setInterval.
I decided to deconstruct my SoundLoop2 and refactor it in a simpler manner. This resulted in 4 classes.
- MusicBuilder Class to handle "playlists" and loop modes
- SoundObject Class wich is a simplefied version of SoundLoop2
- SOCollection Class wich is a simple Array of SoundObjects with custom method to retrieve information.
- Timer Class wich calculates the exact (I hope) time elapsed between the start and the desired duration and returns an event when done.
I was quite disapointed by setInterval's unreliable timing. I needed something that could give me the exact time to the millisecond.
Then I found this post (in french) with a solution for time evaluation that seemed interesting and decided to apply it my Timer Class, and what not ! it seemed to work !
The Timer class is an utility class that can be used with any other Class. Think of it as an alarm clock. So far it looks like the Timer gets the right answer each time, but It will need much further testing for me to see it is totally reliable !
SoundObject can be used on it's own and it can loop on it's own too, but MusicBuilder needs the other 3 classes to work.
What can MusicBuilder do ? we'll come to that in a short while. First let's see what's in store for us with SoundObject.
To use it here is what you need to do :
-
-
import ca.daroost.SoundObject;
-
import mx.utils.Delegate; // or whichever Delegate class you want to use
-
var mySObj:SoundObject = new SoundObject(this, "intro.mp3", 0, 25, "mySObj1", true);
-
-
mySObj.loadAndPlay();
-
mySObj.onLoopComplete = Delegate.create(this, completeHandler);
-
-
function completeHandler(sobj:SoundObject) {
-
sobj.repeat();
-
}
-
What do we send in the consructor ? We send the MovieClip scope of the sound (Much like the Sound class), we put the url of the mp3 file, the start and end offsets, the name of the object and whether we want it to stream or not. As simple as that. Aftewards we define the onLoopComplete method that will be triggered when the sound position reaches our end offset.
At first in SoundLoop2 I used EventDispatcher to trigger that event, but no more. I simply listen to my Timer Class to tell me when we have reached the appropriate time and then just call the callback function created by the user.
Inside the class here is what it looks like :
-
import ca.daroost.utils.Timer;
-
//Constructor
-
function SoundObject(...) {
-
soundTimer = new Timer();
-
soundTimer.addEventListener("onTimerDone", this);
-
//...
-
}
-
-
function onTimerDone(evtObj:Object) {
-
this.onLoopComplete(this);
-
}
-
-
//...
-
that's it !
Now all we have to do is set this up with the MusicBuilder class so we can have one nice long song that can loop seamlessly (hopefully seamlessly) :
-
-
import ca.daroost.SoundObject;
-
import ca.daroost.SOCollection;
-
import ca.daroost.MusicBuilder;
-
-
var mySObj1:SoundObject = new SoundObject(this, "intro.mp3", 0, 25, "mySObj1", true);
-
var mySObj2:SoundObject = new SoundObject(this, "loop1b.mp3", 0, 15, "mySObj1", true);
-
var mySObj3:SoundObject = new SoundObject(this, "phrase3.mp3", 0, 100, "mySObj1", true);
-
var mySObj4:SoundObject = new SoundObject(this, "phrase4.mp3", 0, 100, "mySObj1", true);
-
var mySObj5:SoundObject = new SoundObject(this, "phrase5a.mp3", 0, 100, "mySObj1", true);
-
-
var myCollection:SOCollection = new SOCollection(mySObj1, mySObj2, mySObj3, mySObj4, mySObj5);
-
var musicBox:MusicBuilder = new MusicBuilder(myCollection);
-
musicBox.composeSong("last");
-
Everything is in that single line - musicBox.composeSong("last"). Possible values are "all", "last", "once" or a number telling at which position in the sound collection to start playing again. This value starts at 0 for the first one.
- composeSong("all") : when the last sound finishes playing, the song will start again from the first one
- composeSong("last"): only the last sound will be looped
- composeSong("once"): there will be no looping here.
- composeSong(2): as mentionned earlier, when the last sound finishes playing, the song will start again from the third (3) sound in the list.
This is much better than SoundLoop2 where I had some limitations to the number of sounds I could add to the queue. Now it is almost endless, tho I haven't tried to test the limits of my approach. But I would think it could be quite a big queue of sounds !
Download
Here is a first draft of those Classes with an example Fla with mp3 I offer you for testing purposes only.
[...] http://lab.daroost.ca/2007/02/25/sondloop2-revisited-musicbuilder-soundobject/ [...]
GoPiano…
Megacool Blog indeed!… if anyone else has anything it would be much appreciated. Great website Enjoy!…
[...] MusicBuilder & SoundObject [...]
femifokyzave…
Download mp3 with Bryan Dalton and Dan E featuring Mitch Crown …
[...] MusicBuilder & SoundObject ????????MusicBuilder?SoundObject?SOCollection?Timer?????????multiple streaming mp3????????????????????Timer?????????????????????????MP3??? [...]
[...] MusicBuilder & SoundObject ????????MusicBuilder?SoundObject?SOCollection?Timer?????????multiple streaming mp3????????????????????Timer?????????????????????????MP3??? [...]