FMOD Studio middleware integration and scripting API bindings for the Godot game engine.

I started developing this back in 2019 but no longer maintain it. If you found this recently and are looking to integrate FMOD into a new Godot project, consider using the GDNative fork of this repo by utopia-rise.

Some of the documentation present here may still prove useful, so do have a read if you're interested.

All the integration code in this repo is MIT-licensed but in order to publish your FMOD-powered game commercially, you must register your project with FMOD and obtain a license. You don't need a license to get started however and when you're ready to publish, getting one is free for small projects and indies. Always check for the latest licensing terms on FMOD's website in case they get updated.

All the best with your Godot project - Alex.

P.S. Shoutout to Mike from Game From Scratch for covering this repo on his YouTube channel


FMOD Studio integration for Godot

A Godot C++ module that provides an integration and GDScript bindings for the FMOD Studio API.

This module exposes most of the Studio API functions to Godot's GDScript and also provides helpers for performing common functions like attaching Studio events to Godot nodes and playing 3D/positional audio. It is still very much a work in progress and some API functions are not yet exposed. Feel free to tweak/extend it based on your project's needs.

Latest release

Precompiled engine binaries for Windows, macOS and Linux with FMOD Studio already integrated, is available for downloading in the Releases tab.

Current build status Build Status

Building

If you wish to compile the module yourself, build instructions are available here.

Using the module

Basic usage

Start playing sounds in just 5 lines of GDScript!

extends Node

