在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:utopia-rise/fmod-gdnative开源软件地址:https://github.com/utopia-rise/fmod-gdnative开源编程语言:C++ 75.8%开源软件介绍:FMOD Studio integration for Godot using GDNativeA Godot C++ GDNative that provides an integration for the FMOD Studio API. FMOD is an audio engine and middleware solution for interactive audio in games. It has been the audio engine behind many titles such as Transistor, Into the Breach and Celeste. More on FMOD's website. This GDNative 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. Note: FMOD also provides a C# wrapper for their API which is used in the Unity integration and it is possible to use the same wrapper to build an integration for Godot in C#. However do note that this would only work on a Mono build of Godot as C# support is required and performance might not be on the same level as a C++ integration. Note: This project is a fork of godot-fmod-integration which uses godot module to integrate fmod in the engine. We thank alexfonseka for the work he did. This fork was designed to be able to use Fmod without building Godot Engine ! Continuous deliveryThis project uses github actions to continuously deploy released drivers. If you do not want to use those releases, you
can compile from sources by looking to compile from sources section. OS Compatibility matrix :
Godot compatibility matrix
Fmod compatibility matrix
Installing the plugin in your projectInstall addon folderWe provide releases in github repository. You can download It does not contains :
It contains :
Add Fmod libraries to appropriate folderDownload the FMOD Studio API (You need to create an account), if you have not done it yet.
Then place fmod libraries (both
You can also refer to
You should now be ready to go with Fmod and Godot ! Fmod on android with GDNativeFmod require a specific .jar to run on Android + some additionnal setup lines in the godot java wrapper for Android.
Starting from Godot 3.2, a new custom android build system was introduced. You can use add simple files to your godot
project to add java code and libraries without recompiling the whole engine. Here is how-to: And finally you have to setup the android export template. Using the GDNativeBasic usageextends Node
func _ready():
# set up FMOD
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
# load banks
Fmod.load_bank("res://Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Music.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
# register listener
Fmod.add_listener(0, self)
# play some events
Fmod.play_one_shot("event:/Music/Level 02", self) You can look at test scenes in POC folder of example project to find how to use the provided methods. Calling Studio eventsFollowing is an example of an event instance called manually (ie. not directly managed by the integration). These instances are refered by an int id, returned when created. Remember to release the instance once you're done with it. func _ready():
# set up FMOD
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
Fmod.set_sound_3D_settings(1.0, 64.0, 1.0)
# load banks
Fmod.load_bank("res://Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Music.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
# register listener
Fmod.add_listener(0, self)
# play some events
var my_music_event = Fmod.create_event_instance("event:/Music/Level 02")
Fmod.start_event(my_music_event)
var t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.stop_event(my_music_event, Fmod.FMOD_STUDIO_STOP_ALLOWFADEOUT)
t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.release_event(my_music_event) Using the integration helpersThese are helper functions provided by the integration for 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 # 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(instanceId, self)
# detaches the instance from its Node
FMOD.detach_instance_from_node(instanceId)
# blocks the calling thread until all sample loading is done
FMOD.wait_for_all_loads() Attach to existing event, 3D positioningHere is an example where we attach event and listener to instances. In the example project
you have a scene func _ready():
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
Fmod.set_sound_3D_settings(1.0, 64.0, 1.0)
# load banks
Fmod.load_bank("res://Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Music.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
# register listener
Fmod.add_listener(0, $Listener)
# Create event instance
var my_music_event = Fmod.create_event_instance("event:/Weapons/Machine Gun")
Fmod.start_event(my_music_event)
# attach instance to node
Fmod.attach_instance_to_node(my_music_event, $NodeToAttach)
var t = Timer.new()
t.set_wait_time(10)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.detach_instance_from_node(my_music_event)
Fmod.stop_event(my_music_event, Fmods.FMOD_STUDIO_STOP_IMMEDIATE) Timeline marker & music beat callbacksYou 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, Playing sounds using FMOD Core / Low Level APIYou can load and play any sound file in your project directory by using the FMOD Low Level API bindings. Similar to Studio Events these instances are identified by a UUID generated in script. Any instances you create must be released manually. Refer to FMOD's documentation pages for a list of compatible sound formats. You can use Fmod.load_file_as_music(path) to stream the file and loop it or Fmod.load_file_as_sound(path) to load and play it at once. Note that instances of file loaded as sound are automatically release by FMOD once played. func _ready():
# set up FMOD
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
Fmod.add_listener(0, self)
Fmod.load_file_as_music("res://assets/Music/jingles_SAX07.ogg")
music = Fmod.create_sound_instance("res://assets/Music/jingles_SAX07.ogg")
Fmod.play_sound(my_sound)
var t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.stop_sound(my_sound)
Fmod.release_sound(music)
Fmod.unload_file("res://assets/Music/jingles_SAX07.ogg") Muting all eventYou can mute all event using func _ready():
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
Fmod.set_sound_3d_settings(1.0, 64.0, 1.0)
# load banks
Fmod.load_bank("res://Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Music.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
# register listener
Fmod.add_listener(0, self)
# play some events
Fmod.play_one_shot("event:/Music/Level 02", self)
var my_music_event = Fmod.create_event_instance("event:/Music/Level 01")
Fmod.start_event(my_music_event)
var t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.mute_all_events();
t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.unmute_all_events() Pausing all eventsfunc _ready():
# set up FMOD
Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)
Fmod.set_sound_3d_settings(1/0, 64.0, 1.0)
# load banks
Fmod.load_bank("res://Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://Music.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
# register listener
Fmod.add_listener(0, self)
# play some events
Fmod.play_one_shot("event:/Music/Level 02", self)
var my_music_event = Fmod.create_event_instance("event:/Music/Level 01")
Fmod.start_event(my_music_event)
var t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.pause_all_events(true)
t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
Fmod.pause_all_events(false) Changing the default audio output deviceBy 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, # retrieve all available audio drivers
var drivers = Fmod.get_available_drivers()
# change the audio driver
# you must pass in the id of the respective driver
Fmod.set_driver(id)
# retrieve the id of the currently set driver
var id = Fmod.get_driver() Reducing audio playback latencyYou may encounter that the audio playback has some latency. This may be caused by the DSP buffer size. You can change the value before initialisation to adjust it: Fmod.set_dsp_buffer_size(512, 4)
# retrieve the buffer length
Fmod.get_dsp_buffer_length()
# retrieve the number of buffers
Fmod.get_dsp_num_buffers() Profiling & querying performance data
# called every frame
var perf_data = FMOD.get_performance_data()
print(perf_data.CPU)
print(perf_data.memory)
print(perf_data.file) ContributingIn order to be able to PR this repo from a fork, you need to add ThanksThis project is a forked from godot-fmod-integration
from alexfonseka. We'd like to thank him for the work he did, we simply adapted his
work to GDNative. |
2022-08-15
2022-08-17
2022-09-23
2023-10-27
2022-08-18
请发表评论