GithubHelp home page GithubHelp logo

heraldofgargos / godot-fmod-integration Goto Github PK

View Code? Open in Web Editor NEW
175.0 9.0 13.0 1.03 MB

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

License: MIT License

Python 2.27% C++ 94.66% Shell 3.00% C 0.07%
game-development game-engine-development game-audio dynamic-audio godot-engine fmod fmod-api middleware

godot-fmod-integration's Introduction

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.

godot-fmod-integration's People

Contributors

heraldofgargos avatar piiertho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

godot-fmod-integration's Issues

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

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

WebGL/HTML5 integration

Hello,

I am curious if there is a way to use FMOD in the browser? From what I have seen there are no linkings/libraries for WebGL/HTML5 export.

Include Demo Project in the releases tab

Is your feature request related to a problem? Please describe.
In short: I'd like this repository to show newer users the demo so the FMOD code is a lot more tangible (instead of copy/pasting into unprepared/empty projects). It'd also be nice to be redirected/shown how to retrieve banks from an FMOD Studio project.

The long of it: I couldn't figure out how to get the bank files described in the lines of Basic Usage code that initialize the banks and I've been stuck for a day. I understood them as part of any project using FMOD but as an FMOD beginner I had no idea how to export/obtain banks from FMOD Studio, thinking it was a dependency like the .dlls. I just went off of what I had downloaded from the releases tab since I'm not normally a programmer who downloads unbuilt code.

Describe the solution you'd like
In the releases tab, add a separate download segment for the demo project with a description that goes over the fact that it's a Godot project with its own banks from an FMOD Studio project.

Describe alternatives you've considered
A description in the README that points out the demo and its usefulness, perhaps even a tutorial (a link or otherwise) on how to create/utilize banks in FMOD that can be used in this utility.

Additional context
Mostly personal frustration from being a new coder who's never stepped outside the usual GDScript boundaries.

I went as far as downloading VS2019, Python and Scons, cloning Godot to my hard drive, adding this module and building Godot only to realize I already had the .exe and some banks ready to go. The big "ohhhh" moment was seeing the FMOD integration demo pop up on the project list after I threw everything into one folder for the heck of it.

This is probably a fantastic tool for musicians like myself who are new to software dev (I'm already incredibly grateful to you and the contributors for giving me another option for audio) but this extra step in documentation would make it so much more approachable for people like myself.

Playing a MOD file

Sorry, this is the only way I can see to ask this kind of question. Godot is compiled, and the demo project works!

But none of the examples show me how to just play a simple file from the hard drive - all the examples use "banks".

In C++ it's pretty straight forward; system->createSound("path to sound", &sound) gives you a pointer to the sound, which you play with system->playSound(sound). But I can't see any equivalent functions available from the Fmod Godot object.

Specifically I have those old MOD "tracker" songs and I want my games to be able to play them. S3M, MOD, IT, XM etc. It's the sole reason I'm using your module :)

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

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

MacOS @rpath linking

There is an issue on OSX where FMOD does not properly path to required dynamic libraries. I have a workaround that does work, for sure. I'll include it in this issue. Do you think we could automate this process during the build?

install_name_tool -change @rpath/libfmod.dylib (path to libfmod.dylib) (path to Godot build)
install_name_tool -change @rpath/libfmodstudio.dylib (path to libfmodstudio.dylib) (path to Godot build)

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 #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.

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

Update to Godot 3.2

I wonder if this API works with current Godot stable version (3.2). If not, do you have plans to update de API?

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.