Skip to content

Functions Reference

gl326 edited this page Dec 12, 2022 · 21 revisions
  1. System
  1. Music/Ambience State
  2. Music Events
  3. Containers
  4. Parameters
  5. Busses

System

These functions are the absolute basic standard ones that would be used in any project to hook the system into the flow of your game.

bard_audio_update()

This should generally be run once per frame, i.e. in the Step event of a global controller object or something like that. This is where the state of all your audio will update. Internally, all timing and updates are based on the actual play states of the sound files and on deltatime / milliseconds, not frames.

bard_audio_clear(clearPersistent = false)

This should generally be run in a Room End event or equivalent "Level End" event in your game. This cleans up audio players, ends their associated sounds, and frees up the associated memory. Audio that is marked "persistent" like music or background ambience will continue to play unless you explicitly set the clearPersistent flag to TRUE ie. with bard_audio_clear(true);

bard_audio_load_event()

This function should be added to the Asynchronous Save/Load event in any global object. This allows the system to queue and process audio that needs to load in from audio groups or external files.

bard_audio_listener_update(_x,_y,_z = 0,_view_zoom_scale=1)

This updates the position of the audio listener to the specified x,y,(z) location. "Where" audio seems to be coming from will based on the spatial relationship between this "listener" position and the 3D position of playing sounds. Generally speaking, you'll want to run this function every frame and simply place the listener at the center of the camera view.

In the script bard_audio_system you'll find a global variable definition for global.listener_distance among other values - this is the default distance the listener is positioned away from the screen. The further it is, the less sounds will appear to pan left and right of the listener. Audio sounds most natural when the listener position reflects where the actual player's head is relative to the game screen. The _view_zoom_scale input scales this distance, such that if your game camera is zoomed in (thus scaling the view by some amount less than 1), the listener will be placed closer to the screen, making audio sound louder and closer. Or if the view is zoomed out (thus scaling the view by some amount greater than 1), the listener will be farther and audio will be quieter and more distant.

bard_audio_isloading()

This returns how many items are currently in the loading queue. If nothing is currently loading then it will return 0. You can use this to display loading graphics or delay entering a new area until audio loading is complete.

bard_audio_debug_gui()

Run this in a Draw GUI event to display information on the state of the audio system including currently playing sounds, their input volumes, emitter positions, beat timing, etc.

Music/Ambience State

These functions are for playing, getting data from, and updating global audio state and sounds, ie. music and ambiences. You do not need to use these if you would rather have your music and ambience state controlled your own way. They are essentially just interfaces for class_audio_playstack() instances called global.music_system and global.ambience_system. For the audio assets themselves you will need to provide string names of containers which you previously defined in the Audio Editor.

music_set(_container_name, tier=0, fadeOutTime=2, playbackGap=0, leaveOldPaused=false)

This sets the currently playing background music to the specified container. The "tier" can be any integer value 0 or greater (generally 0 - 3). In place of the container name, you can say 0 to mean "silent" or -1 to mean "empty/no instruction."

By assigning music a higher "tier," it will remember music playing on a lower tier and be able to return to it later. For example, if you are exploring an overworld area with its own background music on tier 0, you could enter combat and begin playing battle music on tier 1. Then when combat is over, set the tier 1 music to -1, thus allowing the overworld music to resume. If you want to enter a cutscene that is temporarily silent, you could set the tier 1 music to 0, and then -1 when you want the regular music to resume. Playing a non-looping container on a higher tier will also automatically resume the lower-tier music when the higher-tier song ends, like if you want to play a short jingle for finding an item.

set_music_key(key_name)

This lets you set the current musical key to one you defined in the bard_audio_system_music_keys script. The current music key only really matters if you use container_play_note().

music_playing()

Return the string name of the container that is currently playing from the music system. It will return 0 if it is currently set to be silent, or -1 if there is no instruction found.

music_playing_tier()

Returns the "tier" of the currently playing music audio. (An integer).

music_pause()

Pauses the currently playing music and prevents any updates until unpaused.

music_unpause()

Unpauses the music system.

music_time()

Return the current playtime of the current music container, in seconds.

music_time_beat()

Return the current playtime of the current music container, in beats. Beats are measured based on the "starting beat" and BPM you set for the music in the Audio Editor, or is set to 120BPM if none was provided. This counts progress through the song in terms of beats, so if you are halfway through the 1st beat of the song, this will return 0.5.

music_bpm()

Returns the BPM of the currently playing song. This also factors in the current pitch setting on the music, so if it is slowed down or sped up then you'll see what the BPM effectively currently is.

music_set_time()

This sets the playtime of the currently playing music to the provided time in seconds. This simply sets the playtime on the audio asset itself, so if you are playing a looping song that had a head intro, this won't revert the song back into its head.

music_align()

