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:

Create event

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():

Create event

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():

Cleanup event

Available effects

MacroDescription
AFX_NONEUsed to reset an AFX system to have no active effect. Audio will sound as it normally would.
AFX_MUFFLEMuffles 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_MUFFLEThis is a more pronounced version of AFX_MUFFLE.
AFX_CHEAP_PHONEMakes audio sound like it's coming from an old cell phone speaker, sounding cheap and harsh.
AFX_CAVEGives the illusion that the audio is being played in an enourmous, echoing room.
AFX_GRAND_CANYONThis 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_SPEAKERAudio will have a slightly crushed tone and an amplified bass, as if coming out of a speaker that was pushed too far.
AFX_CHIPTUNIZEWill turn audio into a retro sounding 'chiptune' style.
AFX_ROTARY_SPEAKERYour audio will constantly flicker around, as if played from a spinning speaker.
AFX_BASS_BOOSTGreatly increases lower frequencies.
AFX_BRIGHTSlightly increases frequencies closer to the higher end, giving the audio a slightly sharper feel.
AFX_SCOOPED_MIDSMakes 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_SPRINGGives 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_CANThis 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_DREAMYApplies a special kind of large reverb that only effects the lower frequencies of audio, making things sound airy.
AFX_HALLMakes 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:

Create event

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():

Create event

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:

Create event

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.