EZAFX Documentation
Instant preset audio effects for GameMaker.
Want to add cool audio effects to your game, but don't know where to start? You're in the right place. This extension adds a way to apply audio effects to your sounds with a single line of code without any setup.
Features:
- 15 built-in audio effect presets
- Built-in debug view for sampling all of the effects in-game
- Supports applying effects to your whole game, a single sound, or a specific audio bus
Quick start
Just use audio_play_with_effect()
anywhere that you want to play a sound with an effect:
The arguments are the same as audio_play_sound()
with the exception of the fourth one. That argument should be one of the AFX_*
macros to specify which effect you want to use.
If you want to apply an audio effect to all of the sounds in your game, you can use afx_create_system()
:
In the above example, the "bass boost" effect will be applied to all of the sounds in your game. The final argument is set to 0
to indicate that we want this effect to be applied immediately. If the last argument is left out, it defaults to 1 second of transition time. All effects that can be applied to AFX systems can be smoothly transitioned from one another, which makes it extremely easy to add audio polish to your game. One thing to note about this argument, is that it is in frames and not seconds. So putting a 1
here does not mean 1 second, it means 1 frame. You can use game_get_speed(gamespeed_fps)
to determine how many frames are in a second.
When a system is no longer needed, you can free up its memory with afx_destroy_system()
:
Available effects
Macro | Description |
---|---|
AFX_NONE | Used to reset an AFX system to have no active effect. Audio will sound as it normally would. |
AFX_MUFFLE | Muffles the higher pitches of an audio, making it sound muffled. This is useful if you want to make audio sound like it's coming from another room. Also commonly used as a global effect for pause menus. |
AFX_DEEP_MUFFLE | This is a more pronounced version of AFX_MUFFLE . |
AFX_CHEAP_PHONE | Makes audio sound like it's coming from an old cell phone speaker, sounding cheap and harsh. |
AFX_CAVE | Gives the illusion that the audio is being played in an enourmous, echoing room. |
AFX_GRAND_CANYON | This will make your audio echo back to you at a steady interval, like how voices sound when you yell into a canyon. |
AFX_BLOWN_OUT_SPEAKER | Audio will have a slightly crushed tone and an amplified bass, as if coming out of a speaker that was pushed too far. |
AFX_CHIPTUNIZE | Will turn audio into a retro sounding 'chiptune' style. |
AFX_ROTARY_SPEAKER | Your audio will constantly flicker around, as if played from a spinning speaker. |
AFX_BASS_BOOST | Greatly increases lower frequencies. |
AFX_BRIGHT | Slightly increases frequencies closer to the higher end, giving the audio a slightly sharper feel. |
AFX_SCOOPED_MIDS | Makes the frequencies in the middle of the audio spectrum reduced, pronouncing only the high and low end sounds. This can be useful to apply to just your music, so that certain sound effects feel more pronounced without increasing their volume. |
AFX_SPRING | Gives the audio a very fast echo, as if being played in a very small room. Similar in quality to the sound springs make. |
AFX_TIN_CAN | This makes audio feel less pronounced and a little sharper, with an immediate echo. Can be used to make things sound cheap, or eerie when used effectively. |
AFX_DREAMY | Applies a special kind of large reverb that only effects the lower frequencies of audio, making things sound airy. |
AFX_HALL | Makes it so the audio sounds like it is playing in a medium-sized echoing hall. Useful for making things sound like they are coming from the inside of an empty room. |
Using systems
Creating an AFX system with afx_create_system()
actually returns a large struct with a lot of information and methods attached to it. You've already seen one, which is system.fx_set()
and is used to apply an effect to the system (or to reset the system to no effect by passing in AFX_NONE
). Here's a more complete code example showing some of the other methods:
Effect transitions
When you apply a new effect using system.fx_set()
and supply a number value for the second argument, it will transition the current audio effect to the new one over that many frames. By default this is done linearly, but EZAFX supports other types of easing curves. To change which easing curve is used, you can use system.set_curve()
:
The built-in available curves are all under the AFX_CURVE_*
macros, but these macros correlate to string values. What's actually going on under the hood, is that they represent channels in an animation curve asset (afx_ac
). If the included curves don't suit your need, you can add a new channel to this animation curve asset and pass in the name of the channel as a string to system.set_curve()
.
System API
system.fx_set(effect, [time])
Applies a new effect to the AFX system, over a period of frames set by [time]
. When omitted, defaults to current gamespeed (or 1 second). When a 0 is passed, it will apply the effect immediately.
system.fx_get()
Returns the currently applied effect, or AFX_NONE
if none is applied.
system.set_audio_bus(bus)
Detaches the system from its current bus and attaches it to a new bus. If this is done while sounds are playing the effect might be abrupt, so take care when using this method.
system.get_audio_bus()
Returns the current audio bus this system is attached to.
system.set_curve(curve)
Sets the easing curve for this system, where curve
is one of the AFX_CURVE_*
macros.
Debugging
If you want to view debug information about a previously created AFX system, or want to sample the various effects in-game without recompiling, there's an included function to help you:
Once you use afx_debug()
on an AFX system, a new debug view will be created for that system that can be viewed with the debug overlay. This view will show the currently applied effect and transition state, along with buttons to change the current effect in-game.
How it works
It can be useful to know how EZAFX works under the hood for things like profiling your game's performance, or when trying to accomplish more advanced audio techniques.
When you use audio_play_with_effect()
, it actually creates a new persistent instance in your game to handle the sound. This instance creates a new audio bus, emitter, and AFX system to control just this new bus. It then plays the sound on that bus, and when the sound is finished playing, it destroys itself along with the AFX system and emitter. For most games this happens transparently, but for games that use 3D audio, this may not work as expected. In those instances, I would suggest sticking to afx systems to have a more fine-tuned control over your audio.
When you create an AFX system with afx_create_system()
, it creates all of the actual audio effects up front. It then attaches them to the audio bus you've provided (or the master bus if none was provided). This is the secret sauce on how audio effect transitions are achieved: When created, all of the effect slots of the bus are taken over by permanent effects. When a system is first created, these effects are setup so that they don't have an effect on the sound. Then, when an effect is applied with system.fx_set()
, the values for the relevant effects are tweened to their new targets. This is good to know, because it exposes a flaw with EZAFX: It can't be used in combination with your own audio effects that you've created directly. It's all or nothing baby.
If you need to use custom audio effects in conjuction with EZAFX, I'd recommend taking a look at how the effects are setup and trying to setup your own. Otherwise it might be best to just use your own effects, and use EZAFX as a kicking-off point for the settings that you'd like to use. After all, EZAFX is meant to be a drop-in solution to avoid having to tinker with such things altogether, so if you grow out of it that is perfectly fine too.