diff --git a/README.md b/README.md index 0fa4b677..6650a911 100644 --- a/README.md +++ b/README.md @@ -523,6 +523,17 @@ Fmod.set_driver(id) var id = Fmod.get_driver() ``` +### Reducing audio playback latency + +You 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: +```gdscript +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 `getPerformanceData` returns an object which contains current performance stats for CPU, Memory and File Streaming usage of both FMOD Studio and the Core System. diff --git a/demo/addons/fmod/Fmod.gd b/demo/addons/fmod/Fmod.gd index 15198ae5..f8f8c3d3 100644 --- a/demo/addons/fmod/Fmod.gd +++ b/demo/addons/fmod/Fmod.gd @@ -197,6 +197,18 @@ func get_global_parameter_desc_count() -> int: func get_global_parameter_desc_list() -> Array: return godot_fmod.get_global_parameter_desc_list() +func set_dsp_buffer_size(bufferLength: int, numberOfBuffers: int) -> void: + godot_fmod.set_dsp_buffer_size(bufferLength, numberOfBuffers) + +func get_dsp_buffer_size() -> Array: + return godot_fmod.get_dsp_buffer_size() + +func get_dsp_buffer_length() -> int: + return godot_fmod.get_dsp_buffer_length() + +func get_dsp_num_buffers() -> int: + return godot_fmod.get_dsp_num_buffers() + ############### ###LISTENERS### ############### diff --git a/demo/test/unit/test_ainit_fmod.gd b/demo/test/unit/test_ainit_fmod.gd index d5e952a1..d6f12f1d 100644 --- a/demo/test/unit/test_ainit_fmod.gd +++ b/demo/test/unit/test_ainit_fmod.gd @@ -3,5 +3,6 @@ extends "res://addons/gut/test.gd" func before_all(): # set up FMOD Fmod.set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0) + Fmod.set_dsp_buffer_size(512, 4) Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL) Fmod.set_sound_3D_settings(1, 32, 1) diff --git a/demo/test/unit/test_global.gd b/demo/test/unit/test_global.gd index 3af639e7..f5b411c4 100644 --- a/demo/test/unit/test_global.gd +++ b/demo/test/unit/test_global.gd @@ -55,3 +55,17 @@ class TestGlobal: func assert_contains_in_dict(dict: Dictionary, key: String): assert_has(dict, key, "Performance data should contains " + key + " data") + + func test_assert_should_have_dsp_buffer_length(): + var buffer_length = Fmod.get_dsp_buffer_length() + assert_eq(buffer_length, 512) + + func test_assert_should_have_dsp_num_buffers(): + var num_buffers = Fmod.get_dsp_num_buffers() + assert_eq(num_buffers, 4) + + func test_assert_should_have_dsp_buffer_size(): + var buffer_size = Fmod.get_dsp_buffer_size() + assert_eq(buffer_size.size(), 2) + assert_eq(buffer_size[0], 512) + assert_eq(buffer_size[1], 4) diff --git a/src/godot_fmod.cpp b/src/godot_fmod.cpp index b038f815..37e4c152 100644 --- a/src/godot_fmod.cpp +++ b/src/godot_fmod.cpp @@ -136,6 +136,10 @@ void Fmod::_register_methods() { register_method("get_global_parameter_desc_by_id", &Fmod::getGlobalParameterDescByID); register_method("get_global_parameter_desc_count", &Fmod::getGlobalParameterDescCount); register_method("get_global_parameter_desc_list", &Fmod::getGlobalParameterDescList); + register_method("set_dsp_buffer_size", &Fmod::setSystemDSPBufferSize); + register_method("get_dsp_buffer_size", &Fmod::getSystemDSPBufferSize); + register_method("get_dsp_buffer_length", &Fmod::getSystemDSPBufferLength); + register_method("get_dsp_num_buffers", &Fmod::getSystemDSPNumBuffers); register_method("_process", &Fmod::_process); register_signal("timeline_beat", "params", GODOT_VARIANT_TYPE_DICTIONARY); @@ -1313,6 +1317,38 @@ Node * Fmod::getObjectAttachedToInstance(uint64_t instanceId) { return node; } +void Fmod::setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers) { + if (bufferlength > 0 && numbuffers > 0 && ERROR_CHECK(coreSystem->setDSPBufferSize(bufferlength, numbuffers))) { + GODOT_LOG(0, "FMOD Sound System: Successfully set DSP buffer size") + } else { + GODOT_LOG(2, "FMOD Sound System: Failed to set DSP buffer size :|") + } +} + +Array Fmod::getSystemDSPBufferSize() { + unsigned int bufferlength; + int numbuffers; + Array a; + ERROR_CHECK(coreSystem->getDSPBufferSize(&bufferlength, &numbuffers)); + a.append(bufferlength); + a.append(numbuffers); + return a; +} + +unsigned int Fmod::getSystemDSPBufferLength() { + unsigned int bufferlength; + int numbuffers; + ERROR_CHECK(coreSystem->getDSPBufferSize(&bufferlength, &numbuffers)); + return bufferlength; +} + +int Fmod::getSystemDSPNumBuffers() { + unsigned int bufferlength; + int numbuffers; + ERROR_CHECK(coreSystem->getDSPBufferSize(&bufferlength, &numbuffers)); + return numbuffers; +} + void Fmod::pauseAllEvents(const bool pause) { for (int i = 0; i < events.size(); i++) { auto eventInstance = events.get(i); diff --git a/src/godot_fmod.h b/src/godot_fmod.h index bceddfb0..1c437c6c 100644 --- a/src/godot_fmod.h +++ b/src/godot_fmod.h @@ -183,6 +183,10 @@ namespace godot { void setListenerLock(int index, bool isLocked); bool getListenerLock(int index); Node* getObjectAttachedToListener(int index); + void setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers); + unsigned int getSystemDSPBufferLength(); + int getSystemDSPNumBuffers(); + Array getSystemDSPBufferSize(); String loadBank(String pathToBank, unsigned int flag); void unloadBank(String pathToBank);