Audio - Grisgram/gml-raptor GitHub Wiki
Audio support in raptor
is held simple enough to be adopted quickly and powerful enough to support at least different channels with independent volume, overlays, streaming and listeners.
For raptor
audio, no classes or constructors are involved. It is implemented as a series of global functions, so you have it at hand all the time.
There are five audio channels available in raptor, each with its own independent volume and enabled state (muting).
In addition, there's a 6th volume setting, the master volume, which is a multiplier to all other channels, so you can evenly increase or decrease all of them by modifying a single value.
Tip
All volume values are normalized percentage values ranging from 0...1
, where 0 means silent and 1 means 100% volume.
You can access each of the channel's volume settings and their enabled-state through the AUDIOSETTINGS
macro.
This macro is also included in the GAMESETTINGS
by default, so your audio settings are saved, whenever you invoke save_settings()
Channel | AUDIOSETTINGS | Best used for |
---|---|---|
Master | .master_volume |
The multiplier for all other channels. Defaults to 1.0
|
Ambience |
.ambience_enabled .ambience_volume
|
Your ambience sounds (atmosphere, wind, insects, water, etc). This is also used by room_default_audio functions (see below) |
Music |
.music_enabled .music_volume
|
Your background music. This is also used by room_default_audio functions (see below) |
Sound |
.sound_enabled .sound_volume
|
Your action sounds (footsteps, weapons, shots, explosions,...) |
Ui |
.ui_enabled .ui_volume
|
Your ui sounds (Button clicks, opening/closing of windows, ...) |
Voice |
.voice_enabled .voice_volume
|
Your talking characters and story tellers |
Tip
You may modify any of the volume/enabled settings any time in your game, however, for the ongoing streams (Ambience and Music), you need to invoke update_audio_volume()
after changing a setting to apply the new values to the running streams.
In the _GAME_SETTINGS_
folder of the project template, you will find the Audio_Configuration
script. Here you can set the defaults of all five channel types for your game.
To keep this page smaller in size, there are only the music defaults shown here, but when you open the file, you will see, that the values are available for each of the audio channels. Some channel types offer only a subset of the settings shown here, but they all follow the same scheme.
Setting | Default | Description |
---|---|---|
AUDIO_MUSIC_CHANGE_OVERLAY |
true | Defines, what shall happen, when you change the music. If you set overlay to true (default), then the fade_out of the old audio and the fade_in of the new audio will happen at the same time (softly overlapping each other). If you set overlay to false, the fade_out is performed first, until silence, and afterwards the fade_in of the new music starts. Most of the time you get a way better and more immersive audio experience, when you overlay them, but there are situations, where silence can be part of a dramatic effect. |
AUDIO_MUSIC_DEFAULT_FADE_IN_MS |
1000 | Duration of the fade-in of music |
AUDIO_MUSIC_DEFAULT_FADE_OUT_MS |
1000 | Duration of the fade-out of music, when you change the audio |
AUDIO_MUSIC_DEFAULT_LOOP |
true | Shall the audio play in a loop? |
AUDIO_MUSIC_DEFAULT_PITCH |
1.0 | The pitch modifier for the music |
AUDIO_MUSIC_DEFAULT_LISTENER_MASK |
-1 | The listener mask. Leave at default, if you don't have specific listeners in your game |
AUDIO_MUSIC_DEFAULT_PRIORITY |
9 | Audio stream priority. Compare with the other priority values in the file. |
For each of the channels, there is a play_*
function available, and they are divided into two groups:
- non-streaming channels (sound, ui and voice)
- streaming channels (music and ambience)
// Non-streaming channels
* play_sound (snd, gain, pitch, offset, listener_mask, priority)
* play_voice (snd, gain, pitch, offset, listener_mask, priority)
* play_ui_sound (snd, gain, pitch, offset, listener_mask, priority)
// streaming channels
* play_music (snd, gain, fade_in_time_ms, loop, force_restart, pitch, offset, listener_mask, priority)
* play_ambience (snd, gain, fade_in_time_ms, loop, force_restart, pitch, offset, listener_mask, priority)
Each of those functions returns a sound_id, which you should keep in a variable to be able to control it later (like stopping it).
You don't know, what a listener_mask
is? The GameMaker Manual has a huge section about its audio system. For a small game, you might not need this, but for an ambitious project, you should grab the information provided there.
Sometimes, you may want to "add" a sound to a streaming channel, like a random thunder in a rainy ambience. While you can, in theory, simply play the thunder through the play_sound
function (which will work fine), you would play the sound with the sound-channel-priority, its default gain and so on.
So, what you really want, is to overlay an ambience in the ambience channel with all the settings of this channel, from priority to fading timings (which a non-streaming channel does not even support).
That's, where the two *_overlay
functions come into play. You can add any sound to the streaming channel, using all this channels' settings. Overlay sounds do not loop, but they use the fade-in timing of the channel. The thunder mentioned above, overlaying a rainy ambience, is a very good example, how they should be used. That's, what they are here for.
Here are the two available functions for the two streaming channels:
// streaming overlays
* play_music_overlay (snd, gain, fade_in_time_ms, pitch, offset, listener_mask)
* play_ambience_overlay (snd, gain, fade_in_time_ms, pitch, offset, listener_mask)
The ambience and the music channel are very likely "playing all the time", as most games have a constant audio background. However, either through the settings dialog or through a hotkey, they might get muted at some point or their volume shall change.
To simplify this task, raptor
offers a function, to update both streaming channels on-the-fly while they play.
/// @function update_audio_streams()
/// @description Updates both streaming channels (music and ambience) with current
/// values for volume and their enabled state.
/// You must invoke this function whenever you change the enabled state
/// or the volume of a streaming channel
For the three non-streaming channels, there is a function available to stop playback immediately:
/// @function stop_sound(sound_id)
/// @description Stops any supplied playing sound_id
The streaming channels have their own exclusive stop_*
function, due to their streaming state.
/// @function stop_music()
/// @description Stops the currently playing music
/// @function stop_ambience()
/// @description Stops the currently playing ambience sounds
raptor
knows, which looping audio it is currently streaming, and when you change rooms, it will pick up and continue the sound exactly at the position, where you left a room, if the new room has the same default audio settings than the previous one (see chapter below).
This feature is especially useful in situations, where multiple rooms belong to each other, for instance, when you designed your settings menu in a separate room from the main menu room and want to have a seamless audio experience. The user won't recognize the room change, the audio won't restart.
To create a seamless experience when changing room, like in the settings-example above, raptor
offers a mechanic to define the default audio (music and ambience) for each room in the game.
Tip
You can set the default audio for a room any time, you do not need to be in that room!
I recommend, that you set up your default audios for all rooms in the onGameStart
function of the Game_Configuration
script.
If a room is entered and has a default audio set, the ROOMCONTROLLER
will start playback for you. That's another reason, to use this feature, as it takes away the need to control the streams in each and every room again and again.
These are the functions for room default audio:
/// @function set_room_default_audio(_room, _music, _ambience)
/// @description Define a music track and an ambience track that shall start playing
/// automatically, when the room is entered
/// @function get_default_music_for_room()
/// @description Get the sound_id of the currently playing music stream
/// @function get_default_ambience_for_room()
/// @description Get the sound_id of the currently playing ambience stream
This is how I do default audio in most of my GameJams. Those games most of the time consist of two rooms:
- A
main
room (a nice background image together with a How-to-play Button, a Play Button and the Credits) - A
play
room (the actual game)
I do this in the Game_Configuration
script in the onGameStart
function:
// Audio setup for rooms
set_room_default_audio(rmMain, mus_theme, amb_theme);
set_room_default_audio(rmPlay, mus_theme, amb_theme);
As you can see, both rooms have the same sounds set. This is, where raptor
will pick up the sound in the next room and just continue the stream, without restarting it.