Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Choosing a music track at random

edited March 2015 in Help! with 2.0
In my game I have 5 or so music tracks so that the player does not get bored of any one track. But as it is, it means that I have to keep them in one big track, and just basically tell it to loop over and over. Which is simple, but it means the tracks are always heard in the same order, which is not ideal.

What would be the easiest way to choose tracks at random, and not have them playing over each other? Here are a few ways I've theorised:

1. Have a global javascript timer similar to the one discussed here http://www.glorioustrainwrecks.com/node/5108 that keeps track of how long it has been since a track has started playing, and at the end of a certain time, sets a variable that tells the next passage loaded to pick out a track at random.

2. Update the sound macro script I am using to pick a start point at points during the track, so I can randomise the start point.

3. Some kind of event listener that detects when a music track has finished playing, and sets a variable that makes it possible to start playing a new track.


Or, question that would possibly make it easier: Can I just use the existing <<timedcontinue>> macro to do this? Will it persist between passages?

I.e. can I write:

<<if $musicopen is 1>>
<<playsound "music1.ogg">><<set $musicopen to 0>>
<<timedcontinue 240s>><<set $musicopen to 1>>
<</if>>
Or will that have decayed the moment you visit a new passage?

Comments

  • Audio elements have an ended event you can attach a callback function to which fires when the current playlist for that Audio element is finished.
    note: the following assumes the id of the Audio element is player

    1. standard javascript

    var elm = document.getElementById("player");
    elm.onended = function() {
    alert("The audio has ended, place code here to play next tune.");
    };
    2. jQuery

    $("#player").bind('ended', function() {
    alert("The audio has ended, place code here to play next tune.");
    });
  • I bring &lt;&lt;playlist&gt;&gt; for all the good little boys and girls.

    I'm sure that I probably glossed over something and this might take another release to nail, but there's a start now.  Try that out and let me know what happens.
  • Works great thanks! I'm trying it out now and found no bugs. Many thanks for adding in this much-needed functionality. My game is almost a radio drama, so it uses sound extensively and needed more advanced audio controls.

    My main question is does <<cacheaudio>> take much time for the browser to do? E.g. if I try to cache 100MB of audio at game start, what will happen? Previously I tried to address this issue by scattering <<loadsound>> macros through the story, so that the browser would cache things at a staggered rate, and not try to store sounds in memory that it may need only an hour in.

    Of course I could just <<cacheaudio>> later on, I guess.

    A related question is would repeating the <<cacheaudio>> commands at different points cause any problems? E.g. if someone is coming up to a crucial point, and I wanted to cache audio again to make sure they had the sound loaded despite any user shenanigans that may have wiped the cache.


  • With the playlist shuffle, any way to ensure that it doesn't choose the same track twice in a row? Not a huge deal, but nice to have if is easily done.
  • Claretta wrote:

    My main question is does <<cacheaudio>> take much time for the browser to do? E.g. if I try to cache 100MB of audio at game start, what will happen? Previously I tried to address this issue by scattering <<loadsound>> macros through the story, so that the browser would cache things at a staggered rate, and not try to store sounds in memory that it may need only an hour in.

    Of course I could just <<cacheaudio>> later on, I guess.


    You should be able to front-load all of your &lt;&lt;cacheaudio&gt;&gt; macros, putting them in the StoryInit special passage.  Loading of the audio resources should be done by the browser in the background.  Please, let me know if you find issues with this.

    Still, as long as you were careful, say by using a little logic and a $variable (which you're probably already doing with &lt;&lt;loadsound&gt;&gt;), you could spread your &lt;&lt;cacheaudio&gt;&gt; invocations around.  Though, I think that if you decided you really needed to do this, that it would be better to give &lt;&lt;cacheaudio&gt;&gt; the option to set up but not preload an audio track and give &lt;&lt;audio&gt;&gt; a load action.  That would enable all &lt;&lt;cacheaudio&gt;&gt; invocations to be properly front-loaded in StoryInit, while still allowing you to chose to defer the loading of certain tracks until later.

    That said, I think this is probably a case of putting the cart before the horse.


    Claretta wrote:

    A related question is would repeating the <<cacheaudio>> commands at different points cause any problems? E.g. if someone is coming up to a crucial point, and I wanted to cache audio again to make sure they had the sound loaded despite any user shenanigans that may have wiped the cache.


    Currently, you'll overwrite the previously cached &lt;audio&gt; elements, which you probably don't want to do, so I would advise against it.  Beyond that, attempting to play an audio track will always ensure that the audio is loaded first, so you shouldn't really need to do so.  Something you may not be aware of, an audio resource (and this is true of all of the HTML5 media APIs/elements) should not have to be fully loaded to begin playing.  Once enough data frames are loaded for it to begin playback, it will do so.

    Still, if it became an issue (maybe with an abnormally large audio track and an abnormally slow internet connection), there are ways to request that the audio be loaded.  The wrapper I wrote has the functionality, though it's not, currently, directly exposed as an &lt;&lt;audio&gt;&gt; action (though, it is used behind the scenes and, as noted above, it's something I could add).


    Claretta wrote:

    With the playlist shuffle, any way to ensure that it doesn't choose the same track twice in a row? Not a huge deal, but nice to have if is easily done.


    That should already be the case for shuffle.  After playback of the current queue ends, the playlist will be queued up again (assuming that loop/repeat is enabled), then shuffled, and finally checked to see if the next track is the same as the last played track, in which case it's bumped to the end of the queue.
  • Thanks for the reply. Yeah, if I'm just worry about nothing, then no changes would need to be made. :)
  • I'm just curious if there's much difference between this loading method and the old <<loadsound>> macro you made?

    I have a lot of my audio still in the old version, so wondering whether to change over or whether this new one is better to use. Or more to the point, is the loadsound functionality replicated here?

    Of course using the new one for music.
  • The loading behavior should be equivalent between the two.
  • Thanks for confirmation. :)
Sign In or Register to comment.