Runs a container_align() on the currently playing music, correcting any desyncs in the music.

ambience_set(_container_name,_tier=0,fadeOutTime=4)

This works just like music_set() but for ambience instead. There are fewer interfaces for getting ambience data since you generally don't do a lot of effects with ambience.

Music Events

These scripts are all named tersely and differently from everything else because it felt cool (sorry). They all grab data off the current highest tier music in the global.music_system, so they rely on you playing audio through the above systems to function. If you understand the inner workings well enough you can recreate them easily enough on your own system though.

beatEvent()

Return TRUE or FALSE if the currently playing music hit a new beat on the current frame. This state updates each time you run bard_audio_update(), and on a new beat will be TRUE for exactly 1 cycle and will then reset to false the next time bard_audio_update() is run. The frequency of beatEvents updates correctly if you change the pitch of the audio.

doubleBeatEvent()

Like above, but will return TRUE on half-beats as well as on the beats themselves.

measureEvent()

Like above, but will return TRUE only if the new beat also started off a new measure. Measures are counted based on how many beats per measure you set for he playing container in the Audio Editor. A typical 4/4 song will have a new "measure event" every 4 beats, whereas a 3/4 walts would be on every 3 beats, a 6/4 punk jam would be on every 6 beats, etc...

beatMS()

This returns the length of 1 beat in milliseconds. It can be used to time visual effects; for example, draw_circle(x,y,10+(5 * sin(pi * current_time/beatMS())),true) would draw a circle that expands and retracts in time with the current background music.

Containers

These functions are for playing and managing containers which you've defined in the Audio Editor. These are probably the functions you'll be making the most use of, for playing any conceivable sound in your game. Learn more about containers here.

container_play( containerName)

Plays the named container. The name should be provided as a string (ie. "music_area_1") and would be the name of a container you previously defined in the Audio Editor. This returns an integer ID for the sound you just played, which you can use to manipulate the playing audio instance.

If the container is a 3D sound, it will only play as a 3D-positioned sound if the playing object has objSpatialObject as a parent. 3D audio in this system is always associated with a playing object. It will always be positioned at, and move along with, the original playing object, so that for ex. if you have 2 enemy characters on screen who are both moving around and screaming constantly, you will hear each of their individual screams moving with the character as they move around.

