Play audioclip and stop after a set time (ms)

Started by HanaIndiana, Wed 27/12/2023 02:23:26

Previous topic - Next topic

HanaIndiana

I have music audio that I'd like to play portions of, during different times of the game.
For example, play the first 20 seconds of the music then stop.
Later I'll have it start at minute 1:00 of the music and play for 30 seconds.

The only condition for stopping the music is the length of time it's been playing. The manual mentions using Wait(int).

Code: ags
aSong.PlayFrom(1000);
Wait(40);
aSong.Stop();

This isn't ideal because Wait will block (from what I understand), Also, Wait() doesn't use seconds but frame/loops (?) so there is some conversion there and I don't know how accurate it will be for every machine.
I also tried using a while loop and checking the channel song position (PositionMS) until a given PositionMS number, but it kept crashing because it said I was stuck in a long running loop.

Is there another way I could go about this?
I rather not create a ton of music clips, but that might be the answer.

Crimson Wizard

Hello.

If you want some continuous action to run while the rest of the game keeps going, then the usual solution is to do checks in repeatedly_execute. In case of a music it is better to use repeatedly_execute_always, because music also keeps playing when game is paused.

But for that you would need to save the audio channel this music is playing on. So you would need to create a global variable for this. Also, perhaps, create a variable to store the position at which to stop the music.

Let's say you created a global variable of type "AudioChannel*" called "songToStop" and variable of type "int" called "songToStopMs". Then the code will be like:

Code: ags
function repeatedly_execute_always()
{
    if (songToStop != null && songToStop.PositionMs >= songToStopMs)
    {
        songToStop.Stop();
        songToStop = null; // reset the variable
    }
}

And when you start the song, then you do like:
Code: ags
songToStop = aSong.PlayFrom(1000);
songToStopMs = 2000;

HanaIndiana

#2
ah! I was thinking I needed to use repeatedly_execute, but I couldn't figure out how. Thanks for this! I'll try it out.
Edit: Yep, that did the trick, thanks!

SMF spam blocked by CleanTalk