• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM [SOLVED]Multiroom music from external files.

D

DyingSilence

Guest
Hello.

I want my game to have music that continues to play between the rooms that use the same music. My code at the moment looks like this:

Code:
if(global.level == 0)
{
    (!audio_exists(snd_prelevel))
    {
        snd_prelevel = audio_create_stream('Depressed of Happytown.ogg');
    }
    
    if(!audio_is_playing(snd_prelevel))
    {
        audio_play_sound(snd_prelevel,1,1);
    }
}
else
{
    audio_stop_sound(snd_prelevel);
    audio_destroy_stream(snd_prelevel);
}
But it has two issues I'd like to have solved:

1. audio_exists() doesn't actually check if a resource index exists. Is there a function that does that?
2. The check that uses audio_is_playing() doesn't prevent the file to be played multiple times. Why?

Thanks for help in advance!
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
1. audio_exists() doesn't actually check if a resource index exists. Is there a function that does that?
sound_exists? You should probably have a global ds_map with name->sound pairs so that you can check if you loaded something yet or not.
2. The check that uses audio_is_playing() doesn't prevent the file to be played multiple times. Why?
It does but you are loading a new sound which has a different index.
 

samspade

Member
I'm not entirely sure this is what you're looking for but I think it might help. It requires you to store some variables somewhere that I would make global.

Code:
///scr_play_music(music, priority, looping);

var music = argument[0];    //should be a sound file
var priority = argument[1];
var looping = argument[2];  //true or false

if (music != global.current_music) {
    audio_stop_sound(global.current_music);
    global.current_music = music;
    audio_play_sound(global.current_music, priority, looping);
}
Using this rather than audio_play_sound won't start multiples of the same song and will stop any current song to play the one you want.
 
D

DyingSilence

Guest
I'm not entirely sure this is what you're looking for but I think it might help. It requires you to store some variables somewhere that I would make global.

Code:
///scr_play_music(music, priority, looping);

var music = argument[0];    //should be a sound file
var priority = argument[1];
var looping = argument[2];  //true or false

if (music != global.current_music) {
    audio_stop_sound(global.current_music);
    global.current_music = music;
    audio_play_sound(global.current_music, priority, looping);
}
Using this rather than audio_play_sound won't start multiples of the same song and will stop any current song to play the one you want.
This works quite neatly, but resets the song. I guess it doesn't compare if the two are identical.
 
D

DyingSilence

Guest
sound_exists? You should probably have a global ds_map with name->sound pairs so that you can check if you loaded something yet or not.

It does but you are loading a new sound which has a different index.
1. I don't really get this, do you mean the ds_map would store the literal OGG file?
2. If so, can multiple indexes share the same name?

I guess I'm being super dumb right now, thanks for the patience.
 

samspade

Member
This works quite neatly, but resets the song. I guess it doesn't compare if the two are identical.
If it's resetting the song, something is wrong. audio stop and audio play will only be called if music doesn't match the global.current_music. It's possible you're using the specific sound instance id rather than the resource name at some point?
 
D

DyingSilence

Guest
If it's resetting the song, something is wrong. audio stop and audio play will only be called if music doesn't match the global.current_music. It's possible you're using the specific sound instance id rather than the resource name at some point?
Here's exactly what I do:

obj_music_player, CREATE EVENT
Code:
if(global.level == 0)
{
    music = audio_create_stream('Depressed of Happytown.ogg');
    scr_play_music(music);}
The script
Code:
///scr_play_music(music)

var music = argument[0];

if (music != global.current_music) {
    audio_stop_sound(global.current_music);
    global.current_music = music;
    audio_play_sound(global.current_music, 1, 1);
}
It seems that music isn't music anymore once it's loaded again.
 

samspade

Member
audio_create_stream returns a sound index (basically a sound instance id to my understanding). This won't work with the script as every time you use it, it will create a unique value and therefore never match up. The original idea of the script was something like this:

Code:
///some early game create event
global.music = -1;

///any other point
scr_play_music(snd_title_track);
Where you are referencing a sound asset id, not a unique variable assigned to a particular instance of sound being played. In your case I think if you could make it work with the following modifications (but I'm not sure as I haven't used audio_create_stream much):

Code:
///some early create event
global.music_name = "";
global.music_id = -1;


///example of using the script
if (global.level == 0) {
    new_music_name = "Depressed of Happytown.ogg";
    scr_play_music(new_music_name);
}



///scr_play_music(music)

var music = argument[0];

if (music != global.music_name) {
    audio_stop_sound(global.music_id); //can't remember if this will cause an error if -1. Might have to check if it exists first.
    global.music_id = audio_create_stream(music);
    audio_play_sound(global.music_id, 1, 1);
}
Again, I'm doing this from memory and I don't use these very often. So there might be errors. The important points is that you're checking a specific instance id against another different specific instance id so they're never going to match up.
 
D

DyingSilence

Guest
audio_create_stream returns a sound index (basically a sound instance id to my understanding). This won't work with the script as every time you use it, it will create a unique value and therefore never match up. The original idea of the script was something like this:

Code:
///some early game create event
global.music = -1;

///any other point
scr_play_music(snd_title_track);
Where you are referencing a sound asset id, not a unique variable assigned to a particular instance of sound being played. In your case I think if you could make it work with the following modifications (but I'm not sure as I haven't used audio_create_stream much):

Code:
///some early create event
global.music_name = "";
global.music_id = -1;


///example of using the script
if (global.level == 0) {
    new_music_name = "Depressed of Happytown.ogg";
    scr_play_music(new_music_name);
}



///scr_play_music(music)

var music = argument[0];

if (music != global.music_name) {
    audio_stop_sound(global.music_id); //can't remember if this will cause an error if -1. Might have to check if it exists first.
    global.music_id = audio_create_stream(music);
    audio_play_sound(global.music_id, 1, 1);
}
Again, I'm doing this from memory and I don't use these very often. So there might be errors. The important points is that you're checking a specific instance id against another different specific instance id so they're never going to match up.
Your code lacked freeing the stream after it's not used and setting global.music_name to music, but after fixing that it worked like breeze!
Thank you much, that's a very neat solution.
 
Top