If you attempt to play a container whose assets are not loaded into memory (because they're external, or in an audio group) the play will fail, and it will begin loading the assets in the background. For consistent behavior, it's best to load your audio assets in with a container_load() first.

container_play_position( containerName, _x, _y, _z = 0)

Like above, but this creates a new object called objLocationSound which holds the playing audio. This returns the instance id of the newly created objLocationSound so that you can move the object to reposition the sound if you so please. objLocationSound objects are destroyed in bard_audio_update() if and when their associated container stops playing.

container_play_instance(containerName, playID)

Nearly identical to container_play(), but it will only play the container if the provided playID is not -1. The intended use is as a shorthand for checking every frame if a sound needs to played, ie. in the Step Event of a scrollbar you might say if (dragging){ dragging_sound_id = container_play_instance("drag_sfx",dragging_sound_id);}. This would ensure that a dragging sound starts playing anytime the object is in the dragging state. This is a very pedantic alternate function to exist, but I like to use it a lot, so I thought you would too.

container_play_note(containerName, noteID)

This plays the named container, pitched to a musical note using the integer noteID input, based on the current music key set by set_music_key(). 0 is the "root" note, 1 is the next one up, etc. So if the key is set to C major and you want to play note 0, that's a C. This function assumes that the source sound file is pitched to be a C note, and simply re-pitches it to match the provided key/note.

You can also supply a fractional value for the noteID and it will give you its best approximation of what that is using the nearest adjacent integer pitches (we used this to create a theremin instrument in Chicory).

container_stop(containerName, playID = -1)

Stops the playing container. If any stopping effects have been defined in the Audio Editor, those will be respected, ie. the sound might delay for a moment before stopping, fade out, or play a tail sound. However, at the exact moment container_stop() is called, the container will from then on be treated as if it is NOT playing by container_is_playing(). If a playID is supplied, only that playing instance of the container will stop.

container_stop(containerName, playID)

If the playID is something other than -1, that instance of the container will be stopped. The function always returns -1. This is meant to be used in conjunction with container_play_instance(). For example, on a scrollbar object, you could say in its step event if (!dragging){dragging_sound = container_stop_instance("drag_sfx",dragging_sound);} and this would ensure that when the scroll bar is not being dragged, any associated dragging sounds it might be playing are also stopped.

container_stop_hard(containerName)

This stops the named container, ignoring any stop effects. The container then immediately clears itself from memory. Note that if the container has any component sounds which are not looping, this will allow those sounds to play out. Non-looping sounds CAN be cut off by using container_stop(), bu the purpose of this function is mostly to free up the memory. (I never used it, idk).

container_stop_all()

Stops all playing containers with a container_stop_hard().

container_pause(containerName)

Pauses the named container and prevents updates until further notice.

container_unpause(containerName)

Unpauses the named container.

container_is_paused(containerName)

Returns TRUE if the named container exists and is paused, else FALSE.

container_is_playing(containerName)

Returns TRUE if the named container is currently playing and FALSE if not. If the container has been stopped with container_stop() but is still playing some residual audio effects, this will return FALSE so as to correctly feedback that the container "has been stopped." This will also return FALSE if the container is paused, or doesn't exist at all.

container_is_running(containerName)

Exactly like container_is_playing(), but will also return TRUE even if the container is paused, indicating that it currently is running in some form even if it is not currently emitting audio.

container_pitch_note(container,noteID,playID=-1)

Updates an already-playing container to set its pitch to the given noteID, as if it were played with container_play_note(). If a playID other than 01 is provided, it will update only that specific playing instance of the container.

container_get_time(container)

Gets the current playtime for the first audio instance in the container, in seconds.

container_set_time(container,timeInSeconds)

Sets the current playtime for all audio instance in the named container to the provided time. This simply sets the tracking position for the audio assets themselves, so if the container is part of a sequence or is a looping music sound that had an into head item, this will not revert its state or go back to a previous sound.

container_align_time(container)

This goes through all the audio layers in the named container and sets them all to be at the same play position if they are sufficiently out of sync. This is a hack to correct music layers which can drift out of sync after a very long time. At one point Game Maker implemented audio_sync_groups to correct issues with this, but sync_groups have had their own issues int he past so by default we don't make use of them. If you are experiencing audio drift, you can try running this function every few minutes to correct it.

container_set_volume(container,volume)

Sets the volume of the container. Volume is generally a number from 0-1, 1 being (full volume) and 0 being (fully silent). It is not possible to make an audio asset louder than whatever its imported gain is, but if the container is turned down by being on an audio bus, then you could turn it back up by setting its volume to some value over 1. This function and the following ones generally exist fr creating fade effects and shouldn't really be used for mixing audio or adjusting it based on user settings, because this ignores the audio's relationship to other sounds in the mix.

container_fade(container,newVolume,time=2,curve=1)

Fades the names container to the new volume (generally 0-1) over an amount of time. This creates a temporary audio_tween, and you can learn more about their curve values here.

container_fadeout(container,time,curve)

This fades the container to 0 volume and then calls stop() on it once it reaches 0 volume. This creates a temporary audio_tween, and you can learn more about their curve values here.

container_persistent(container)

This returns TRUE if the named container is set to be persistent, else FALSE. Persistent containers will be ignored by bard_audio_clear() by default so that they can play across multiple screens/scenes/levels/etc.

container_set_persistent(container,trueorfalse)

Sets the named container to be persistent (TRUE) or not (FALSE).

container_reset(container)

Resets all stored data ont he saved container, so that the next time it is played it is as if it has not been played before. This is useful to, for example, set a Sequence back to its first sound, or reshuffle a random choice container.

container_load(container)

Loads all audio assets associated with the named container into memory. It works recursively, so if you have child containers inside the named container, their assets will also be loaded. Note that Game Maker audio assets are always loaded into memory by default. The might not be loaded into memory only if they are in an Audio Group, or if they are external files.

This function begins an asynchronous process, and will load audio groups/external files/etc. into memory one by one in the order they are encountered when crawling through the container contents. You can check the status of this process with bard_audio_isloading().

container_unload(container)

Unloads all audio assets associated with the named container out of memory. It works recursively, so if you have child containers inside the named container, their assets will also be unloaded. If the audio assets are Game Maker audio assets in the "default" audio group, they will not unload.

This function begins an asynchronous process, and will unload audio groups/external files/etc. one by one in the order they are encountered when crawling through the container contents. These processes share a queue with the loading processes, such that only 1 asynchronous process is in flight at a time. You can check the status of this process with bard_audio_isloading().

container_is_loaded(container,recursive = true)

Returns FALSE if any audio assets inside the container need to be loaded, otherwise it returns TRUE. If recursive is set to true (by default, it is) then all assets in all child containers are also checked.

container_set_effect(container_name,effect_name,enabled=true)

This function lets you enable or disable a named effect on a named container. The effect should be one that was previously defined in the audio editor. container_name = the name of the container (string). effect_name = the name of the effect (string). If you have multiple effects defined with the same name on the same container, they'll all turn on or off together - this is intentional, letting you apply multiple effects at once. enabled = whether the effect is turning ON or OFF (a boolean, default is true)

container_set_custom_effect(container_name,effect_struct,enabled=true)

This function lets you apply a custom-made audio effect struct to the named container. (Learn about audio effects here). "enabled" should be true to turn the effect ON and false to turn the effect OFF. (By default it is set to true). Here's an example:

custom_effect = audio_effect_create(AudioEffectType.Reverb1);	

custom_effect.size = .5;

custom_effect.damp = .5;

custom_effect.mix = 1;
container_set_custom_effect("bgm_1",custom_effect,true);

container_clear_effects(container_name)

This removes all effects from the named bus.

container_effect_state(container_name,effect_name)

Given the name of a container and the name of an effect attached to that container, this returns TRUE if that effect is enabled and FALSE if it is not.

container_audio_effect_state(container_name,effect_struct)

Given the name of a container and any audio_effect struct, this returns TRUE if that effect is enabled on that container and FALSE if it is not.

Parameters

These functions can be used to update audio parameters during gameplay. Audio parameters would have been previously defined in the Audio Editor. After any parameter changes state, any attached containers will update their sounds during the next bard_audio_update().

audio_param_set(parameter, value)

Sets the named parameter to the new value. The value is clamped between 0 and 100.

audio_param_set_unique(parameter, value, container_name, playID)

This updates the named parameter, but ONLY for the named container and playID. The playID would have been the return value from a previous container_play() event. The value is clamped between 0 and 100. You can use this to have multiple instances of the same sound be in different states.

audio_param_state(parameter, value)

Returns the current global value assigned to the named parameter. It will be between 0 and 100.

audio_param_unique_get(parameter, container_name, playID)

Returns the current unique state (0 - 100) for the parameter for the given container and playID, as previously set by audio_param_set_unique(). If there is no such unique state, this will return undefined.

audio_param_tween(parameter, tweenTo, timeInSeconds=1, curve=1)

This 'animates' the named parameter's value to the new value over a set amount of time, in seconds. This creates a temporary audio_tween, and you can learn more about their curve values here.

audio_param_reset(parameter)

Resets the named parameter to whatever value you set as its default in the Audio Editor.

audio_param_reset_all()

Resets all parameters to whatever value you set as their default in the Audio Editor.

Busses

These functions are for getting and changing the volume of busses during gameplay. Busses can be defined in the Audio Editor.

bus_gain(bus_name)

Returns the current gain setting of the named bus. This value will generally range from 0 (full volume) to -1 (fully turned off). Note that this is not necessarily what the 'effective' gain of this bus is when audio is played from it, since busses inherit the volume of parent busses.

bus_set_gain(bus_name, value)

Sets the gain of the bus. This value will generally range from 0 (full volume) to -1 (fully turned off). Any attached containers will update their volume accordingly in the following bard_audio_update() event.

bus_fade(bus_name, fadeToNegativeOneToZero=-1, fadeTimeInSeconds=1, curve=1)

This 'animates' the named bus's gain value to the new value over a set amount of time, in seconds. This creates a temporary audio_tween, and you can learn more about their curve values here.

bus_reset(bus_name)

This resets the named bus to its default gain value. Ie, if music is typically slightly turned down, but you temporarily muted it, this would be a way to return it to its default state.

bus_reset_all()

Resets all busses to their default values. This is slightly inefficient since it recalculates the active volume on every bus. This function exists mainly for debug purposes / entering the audio editor.

bus_set_effect(bus_name,effect_name,enabled=true,recursive=true)

This function lets you enable or disable a named effect on a named bus. The effect should be one that was previously defined in the audio editor. bus_name = the name of the bus (string). effect_name = the name of the effect (string). If you have multiple effects defined with the same name on the same bus, they'll all turn on or off together - this is intentional, letting you apply multiple effects at once. enabled = whether the effect is turning ON or OFF (a boolean, default is true) recursive = whether to apply the effect to all child busses as well (a boolean, default is true)

bus_set_custom_effect(bus_name,effect_struct,enabled=true,recursive=true)

This function lets you apply a custom-made audio effect struct to the named bus. (Learn about audio effects here). "enabled" should be true to turn the effect ON and false to turn the effect OFF. (By default it is set to true). When "recursive" is true, all child busses also take on the named audio effect. (By default is is set to true). Here's an example:

custom_effect = audio_effect_create(AudioEffectType.Reverb1);	

custom_effect.size = .5;

custom_effect.damp = .5;

custom_effect.mix = 1;
bus_set_custom_effect("master",custom_effect,true);

bus_clear_effects(bus_name,recursive=true)

This removes all effects from the named bus.

bus_effect_state(bus_name,effect_name)

Given the name of a bus and the name of an effect attached to that bus, this returns TRUE if that effect is enabled and FALSE if it is not.

bus_audio_effect_state(bus_name,effect_struct)

Given the name of a bus and any audio_effect struct, this returns TRUE if that effect is enabled on that bus and FALSE if it is not.

Clone this wiki locally