I've made some music that contains an intro sequence and then a loopable part. The idea is that I'll start by playing the intro and as soon as it ends I'll play the loopable part and repeat that indefinitely.
My attempt so far plays the loopable part during an "On Ended" trigger (I figured that a fraction of a frame's lag before it plays the loopable part won't be noticeable). The problem is that it takes longer than a frame to play the loopable part, and there's a noticeable pause in between.
Any ideas on how to queue the second track so that it plays immediately after the first?
NOTE: The loopable part loops perfectly. It's just this intro-to-loop that needs fixing.
Develop games in your browser. Powerful, performant & highly capable.
I've asked this numerous times over the years and nothing anyone suggested worked perfectly. We need a way to loop back to a certain point in a music track containing both the intro and body.
Here's a sub-optimal solution that you probably thought of already
Keep the entire song with intro and all in a single file, then when it's done playing you start looping the second file that doesn't have the intro. At least you won't get a skip shortly after the song starts.
I agree it's an important thing. Music playback's got to be the most neglected part of any gamedev middleware :-/
ErekT It's funny considering all the crazy effects and such with the audio plugin. But looping music properly? Oh hell no.
I did some tests by using a single file and using seek to hop to different loop sections when arriving at specific positions, but it gives inconsistent results. Sometimes it matches, but sometimes it plays a bit more than it should and there's a noticeable glitch.
My guess is that the event sheet don't execute fast enough to perfectly synchronize with the audio and to trigger the seek action in the exact moment. So sometimes the tick happens to be almost synchronized and there's no glitch, but often it can deviate by an error up to dt that is enough to cause trouble.
Supposing that the browser's seek doesn't add considerable latency by itself, wouldn't be possible to add some kind of asynchronous trigger that fires when the audio reaches a specific position to minimize this problem?
Something on the lines of how the asynchronous storage and the timer behavior works, like:
+System: On start of layout
-Audio: Schedule trigger "musicTrigger" to tag "music" at position 30 (once)
+Audio: On trigger "musicTrigger"
-Audio: Seek tag "music" to 15 seconds
Currently not too sure about Web Audio myself, but I came across this exciting stuff in the AudioBufferSourceNode specification:
Is a double value indicating, in seconds, where in the AudioBuffer the restart of the play must happen. Its default value is 0.
Is a double value indicating, in seconds, where in the AudioBuffer the replay of the play must stop (and eventually loop again). Its default value is 0.
Okay, I'm fairly certain the Audio object uses AudioBufferSourceNode. So somebody should be able to hack it in (I'm not the best, but I'm trying...).
If you play music, it uses HTML5 audio instead of the Web Audio API, since HTML5 audio can stream it (without having to decode and load the entire decompressed track in to memory). However most browsers don't even support seamlessly looping an entire HTML5 audio track, let alone a portion. I think Edge adds support for this, but that's the only case I know. There's not much we can do if the browser doesn't support it. I'd recommend trying to have a short overlap and crossfade between them instead of hoping to get sample-accurate alignment.
Oy. HTML5/Browsers never fail to disappoint.
Dalal hope you get this working. good luck!
Tokinsom, thanks! And hey, did you still need loop points in your games? If your games are for web, and you're okay with placing your music in the Sounds folder, then the hack I was experimenting with will work for you just fine in modern browsers. Let me know if it would be useful to you and I can send you what I have.