func _ready():
	# initialize FMOD
	# initializing with the LIVE_UPDATE flag lets you
	# connect to Godot from the FMOD Studio editor
	# and author events in realtime
	Fmod.system_init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_VOL0_BECOMES_VIRTUAL)

	# load banks
	# place your banks inside the project directory
	Fmod.bank_load("./Banks/Desktop/Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
	Fmod.bank_load("./Banks/Desktop/Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)

	# register a listener
	Fmod.system_add_listener($Listener)

	# play some events
	Fmod.play_one_shot("event:/Footstep", $SoundSource1)
	Fmod.play_one_shot("event:/Gunshot", $SoundSource2)

func _process(delta):
	# update FMOD every tick
	# calling system_update also updates the listener 3D position
	# and 3D positions of any attached event instances
	Fmod.system_update()

Calling Studio events

One-shots are great for quick sounds which you would want to simply fire and forget. But what about something a bit more complex like a looping sound or an interactive music event with a bunch of states? Here's an example of a Studio event called manually (ie. not directly managed by the integration). You can then call functions on that specific instance such as setting parameters. Remember to release the instance once you're done with it!

# create an event instance
# this is a music event that has been authored in the Studio editor
var my_music_event = Fmod.create_event_instance("event:/Waveshaper - Wisdom of Rage")

# start the event
Fmod.event_start(my_music_event)

# wait a bit
yield(music_state_timer, "timeout")

# setting an event parameter
# in this case causes the music to transition to the next phase
Fmod.event_set_parameter(my_music_event, "State", 2.0)

# wait a bit
yield(music_timer, "timeout")

# stop the event
Fmod.event_stop(my_music_event, Fmod.FMOD_STUDIO_STOP_ALLOWFADEOUT)

# schedule the event for release
Fmod.event_release(my_music_event)

Using the integration helpers

These are helper functions provided by the integration for playing events and attaching event instances to Godot Nodes for 3D/positional audio. The listener position and 3D attributes of any attached instances are automatically updated every time you call system_update(). Instances are also automatically cleaned up once finished so you don't have to manually call event_release().

# play an event at this Node's position
# 3D attributes are only set ONCE
# parameters cannot be set
Fmod.play_one_shot("event:/Footstep", self)

# same as play_one_shot but lets you set initial parameters
# subsequent parameters cannot be set
Fmod.play_one_shot_with_params("event:/Footstep", self, { "Surface": 1.0, "Speed": 2.0 })

# play an event attached to this Node
# 3D attributes are automatically set every frame (when update is called)
# parameters cannot be set
Fmod.play_one_shot_attached("event:/Footstep", self)

# same as play_one_shot_attached but lets you set initial parameters
# subsequent parameters cannot be set
Fmod.play_one_shot_attached_with_params("event:/Footstep", self, { "Surface": 1.0, "Speed": 2.0 })

# attaches a manually called instance to a Node
# once attached, 3D attributes are automatically set every frame (when update is called)
Fmod.attach_instance_to_node(event_instance, self)

# detaches the instance from its Node
Fmod.detach_instance_from_node(event_instance)

# quick helpers for pausing and muting
# affects all events including manually called instances
Fmod.pause_all_events()
Fmod.unpause_all_events()
Fmod.mute_all_events()
Fmod.unmute_all_events()

# returns True if a bank is currently loading
Fmod.banks_still_loading()

# blocks the calling thread until all sample loading is done
Fmod.wait_for_all_loads()

Timeline marker & music beat callbacks

You can have events subscribe to Studio callbacks to implement rhythm based game mechanics. Event callbacks leverage Godot's signal system and you can connect your callback functions through the integration.

# create a new event instance
var my_music_event = Fmod.create_event_instance("event:/schmid - 140 Part 2B")

# request callbacks from this instance
# in this case request both Marker and Beat callbacks
Fmod.event_set_callback(my_music_event,
	Fmod.FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER | Fmod.FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT)

# hook up our signals
Fmod.connect("timeline_beat", self, "_on_beat")
Fmod.connect("timeline_marker", self, "_on_marker")

# will be called on every musical beat
func _on_beat(params):
	print(params)

# will be called whenever a new marker is encountered
func _on_marker(params):
	print(params)

In the above example, params is a Dictionary which contains parameters passed in by FMOD. These vary from each callback. For beat callbacks it will contain fields such as the current beat, current bar, time signature etc. For marker callbacks it will contain the marker name etc. The event_id of the instance that triggered the callback will also be passed in. You can use this to filter out individual callbacks if multiple events are subscribed.

Playing sounds using FMOD Core / Low Level API

You can load and play any sound file in your project directory using the FMOD Low Level API bindings. Similar to Studio events these instances have to be released manually. Refer to FMOD's documentation pages for a list of compatible sound formats. If you're using FMOD Studio it's unlikely you'll have to use this API though.

# create a sound
var my_sound = Fmod.sound_create("./ta-da.wav", Fmod.FMOD_DEFAULT)

# play the sound
# this returns a handle to the channel
var channel_id = Fmod.sound_play(my_sound)

# wait a bit
yield(sound_timer, "timeout")

Fmod.sound_stop(channel_id)
Fmod.sound_release(my_sound)

Changing the default audio output device

By default, FMOD will use the primary audio output device as determined by the operating system. This can be changed at runtime, ideally through your game's Options Menu.

Here, system_get_available_drivers() returns an Array which contains a Dictionary for every audio driver found. Each Dictionary contains fields such as the name, sample rate and speaker config of the respective driver. Most importantly, it contains the id for that driver.

# retrieve all available audio drivers
var drivers = Fmod.system_get_available_drivers()

# change the audio driver
# you must pass in the id of the respective driver
Fmod.system_set_driver(id)

# retrieve the id of the currently set driver
var id = Fmod.system_get_driver()

Profiling & querying performance data

system_get_performance_data() returns an object which contains current performance stats for CPU, Memory and File Streaming usage of both FMOD Studio and the Core System.

# called every frame
var perf_data = Fmod.system_get_performance_data()

print(perf_data.CPU)
print(perf_data.memory)
print(perf_data.file)

Contributing

This project is still a work in progress and is probably not yet ready for use in full-blown production. If you run into issues (crashes, memory leaks, broken 3D sound etc.) let us know through the issue tracker. If you are a programmer, sound designer or a composer and wish to contribute, the contribution guidelines are available here. Thank you for being interested in this project!

An update from the creator

Unfortunately, due to full-time work and personal reasons, the development of this project has slowed down significantly and I'm no longer able to actively maintain and contribute new features.

However, this does not mean that the project is abandoned. All the work I've contributed so far is licensed under MIT, one of the most liberal open source licenses available. So feel free to use/modify/extend the code for your own projects - commercial or otherwise. Note that the MIT license only applies to the integration, not the FMOD SDK itself, which is proprietary and is not included in this repository.

Comments
  • Rework event managing and mute

    Rework event managing and mute

    This refactors event nature handling using UserData of FMOD::Studio::EventInstance. This refactors callbacks handling with UserData. This modifies Fmod::muteAllEvents and Fmod::unmuteAllEvents so that it set volume to 0 and get former volume back. This adds Fmod::muteMasterBus and Fmod::unmuteMasterBus helper functions.

  • Travis ci

    Travis ci

    Hi !
    Here is a PR for travis CI ! It assures code compiles for each platforms and provide a way to release for each platform (just by creating a release in github, the tag will be triggered, as you can see here).
    You should provide some environment variable to your travis :

    • ANDROID_NDK_ROOT: you should set it to /home/travis/build/alexfonseka/android-sdk/ndk-bundle. (it should be readable in console)
    • FMODUSER: A fmod user to download fmod api. (should not be visible in console)
    • FMODPASS: the password corresponding to FMODUSER. (should not be visible in console)
    • TRAVIS_TOKEN: a github personal access token to deploy release. (should not be visible in console)

    Hope you'll enjoy it !

  • Set3DSoundSettings : Enable to specify global distance unit

    Set3DSoundSettings : Enable to specify global distance unit

    As Godot uses pixels, fmod is interpreting 1 meter per pixel. This provide a wrapper method to set global distance unit parameter.

    I currently have not tested it in engine, only compilation. It would be nice to test it before merging. Same approach works with GDNative, it should not cause trouble to integrate.

  • Linking error on compile

    Linking error on compile

    When I try to build godot (8698876) on Windows 10 x64, I get this error:

    [ 97%] Linking Static Library ==> modules\freetype\freetype_builtin.windows.tools.64.lib [ 97%] Linking Program ==> bin\godot.windows.tools.64.exe LINK : fatal error LNK1181: cannot open input file 'fmod64_vc.windows.tools.64.lib' scons: *** [bin\godot.windows.tools.64.exe] Error 1181 scons: building terminated because of errors.

    I have tried both x86 and x64, multithreaded on/off, same error. I have tried both Windows and Windows 10 UWP api files for fmod.

    >python --version Python 3.7.2

    >scons --version script: v3.0.4.3a41ed6b288cee8d085373ad7fa02894e1903864, 2019-01-20 22:51:36 engine: v3.0.4.3a41ed6b288cee8d085373ad7fa02894e1903864, 2019-01-20 22:51:36

  • Potential concurrency issue in event callbacks

    Potential concurrency issue in event callbacks

    There is currently a reader writer problem associated with the callback system for events. Technically it should be fine for a single event since the Studio thread is the only thread that writes and the game thread is the only thread that reads but this constraint no longer applies for multiple events and things can change mid function which can lead to undesired behaviour.

    Reverting https://github.com/alexfonseka/godot-fmod-integration/pull/10 for now.

    A potential workaround would be to wrap the callbackInfo dictionary in a struct with a mutex and obtain a lock every time a thread has to either write to it or read from it.

  • LINK : fatal error LNK1181: impossible to open file fmod_vc.windows.opt.tools.64.lib

    LINK : fatal error LNK1181: impossible to open file fmod_vc.windows.opt.tools.64.lib

    Describe the bug After compiling Godot at 100%, i have this error :

    LINK : fatal error LNK1181: impossible d'ouvrir le fichier en entrée 'fmod_vc.windows.opt.tools.64.lib' scons: *** [bin\godot.windows.opt.tools.64.exe] Error 1181 scons: building terminated because of errors.

    To Reproduce Steps to reproduce the behavior:

    1. following these steps https://github.com/alexfonseka/godot-fmod-integration/blob/master/docs/building.md
    2. the bug is at the step 5 of the building.md

    Expected behavior Just want to compile godot with Fmod api working

    Screenshots image

    Configuration

    • OS: Windows x64
    • FMOD version 2.00.06
  • Android build

    Android build

    This enable to build godot engine with fmod module for android. Only armv8 and armv7 are supported, as x86 and x64 does not represents a significative part of android devices.

  • Update/remove UUID dependency

    Update/remove UUID dependency

    Previously this project had to rely on external dependencies to generate UUIDs but this is no longer the case. The integration will generate and keep track of IDs internally now. I initially wanted to use pointers cast to integers but this seemed a bit difficult to marshal back and forth so sticking to unsigned integers instead. This should greatly simplify the whole scripting process now that the extra responsibility of tracking IDs is taken care of by the integration.

  • Fix crash compiling Godot 3.2 branch after Mutex refactor

    Fix crash compiling Godot 3.2 branch after Mutex refactor

    Trying to compile Godot 3.2 branch after commit godotengine/godot@4ddcdc031b137c4f6e71ee190bec6942424a6658ee190bec6942424a6658 was breaking the compilation with this FMOD Godot Integration.

    The code seems to work correctly, but I'm accepting reviews, since C++ is not the language I use.

  • need video tutorial

    need video tutorial

    Hello, can you do a teaching video to demonstrate how Fmod and Godot interact? I'm new to both of them. I downloaded the demo, but I can't open the project file in the demo folder with Godot. I really want to learn Fmod and Godot integration, but I can't practice it. Thank you for your answer. Https://streamable.com/7qy0ok

  • I Replaced the Demo Project's Bank With My Own And The Positioning isn't Working

    I Replaced the Demo Project's Bank With My Own And The Positioning isn't Working

    Describe the bug I Replaced the Demo Project's Bank With My Own And The Positioning isn't Working. Maybe it's just a simple setting that's wrong!

    To Reproduce Steps to reproduce the behavior:

    1. Create new FMOD Project
    2. New 2D event or 3D event
    3. Drag some audio
    4. Export and replace the bank 5.Change the code to match the event name

    Expected behavior The sound should come out from SoundSource1 or SoundSource2. When I move the Listener, the sound should move.

    Configuration

    • OS: Windows10
    • FMOD version 2.00.09
  • Exporting project in Windows

    Exporting project in Windows

    when exported the exe crashes with this error:

    SCRIPT ERROR: GDScript::load_byte_code: Parse Error: Identifier 'Fmod' is not declared in the current scope. At: res://MainScene.gdc:36 ERROR: load_byte_code: Method/Function Failed, returning: ERR_PARSE_ERROR At: modules/gdscript/gdscript.cpp:785 ERROR: load: Condition ' err != OK ' is true. returned: RES() At: modules/gdscript/gdscript.cpp:2168 ERROR: Failed loading resource: res://MainScene.gdc At: core/io/resource_loader.cpp:285 ERROR: poll: res://MainScene.tscn:3 - Parse Error: [ext_resource] referenced nonexistent resource at: res://MainScene.gd At: scene/resources/resource_format_text.cpp:440 ERROR: load: Condition ' err != OK ' is true. returned: RES() At: core/io/resource_loader.cpp:208 ERROR: Failed loading resource: res://MainScene.tscn At: core/io/resource_loader.cpp:285 ERROR: Failed loading scene: res://MainScene.tscn At: main/main.cpp:1739 WARNING: cleanup: ObjectDB Instances still exist! At: core/object.cpp:2095 ERROR: clear: Resources Still in use at Exit! At: core/resource.cpp:425

  • Sound System:`File not found` on export project -MacOS

    Sound System:`File not found` on export project -MacOS

    Describe the bug

    After compiling on 3.2 stable Godot with this integration, I'm trying to export a MacOS .dmg of the example project included on the repository, and I get the following message on the terminal:

    FMOD Sound System: Live update enabled!
    FMOD Sound System: File not found.
    FMOD Sound System: File not found.
    FMOD Sound System: The requested event, parameter, bus or vca could not be found.
    FMOD Sound System: The requested event, parameter, bus or vca could not be found.
    

    The game graphics and logic runs well, but no sound is playing.

    To Reproduce Steps to reproduce the behavior:

    1. I'm adding a screenshot of the export settings I'm using

    Expected behavior The sound files are likely not getting exported with the app? Hoping Godot exports the FMOD files into the app.

    Screenshots Screen Shot 2020-02-19 at 4 15 49 PM

    Configuration

    • OS: MacOS Mojave Version 10.14.2
    • FMOD API version 2.00.07
    • Godot Engine v3.2.stable.custom_build.4e7d75ccd

    Additional context Maybe I'm just missing to add a specific path somewhere? Or do an extra step for Godot to see the Banks files

Bootstrapper and middleware for Echo framework in golang.
Bootstrapper and middleware for Echo framework in golang.

rk-echo Interceptor & bootstrapper designed for echo framework. Currently, supports bellow functionalities. Name Description Start with YAML Start ser

Jul 9, 2022
Goa is a web framework based on middleware, like koa.js.

Goa Goa is under construction, if you are familiar with koa or go and interested in this project, please join us. What is goa? goa = go + koa Just lik

Sep 27, 2022
Gzip Middleware for Go
 Gzip Middleware for Go

An out-of-the-box, also customizable gzip middleware for Gin and net/http.

Dec 19, 2022
Prometheus middleware for wish
Prometheus middleware for wish

promwish Package promwish provides a simple wish middleware exposing some Prometheus metrics. Example Usage You can add promwish as a middleware to yo

Nov 26, 2022
X-Response-Time middleware for fiber/v2

fiber-responsetime X-Response-Time middleware for fiber/v2 go get github.com/husanu/fiber-responsetime/v2 package main import ( "time" "github.com

Dec 17, 2021
Auth0 Middleware for go labstack/echo

go-echo-auth0-middleware Auth0 Middleware for go labstack/echo Example package main import ( "net/http" "github.com/auth0/go-jwt-middleware/v2/val

Nov 24, 2022
Gin middleware/handler to enable CORS support.

wcors Gin middleware/handler to enable CORS support. Usage Start using it Download and install it: go get github.com/wyy-go/wcors Import it in your co

Jan 8, 2022
Episodio V: Rise of the middleware

APITrials0.5 Episodio V: Rise of the middleware Captain's log: Up to date this file contains some simple errors to be corrected. They come from severa

Jan 10, 2022
EchoMiddleware - Echo Middleware with golang

EchoMiddleware middleware for echo server usage import ( "github.com/universe-3

Jan 4, 2022
⚡Simple cors middleware package for minima
⚡Simple cors middleware package for minima

This is package is wrapper based on rs/cors package made for minima. Geting Started Install the package using go get github.com/gominima/cors and call

Mar 7, 2022
Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects
Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects

Couper Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects. Getting started The quick

Nov 18, 2022
Boilerplate API template includes all the common packages and setup used for API development in this Company

Boilerplate API Boilerplate API template includes all the common packages and setup used for API development in this Company. Development Copy .env.ex

Feb 19, 2022
弹弹play 资源搜索节点 API 实现,基于 Cloudflare Workers 或 Golang 的两种实现。 || API implementations for "dandanplay" resource search service.

dandanplay-resource-service API implementations for "dandanplay" resource search service. 弹弹play 资源搜索节点的 API 实现。 提供基于 Cloudflare Workers 和 Golang 的两种实

Dec 5, 2022
REST API made using native Golang libraries. This API resembles the basic working of Instagram.
REST API made using native Golang libraries. This API resembles the basic working of Instagram.

Golang RESTful API for Instagram A Go based REST API built using native libraries. The API has been thoroughly worked through with Postman. Routes inc

Mar 16, 2022
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base

Backend API Example FiberGo Framework Docs : https://github.com/gofiber Info This application using firebase ecosystem Firebase Auth Cloud Storage Fir

May 31, 2022
Best simple, lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqL Database and Clean Architecture

GOLANG FIBER API (CLEAN ARCHITECTURE) Best simple, lightweight, powerful and really fast Api with Golang (Fiber, REL, Dbmate) PostgreSqLDatabase using

Sep 2, 2022
A quick and easy way to setup a RESTful JSON API

Go-Json-Rest A quick and easy way to setup a RESTful JSON API Go-Json-Rest is a thin layer on top of net/http that helps building RESTful JSON APIs ea

Jan 3, 2023
golang crud restful api with gorm , gin and mysql DB

crud restful api with golang , gorm , gin and mysql this api does a simple CRUD operations on a single table mysql Database . this is build on top off

Feb 26, 2022