From 6842eec25e9a45f16b4092d04945caf94fb5bf48 Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Wed, 3 Nov 2021 20:57:06 +0000 Subject: [PATCH 1/6] :sparkles: add support for DSP buffer size --- demo/addons/fmod/Fmod.gd | 3 +++ src/godot_fmod.cpp | 9 +++++++++ src/godot_fmod.h | 1 + 3 files changed, 13 insertions(+) diff --git a/demo/addons/fmod/Fmod.gd b/demo/addons/fmod/Fmod.gd index 15198ae5..aa4afab3 100644 --- a/demo/addons/fmod/Fmod.gd +++ b/demo/addons/fmod/Fmod.gd @@ -197,6 +197,9 @@ 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) -> int: + return godot_fmod.set_dsp_buffer_size(bufferLength, numberOfBuffers) + ############### ###LISTENERS### ############### diff --git a/src/godot_fmod.cpp b/src/godot_fmod.cpp index b038f815..efc30371 100644 --- a/src/godot_fmod.cpp +++ b/src/godot_fmod.cpp @@ -136,6 +136,7 @@ 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("_process", &Fmod::_process); register_signal("timeline_beat", "params", GODOT_VARIANT_TYPE_DICTIONARY); @@ -1313,6 +1314,14 @@ 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 :|") + } +} + 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..22d64cc4 100644 --- a/src/godot_fmod.h +++ b/src/godot_fmod.h @@ -183,6 +183,7 @@ namespace godot { void setListenerLock(int index, bool isLocked); bool getListenerLock(int index); Node* getObjectAttachedToListener(int index); + void setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers); String loadBank(String pathToBank, unsigned int flag); void unloadBank(String pathToBank); From 03ee1bf85dded3d04e0fe821a983a3961b1c78b0 Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Wed, 3 Nov 2021 21:01:47 +0000 Subject: [PATCH 2/6] add docs --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 0fa4b677..e702d7cf 100644 --- a/README.md +++ b/README.md @@ -523,6 +523,13 @@ 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) +``` + ### 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. From 5b277b1614fe7e274892456a7d98c0f83a30171c Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Thu, 4 Nov 2021 12:21:47 +0000 Subject: [PATCH 3/6] :sparkles: add getters for DSP buffer --- README.md | 4 ++++ demo/addons/fmod/Fmod.gd | 10 ++++++++-- src/godot_fmod.cpp | 12 ++++++++++++ src/godot_fmod.h | 4 ++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e702d7cf..6650a911 100644 --- a/README.md +++ b/README.md @@ -528,6 +528,10 @@ var id = Fmod.get_driver() 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 diff --git a/demo/addons/fmod/Fmod.gd b/demo/addons/fmod/Fmod.gd index aa4afab3..7b05e618 100644 --- a/demo/addons/fmod/Fmod.gd +++ b/demo/addons/fmod/Fmod.gd @@ -197,8 +197,14 @@ 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) -> int: - return godot_fmod.set_dsp_buffer_size(bufferLength, numberOfBuffers) +func set_dsp_buffer_size(bufferLength: int, numberOfBuffers: int) -> void: + godot_fmod.set_dsp_buffer_size(bufferLength, numberOfBuffers) + +func get_dsp_buffer_length() -> int: + return godot_fmod.get_dsp_buffer_length() + +func set_dsp_num_buffers() -> int: + return godot_fmod.get_dsp_num_buffers() ############### ###LISTENERS### diff --git a/src/godot_fmod.cpp b/src/godot_fmod.cpp index efc30371..2cf5b7a0 100644 --- a/src/godot_fmod.cpp +++ b/src/godot_fmod.cpp @@ -137,6 +137,8 @@ void Fmod::_register_methods() { 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_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); @@ -1322,6 +1324,16 @@ void Fmod::setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers) { } } +int Fmod::getSystemDSPBufferLength() { + ERROR_CHECK(coreSystem->getDSPBufferSize(&this->bufferlength, &this->numbuffers)); + return this->bufferlength; +} + +int Fmod::getSystemDSPNumBuffers() { + ERROR_CHECK(coreSystem->getDSPBufferSize(&this->bufferlength, &this->numbuffers)); + return this->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 22d64cc4..1fe3a613 100644 --- a/src/godot_fmod.h +++ b/src/godot_fmod.h @@ -111,6 +111,8 @@ namespace godot { int actualListenerNumber = 0; Listener listeners[FMOD_MAX_LISTENERS]; bool listenerWarning = true; + unsigned int bufferlength = 0; + int numbuffers = 0; Vector loadingBanks; Map banks; @@ -184,6 +186,8 @@ namespace godot { bool getListenerLock(int index); Node* getObjectAttachedToListener(int index); void setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers); + int getSystemDSPBufferLength(); + int getSystemDSPNumBuffers(); String loadBank(String pathToBank, unsigned int flag); void unloadBank(String pathToBank); From cc59eb458e00378294251baa54ac433a8ad3e8aa Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Fri, 5 Nov 2021 14:49:30 +0000 Subject: [PATCH 4/6] :alembic: add GUT test for DSP buffer size --- demo/addons/fmod/Fmod.gd | 4 ++-- demo/project.godot | 2 +- demo/test/unit/test_ainit_fmod.gd | 1 + demo/test/unit/test_global.gd | 8 ++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/demo/addons/fmod/Fmod.gd b/demo/addons/fmod/Fmod.gd index 7b05e618..6f0542f0 100644 --- a/demo/addons/fmod/Fmod.gd +++ b/demo/addons/fmod/Fmod.gd @@ -198,12 +198,12 @@ 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) + godot_fmod.set_dsp_buffer_size(bufferLength, numberOfBuffers) func get_dsp_buffer_length() -> int: return godot_fmod.get_dsp_buffer_length() -func set_dsp_num_buffers() -> int: +func get_dsp_num_buffers() -> int: return godot_fmod.get_dsp_num_buffers() ############### diff --git a/demo/project.godot b/demo/project.godot index 6ae3f110..c070b921 100644 --- a/demo/project.godot +++ b/demo/project.godot @@ -9,7 +9,7 @@ config_version=4 _global_script_classes=[ { -"base": "Node", +"base": "", "class": "FmodNative", "language": "NativeScript", "path": "res://addons/fmod/Fmod.gdns" 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..d5db64b4 100644 --- a/demo/test/unit/test_global.gd +++ b/demo/test/unit/test_global.gd @@ -55,3 +55,11 @@ 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) From e481043b85180a091796df9176c929ce0ad3b0b5 Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Fri, 5 Nov 2021 14:52:26 +0000 Subject: [PATCH 5/6] :recycle: fix accidental change --- demo/project.godot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/project.godot b/demo/project.godot index c070b921..6ae3f110 100644 --- a/demo/project.godot +++ b/demo/project.godot @@ -9,7 +9,7 @@ config_version=4 _global_script_classes=[ { -"base": "", +"base": "Node", "class": "FmodNative", "language": "NativeScript", "path": "res://addons/fmod/Fmod.gdns" From 61835aad6641d6c81f2599124f5eaff6dc581332 Mon Sep 17 00:00:00 2001 From: Miguel Gonzalez Sanchez <822035+bitbrain@users.noreply.github.com> Date: Sat, 13 Nov 2021 12:11:35 +0000 Subject: [PATCH 6/6] :ok_hand: address PR feedback --- demo/addons/fmod/Fmod.gd | 3 +++ demo/test/unit/test_global.gd | 6 ++++++ src/godot_fmod.cpp | 25 ++++++++++++++++++++----- src/godot_fmod.h | 5 ++--- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/demo/addons/fmod/Fmod.gd b/demo/addons/fmod/Fmod.gd index 6f0542f0..f8f8c3d3 100644 --- a/demo/addons/fmod/Fmod.gd +++ b/demo/addons/fmod/Fmod.gd @@ -199,6 +199,9 @@ func get_global_parameter_desc_list() -> Array: 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() diff --git a/demo/test/unit/test_global.gd b/demo/test/unit/test_global.gd index d5db64b4..f5b411c4 100644 --- a/demo/test/unit/test_global.gd +++ b/demo/test/unit/test_global.gd @@ -63,3 +63,9 @@ class TestGlobal: 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 2cf5b7a0..37e4c152 100644 --- a/src/godot_fmod.cpp +++ b/src/godot_fmod.cpp @@ -137,6 +137,7 @@ void Fmod::_register_methods() { 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); @@ -1324,14 +1325,28 @@ void Fmod::setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers) { } } -int Fmod::getSystemDSPBufferLength() { - ERROR_CHECK(coreSystem->getDSPBufferSize(&this->bufferlength, &this->numbuffers)); - return this->bufferlength; +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() { - ERROR_CHECK(coreSystem->getDSPBufferSize(&this->bufferlength, &this->numbuffers)); - return this->numbuffers; + unsigned int bufferlength; + int numbuffers; + ERROR_CHECK(coreSystem->getDSPBufferSize(&bufferlength, &numbuffers)); + return numbuffers; } void Fmod::pauseAllEvents(const bool pause) { diff --git a/src/godot_fmod.h b/src/godot_fmod.h index 1fe3a613..1c437c6c 100644 --- a/src/godot_fmod.h +++ b/src/godot_fmod.h @@ -111,8 +111,6 @@ namespace godot { int actualListenerNumber = 0; Listener listeners[FMOD_MAX_LISTENERS]; bool listenerWarning = true; - unsigned int bufferlength = 0; - int numbuffers = 0; Vector loadingBanks; Map banks; @@ -186,8 +184,9 @@ namespace godot { bool getListenerLock(int index); Node* getObjectAttachedToListener(int index); void setSystemDSPBufferSize(unsigned int bufferlength, int numbuffers); - int getSystemDSPBufferLength(); + unsigned int getSystemDSPBufferLength(); int getSystemDSPNumBuffers(); + Array getSystemDSPBufferSize(); String loadBank(String pathToBank, unsigned int flag); void unloadBank(String pathToBank);