diff --git a/README.md b/README.md
index c17820c6132c192e2c9954387c5d1a771b87d850..8be96cc97acb1b015cd2d48624e68cd48e551198 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ In a script,
 1. Initialize gdpd
 
 ```python
-onready var _gdpd = load("res://addons/gdpd/bin/gdpd.gdns").new()
+@onready var _gdpd = load("res://addons/gdpd/bin/gdpd.gdns").new()
 ```
 
 2. Initialize the audio inputs and outputs
@@ -64,6 +64,7 @@ For a full working example, open the Godot project in the demo folder.
 
 # Compiling gdpd
 
+
 ## Compiling for GNU/Linux
 
 - Install the following packages :
@@ -71,7 +72,8 @@ For a full working example, open the Godot project in the demo folder.
 - Open a terminal and type the following commands :
 	- git clone https://gitlab.univ-lille.fr/ivmi/gdpd.git
 	- cd gdpd
-	- ./update.sh linux
+	- git submodule update --init --recursive
+	- scons
 
 ## Cross-compiling for Windows on GNU/Linux
 
@@ -80,7 +82,8 @@ For a full working example, open the Godot project in the demo folder.
 - Type the following commands :
 	- git clone https://gitlab.univ-lille.fr/ivmi/gdpd.git
 	- cd gdpd
-	- ./update.sh windows
+	- git submodule update --init --recursive
+	- scons platform=windows
 
 
 ## Compiling for Mac OSX
@@ -89,7 +92,9 @@ todo
 
 ## Compiling for Android (/Quest)
 
-todo
+```sh
+scons platform=android
+```
 
 ## Compiling for the Web
 
diff --git a/SConstruct b/SConstruct
index 3eb03e7bd167d7fbdc4e136287f8a2b0307642b6..f152e6dd2ee83a5780cd3043f72ad63522c7ecc0 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,43 +1,8 @@
-#!python
-import os, subprocess
+#!/usr/bin/env python
+import os
+import sys
 
-opts = Variables([], ARGUMENTS)
-
-# Gets the standard flags CC, CCX, etc.
-env = Environment(ENV = os.environ)
-
-# Define our options
-opts.Add(EnumVariable('target', "Compilation target", 'release', ['d', 'debug', 'r', 'release']))
-opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
-opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", '', ['', 'windows', 'x11', 'linux', 'osx']))
-opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'yes'))
-opts.Add(BoolVariable('use_mingw', "Use the MingW for cross-compiling", 'no'))
-opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'demo/addons/gdpd/bin/'))
-opts.Add(PathVariable('target_name', 'The library name.', 'libgdpd', PathVariable.PathAccept))
-
-# Local dependency paths, adapt them to your setup
-godot_headers_path = "src/godot-cpp/godot_headers/"
-cpp_bindings_path = "src/godot-cpp/"
-cpp_library = "libgodot-cpp"
-
-# only support 64 at this time..
-bits = 64
-
-# Updates the environment with the option variables.
-opts.Update(env)
-
-# Process some arguments
-if env['use_llvm']:
-    env['CC'] = 'clang'
-    env['CXX'] = 'clang++'
-
-
-if env['p'] != '':
-    env['platform'] = env['p']
-
-if env['platform'] == '':
-    print("No valid target platform selected.")
-    quit();
+env = SConscript("src/godot-cpp/SConstruct")
 
 # For the reference:
 # - CCFLAGS are compilation flags shared between C and C++
@@ -47,116 +12,82 @@ if env['platform'] == '':
 # - CPPDEFINES are for pre-processor defines
 # - LINKFLAGS are for linking flags
 
-# Check our platform specifics
-if env['platform'] == "osx":
-    env['target_path'] += 'osx/'
-    cpp_library += '.osx'
-    env.Append(CPPDEFINES=['__MACOSX_CORE__', 'HAVE_UNISTD_H', 'LIBPD_EXTRA'])
-    env.Append(CXXFLAGS=['-std=c++17'])
-    env.Append(LINKFLAGS=['-arch', 'x86_64','-framework', 
-                          'CoreAudio', '-framework', 'CoreFoundation'])
-    if env['target'] in ('debug', 'd'):
-        env.Append(CCFLAGS=['-g', '-O2', '-arch', 'x86_64'])
-    else:
-        env.Append(CCFLAGS=['-g', '-O3', '-arch', 'x86_64'])
-
-elif env['platform'] in ('x11', 'linux'):
-    env['CC'] = 'gcc'
-    env['CXX'] = 'g++'
-    env['target_path'] += 'x11/'
-    cpp_library += '.linux'
-    env.Append(CPPDEFINES=['__UNIX_JACK__', 'LIBPD_EXTRA'])
-    env.Append(LIBS=['jack', 'pthread'])
-    env.Append(LDPATH=['/usr/lib/x86_64-linux-gnu'])
-    if env['target'] in ('debug', 'd'):
-        env.Append(CCFLAGS=['-fPIC', '-g3', '-Og'])
-        env.Append(CFLAGS=['-std=c11'])
-        env.Append(CXXFLAGS=['-std=c++17'])
-    else:
-        env.Append(CCFLAGS=['-fPIC', '-O3'])
-        env.Append(CFLAGS=['-std=c11'])
-        env.Append(CXXFLAGS=['-std=c++17'])
-
-elif env['platform'] == "windows":
-    env['target_path'] += 'win/'
-    cpp_library += '.windows'
-    env.Append(ENV=os.environ)
-    env.Append(CPPDEFINES=['NOMINMAX'])
-
-    if not env['use_mingw']:
-        # MSVC
-        env.Append(LINKFLAGS=['/WX'])
-        if env['target'] == 'debug':
-            env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MTd'])
-        elif env['target'] == 'release':
-            env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
-    else:
-        # MinGW
-        env['CXX'] = 'x86_64-w64-mingw32-g++-win32'
-        env['CC'] = 'x86_64-w64-mingw32-gcc-win32'
-        #env.Append(CXXFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings', '-fpermissive'])
-        env.Append(CXXFLAGS=['-O3', '-std=c++14', '-Wwrite-strings', '-fpermissive'])
-        #env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
-        #env.Append(CPPDEFINES=['WIN32', '_WIN32', '_MSC_VER', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
-        env.Append(CFLAGS=['-DWINVER=0x502', '-DWIN32', '-D_WIN32', 
-                        '-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast'])
-        #env.Append(CPPDEFINES=['HAVE_UNISTD_H=1','LIBPD_EXTRA=1','PD=1', 
-                                #'PD_INTERNAL','USEAPI_DUMMY=1','libpd_EXPORTS'])
-        env.Append(CPPDEFINES=['PD_INTERNAL', 'libpd_EXPORTS']) 
-        env.Append(CPPDEFINES=['__WINDOWS_DS__'])
-        #env.Append(CPPDEFINES=['__WINDOWS_WASAPI__'])
-        #env.Append(CPPDEFINES=['__RTAUDIO_DUMMY__', 'LIBPD_EXTRA'])
-        #env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
-        env.Append(LDPATH=['/usr/x86_64-w64-mingw32/lib/'])
-        env.Append(LINKFLAGS=['-Wl,--export-all-symbols',
-                '-static-libgcc','/usr/x86_64-w64-mingw32/lib/libm.a'])
-
-    #env.Append(LIBS=['-lkernel32','-luser32', '-lgdi32', 
-    #                  '-lwinspool', '-lshell32', '-lole32', 
-    #                  '-loleaut32', '-luuid', '-lcomdlg32', 
-    #                  '-ladvapi32','-lws2_32', '-lwsock32',
-    #                  '-ldsound', '-lwinmm'])
-    env.Append(LIBS=['-lws2_32', '-lwsock32','-loleaut32', '-luuid',
-                     '-lole32', '-ldsound', '-lwinmm'])
-    #env.Append(LIBS=['-lws2_32', '-lwsock32','-loleaut32', '-lmfplat','-lmfuuid', 
-    #                 '-lole32', '-lwmcodecdspuuid' ,'-luuid','-lksuser'])
-    env['SHLIBSUFFIX']  = '.dll'
-
-    #env.Append(CPPDEFINES=['WINVER=0x502'])
-    #env.Append(CCFLAGS=['-W3', '-GR'])
-    env.Append(LINKFLAGS=['-pthread'])
-    #if env['use_mingw']:
-        #env['CC'] = 'x86_64-w64-mingw32-gcc'
-        #env['CXX'] = 'x86_64-w64-mingw32-g++'
-        #env['AR'] = "x86_64-w64-mingw32-ar"
-        #env['RANLIB'] = "x86_64-w64-mingw32-ranlib"
-        #env['LINK'] = "x86_64-w64-mingw32-g++"
-#        env.Append(CFLAGS=['-std=c11'])
-    #    env.Append(CXXFLAGS=['-fpermissive'])
-    #    env.Append(LIBS=['ws2_32', 'kernel32'])
-    #    env.Append(LINKFLAGS=['-shared', '-Wl,--export-all-symbols','-mwindows','-Wl,-enable-stdcall-fixup'])
-
-if env['target'] in ('debug', 'd'):
-    cpp_library += '.debug'
+env.Append(CPPPATH=['.', 'src/libpd/libpd_wrapper', 'src/libpd/libpd_wrapper/util', 'src/libpd/cpp','src/libpd/pure-data/src',  'src/rtaudio'])
+
+env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H',\
+		'-D_GNU_SOURCE','-DLIBPD_EXTRA'])
+
+sources = Glob('src/*.cpp') + Glob('src/rtaudio/*.cpp') +\
+		Glob('src/libpd/libpd_wrapper/*.c') +\
+		Glob('src/libpd/libpd_wrapper/util/*.c') +\
+		Glob('src/libpd/pure-data/extra/bob~/bob~.c') +\
+		Glob('src/libpd/pure-data/extra/bonk~/bonk~.c') +\
+		Glob('src/libpd/pure-data/extra/choice/choice.c') +\
+		Glob('src/libpd/pure-data/extra/fiddle~/fiddle~.c') +\
+		Glob('src/libpd/pure-data/extra/loop~/loop~.c') +\
+		Glob('src/libpd/pure-data/extra/lrshift~/lrshift~.c') +\
+		Glob('src/libpd/pure-data/extra/pd~/pd~.c') +\
+		Glob('src/libpd/pure-data/extra/pique/pique.c') +\
+		Glob('src/libpd/pure-data/extra/sigmund~/sigmund~.c') +\
+		Glob('src/libpd/pure-data/extra/stdout/stdout.c') +\
+		Glob('src/libpd/pure-data/src/[mg]_*.c') +\
+		Glob('src/libpd/pure-data/src/x_acoustics.c') +\
+		Glob('src/libpd/pure-data/src/x_arithmetic.c')+\
+		Glob('src/libpd/pure-data/src/x_array.c')+\
+		Glob('src/libpd/pure-data/src/x_connective.c')+\
+		Glob('src/libpd/pure-data/src/x_file.c')+\
+		Glob('src/libpd/pure-data/src/x_gui.c')+\
+		Glob('src/libpd/pure-data/src/x_interface.c')+\
+		Glob('src/libpd/pure-data/src/x_list.c')+\
+		Glob('src/libpd/pure-data/src/x_midi.c')+\
+		Glob('src/libpd/pure-data/src/x_misc.c')+\
+		Glob('src/libpd/pure-data/src/x_net.c')+\
+		Glob('src/libpd/pure-data/src/x_scalar.c')+\
+		Glob('src/libpd/pure-data/src/x_text.c')+\
+		Glob('src/libpd/pure-data/src/x_time.c')+\
+		Glob('src/libpd/pure-data/src/x_vexp.c')+\
+		Glob('src/libpd/pure-data/src/x_vexp_fun.c')+\
+		Glob('src/libpd/pure-data/src/x_vexp_if.c')+\
+		Glob('src/libpd/pure-data/src/d_[acgmorsu]*.c') +\
+		Glob('src/libpd/pure-data/src/d_dac.c') +\
+		Glob('src/libpd/pure-data/src/d_delay.c') +\
+		Glob('src/libpd/pure-data/src/d_fft.c') +\
+		Glob('src/libpd/pure-data/src/d_fft_fftsg.c') +\
+		Glob('src/libpd/pure-data/src/d_filter.c') +\
+		Glob('src/libpd/pure-data/src/s_audio.c') +\
+		Glob('src/libpd/pure-data/src/s_audio_dummy.c') +\
+		Glob('src/libpd/pure-data/src/s_inter.c') +\
+		Glob('src/libpd/pure-data/src/s_inter_gui.c') +\
+		Glob('src/libpd/pure-data/src/s_loader.c') +\
+		Glob('src/libpd/pure-data/src/s_main.c') +\
+		Glob('src/libpd/pure-data/src/s_net.c') +\
+		Glob('src/libpd/pure-data/src/s_path.c')  +\
+		Glob('src/libpd/pure-data/src/s_print.c') +\
+		Glob('src/libpd/pure-data/src/s_utf8.c')
+
+if env["platform"] == "linux":
+	env.Append(CPPDEFINES=['__UNIX_JACK__', 'HAVE_LIBDL'])
+	env.Append(LIBS=['jack', 'pthread'])
+	env.Append(LDPATH=['/usr/lib/x86_64-linux-gnu'])
+	env.Append(CFLAGS=['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast',
+						'-Wno-discarded-qualifiers',
+						'-fPIC', '-O3', '-ffast-math', '-funroll-loops', 
+						'-fomit-frame-pointer'])
+	env.Append(CXXFLAGS=['-std=c++17'])
+elif env["platform"] == "windows": 
+	env.Append(CPPDEFINES=['NOMINMAX', '__WINDOWS_DS__', 'PD_INTERNAL'])
+
+if env["platform"] == "macos":
+	library = env.SharedLibrary(
+		"demo/addons/gd4pd/bin/libgdpd.{}.{}.framework/libgd4pd.{}.{}".format(
+			env["platform"], env["target"], env["platform"], env["target"]
+		),
+		source=sources,
+	)
 else:
-    cpp_library += '.release'
-
-cpp_library += '.' + str(bits)
-
-# make sure our binding library is properly included
-env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/', 'src/libpd/cpp','src/libpd/pure-data/src', 'src/libpd/libpd_wrapper', 'src/libpd/libpd_wrapper/util', 'src/rtaudio'])
-env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
-env.Append(LIBS=[cpp_library])
-env.Append(CFLAGS=['-DUSEAPI_DUMMY', '-DPD', '-DHAVE_UNISTD_H', '-D_GNU_SOURCE'])
-
-# tweak this if you want to use different folders, or more folders, to store your source code in.
-env.Append(CPPPATH=['src/'])
-
-sources = Glob('src/*.cpp') + Glob('src/rtaudio/*.cpp') + Glob('src/libpd/libpd_wrapper/*.c') + Glob('src/libpd/libpd_wrapper/util/*.c') + Glob('src/libpd/pure-data/extra/**/*.c') + Glob('src/libpd/pure-data/src/[xmgz]_*.c') + Glob('src/libpd/pure-data/src/d_[acgmorsu]*.c') + Glob('src/libpd/pure-data/src/d_dac.c') + Glob('src/libpd/pure-data/src/d_delay.c') + Glob('src/libpd/pure-data/src/d_fft.c') + Glob('src/libpd/pure-data/src/d_fft_fftsg.c') + Glob('src/libpd/pure-data/src/d_filter.c') + Glob('src/libpd/pure-data/src/s_audio.c') + Glob('src/libpd/pure-data/src/s_audio_dummy.c') + Glob('src/libpd/pure-data/src/s_print.c') + Glob('src/libpd/pure-data/src/s_path.c')  + Glob('src/libpd/pure-data/src/s_main.c') + Glob('src/libpd/pure-data/src/s_inter.c') + Glob('src/libpd/pure-data/src/s_utf8.c') + Glob('src/libpd/pure-data/src/s_loader.c') + Glob('src/libpd/pure-data/extra/*.c') 
-
-library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
+	library = env.SharedLibrary(
+		"demo/addons/gd4pd/bin/libgdpd{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
+		source=sources,
+	)
 
 Default(library)
-
-# Generates help for the -h scons option.
-Help(opts.GenerateHelpText(env))
diff --git a/demo/Main.tscn b/demo/Main.tscn
index 8899168122e119736af3b4183b813d2987b3cad2..7bedbd4e653e562fe3106cda40556a5bed7d687c 100644
--- a/demo/Main.tscn
+++ b/demo/Main.tscn
@@ -1,9 +1,9 @@
-[gd_scene load_steps=2 format=2]
+[gd_scene load_steps=2 format=3 uid="uid://dlfiamica4p0h"]
 
-[sub_resource type="GDScript" id=1]
+[sub_resource type="GDScript" id="1"]
 script/source = "extends Control
 
-onready var _gdpd = load(\"res://addons/gdpd/bin/gdpd.gdns\").new()
+@onready var _gdpd = GdPd.new()
 
 func _ready():
 	pass
@@ -12,7 +12,8 @@ func _process(delta):
 	while _gdpd.has_message() :
 		var msg = _gdpd.get_next()
 		print(\"got message from pd \", msg)
-
+	pass
+	
 func _load_patch(pd_patch) :
 	#separate file name from directory
 	var patch_name = pd_patch.split(\"/\")[-1]
@@ -63,66 +64,61 @@ func _on_HSlider2_value_changed(value):
 "
 
 [node name="Control" type="Control"]
+layout_mode = 3
+anchors_preset = 15
 anchor_right = 1.0
 anchor_bottom = 1.0
-script = SubResource( 1 )
-__meta__ = {
-"_edit_use_anchors_": false
-}
+grow_horizontal = 2
+grow_vertical = 2
+script = SubResource("1")
 
 [node name="Stop" type="Button" parent="."]
-margin_left = 213.0
-margin_top = 83.0
-margin_right = 316.0
-margin_bottom = 129.0
+layout_mode = 0
+offset_left = 213.0
+offset_top = 83.0
+offset_right = 316.0
+offset_bottom = 129.0
 text = "Stop"
-__meta__ = {
-"_edit_use_anchors_": false
-}
 
 [node name="Start" type="Button" parent="."]
-margin_left = 73.0
-margin_top = 83.0
-margin_right = 177.0
-margin_bottom = 134.0
+layout_mode = 0
+offset_left = 73.0
+offset_top = 83.0
+offset_right = 177.0
+offset_bottom = 134.0
 text = "Start"
 
 [node name="HSlider" type="HSlider" parent="."]
-margin_left = 73.0
-margin_top = 193.0
-margin_right = 406.0
-margin_bottom = 209.0
+layout_mode = 0
+offset_left = 73.0
+offset_top = 193.0
+offset_right = 406.0
+offset_bottom = 209.0
 max_value = 12.0
-__meta__ = {
-"_edit_use_anchors_": false
-}
 
 [node name="Label" type="Label" parent="."]
-margin_left = 73.0
-margin_top = 170.0
-margin_right = 113.0
-margin_bottom = 184.0
+layout_mode = 0
+offset_left = 73.0
+offset_top = 170.0
+offset_right = 113.0
+offset_bottom = 184.0
 text = "Send pitch to patch1"
 
 [node name="HSlider2" type="HSlider" parent="."]
-margin_left = 73.0
-margin_top = 275.0
-margin_right = 406.0
-margin_bottom = 291.0
+layout_mode = 0
+offset_left = 73.0
+offset_top = 275.0
+offset_right = 406.0
+offset_bottom = 291.0
 max_value = 12.0
-__meta__ = {
-"_edit_use_anchors_": false
-}
 
 [node name="Label2" type="Label" parent="."]
-margin_left = 73.0
-margin_top = 246.0
-margin_right = 204.0
-margin_bottom = 260.0
+layout_mode = 0
+offset_left = 73.0
+offset_top = 246.0
+offset_right = 204.0
+offset_bottom = 260.0
 text = "Send pitch to patch2"
-__meta__ = {
-"_edit_use_anchors_": false
-}
 
 [connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"]
 [connection signal="pressed" from="Start" to="." method="_on_Start_pressed"]
diff --git a/demo/addons/gdpd/bin/gdpd.gdns b/demo/addons/gdpd/bin/gdpd.gdns
deleted file mode 100644
index 4a291d78bc236d788ab62f23796071ecb8cfb0fa..0000000000000000000000000000000000000000
--- a/demo/addons/gdpd/bin/gdpd.gdns
+++ /dev/null
@@ -1,9 +0,0 @@
-[gd_resource type="NativeScript" load_steps=2 format=2]
-
-[ext_resource path="res://addons/gdpd/bin/libgdpd.gdnlib" type="GDNativeLibrary" id=1]
-
-[resource]
-resource_name = "gdpd"
-class_name = "Gdpd"
-library = ExtResource( 1 )
-_sections_unfolded = [ "Resource" ]
diff --git a/demo/addons/gdpd/bin/libgdpd.gdnlib b/demo/addons/gdpd/bin/libgdpd.gdnlib
deleted file mode 100644
index 048e4afda8844119f77b118645465d3907cd9c32..0000000000000000000000000000000000000000
--- a/demo/addons/gdpd/bin/libgdpd.gdnlib
+++ /dev/null
@@ -1,18 +0,0 @@
-[general]
-
-singleton=false
-load_once=false
-symbol_prefix="godot_"
-reloadable=true
-
-[entry]
-
-X11.64="res://addons/gdpd/bin/x11/libgdpd.so"
-Windows.64="res://addons/gdpd/bin/win/libgdpd.dll"
-OSX.64="res://addons/gdpd/bin/osx/libgdpd.dylib"
-
-[dependencies]
-
-X11.64=[  ]
-Windows.64=[  ]
-OSX.64=[  ]
diff --git a/demo/addons/gdpd/gdpd.gdextension b/demo/addons/gdpd/gdpd.gdextension
new file mode 100644
index 0000000000000000000000000000000000000000..dda572ae21d2b67f3e06b5fd7144fe472a026a3f
--- /dev/null
+++ b/demo/addons/gdpd/gdpd.gdextension
@@ -0,0 +1,23 @@
+[configuration]
+
+entry_symbol = "gdpd_library_init"
+compatibility_minimum = 4.1
+
+[libraries]
+
+macos.debug = "res://addons/gdpd/bin/libgdpd.macos.template_debug.framework"
+macos.release = "res://addons/gdpd/bin/libgdpd.macos.template_release.framework"
+windows.debug.x86_32 = "res://addons/gdpd/bin/libgdpd.windows.template_debug.x86_32.dll"
+windows.release.x86_32 = "res://addons/gdpd/bin/libgdpd.windows.template_release.x86_32.dll"
+windows.debug.x86_64 = "res://addons/gdpd/bin/libgdpd.windows.template_debug.x86_64.dll"
+windows.release.x86_64 = "res://addons/gdpd/bin/libgdpd.windows.template_release.x86_64.dll"
+linux.debug.x86_64 = "res://addons/gdpd/bin/libgdpd.linux.template_debug.x86_64.so"
+linux.release.x86_64 = "res://addons/gdpd/bin/libgdpd.linux.template_release.x86_64.so"
+linux.debug.arm64 = "res://addons/gdpd/bin/libgdpd.linux.template_debug.arm64.so"
+linux.release.arm64 = "res://addons/gdpd/bin/libgdpd.linux.template_release.arm64.so"
+linux.debug.rv64 = "res://addons/gdpd/bin/libgdpd.linux.template_debug.rv64.so"
+linux.release.rv64 = "res://addons/gdpd/bin/libgdpd.linux.template_release.rv64.so"
+android.debug.x86_64 = "res://addons/gdpd/bin/libgdpd.android.template_debug.x86_64.so"
+android.release.x86_64 = "res://addons/gdpd/bin/libgdpd.android.template_release.x86_64.so"
+android.debug.arm64 = "res://addons/gdpd/bin/libgdpd.android.template_debug.arm64.so"
+android.release.arm64 = "res://addons/gdpd/bin/libgdpd.android.template_release.arm64.so"
diff --git a/demo/default_env.tres b/demo/default_env.tres
index 20207a4aa2cfbae0c95636531b00d91502940d12..7556034046022899d5c04d62b0d11a112d61f743 100644
--- a/demo/default_env.tres
+++ b/demo/default_env.tres
@@ -1,7 +1,7 @@
-[gd_resource type="Environment" load_steps=2 format=2]
+[gd_resource type="Environment" load_steps=2 format=3 uid="uid://7q3at2gctprf"]
 
-[sub_resource type="ProceduralSky" id=1]
+[sub_resource type="Sky" id="1"]
 
 [resource]
 background_mode = 2
-background_sky = SubResource( 1 )
+sky = SubResource("1")
diff --git a/demo/icon.png.import b/demo/icon.png.import
index a4c02e6e27173699ab89f60c32661726fadfdbcd..1d4172c193e61612e161a0ba84bd581e2354df2f 100644
--- a/demo/icon.png.import
+++ b/demo/icon.png.import
@@ -1,8 +1,9 @@
 [remap]
 
 importer="texture"
-type="StreamTexture"
-path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
+type="CompressedTexture2D"
+uid="uid://dhwg245htvjgs"
+path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
 metadata={
 "vram_texture": false
 }
@@ -10,26 +11,24 @@ metadata={
 [deps]
 
 source_file="res://icon.png"
-dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
+dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
 
 [params]
 
 compress/mode=0
+compress/high_quality=false
 compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
+compress/hdr_compression=1
 compress/normal_map=0
-flags/repeat=0
-flags/filter=true
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
 process/fix_alpha_border=true
 process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
 process/normal_map_invert_y=false
-stream=false
-size_limit=0
-detect_3d=true
-svg/scale=1.0
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/demo/patch1.pd b/demo/patch1.pd
index 295f29d7515db9dca6c5e2786ea944188d612441..30acf1a8d97430581802ad5ec65b61388a90ae1f 100644
Binary files a/demo/patch1.pd and b/demo/patch1.pd differ
diff --git a/demo/patch2.pd b/demo/patch2.pd
index e4495276a278f03fd8fe1962354f243a9d8667e1..dced1b7e3af757e8af21d3900705a4c6a71fc416 100644
Binary files a/demo/patch2.pd and b/demo/patch2.pd differ
diff --git a/demo/project.godot b/demo/project.godot
index 7ad6ab0d873eb848fbed384952c6683aaff2acea..acda1c867627c09af846746c1ab6c32db7e8d38b 100644
--- a/demo/project.godot
+++ b/demo/project.godot
@@ -6,22 +6,18 @@
 ;   [section] ; section goes between []
 ;   param=value ; assign values to parameters
 
-config_version=4
-
-_global_script_classes=[  ]
-_global_script_class_icons={
-}
+config_version=5
 
 [application]
 
 config/name="GdPd"
 run/main_scene="res://Main.tscn"
+config/features=PackedStringArray("4.1")
 run/low_processor_mode=true
 config/icon="res://icon.png"
 
 [rendering]
 
+environment/defaults/default_environment="res://default_env.tres"
 quality/driver/driver_name="GLES2"
 vram_compression/import_etc=true
-vram_compression/import_etc2=false
-environment/default_environment="res://default_env.tres"
diff --git a/src/gdlibrary.cpp b/src/gdlibrary.cpp
deleted file mode 100644
index 0381d24d16b18c7d5bced2d46a1f99ff1fd144a9..0000000000000000000000000000000000000000
--- a/src/gdlibrary.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "gdpd.hpp"
-
-extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
-    godot::Godot::gdnative_init(o);
-}
-
-extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
-    godot::Godot::gdnative_terminate(o);
-}
-
-extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
-    godot::Godot::nativescript_init(handle);
-
-    godot::register_class<godot::Gdpd>();
-}
-
diff --git a/src/gdpd.cpp b/src/gdpd.cpp
index e1c3d57995a9af2edb5a68e1d0f6b3f46e03e90c..039cccbf08a7b8814bb2185c4a3d5537986e4823 100644
--- a/src/gdpd.cpp
+++ b/src/gdpd.cpp
@@ -1,50 +1,78 @@
-#include "gdpd.hpp"
+/***************************************************************************
+ *  gdpd.cpp
+ *  Part of GdPd
+ *  2023- see README for AUTHORS
+ *  https://gitlab.univ-lille.fr/immersync
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 130, Boston, MA 02111-1307, USA.
+ */
+
+#include "gdpd.h"
+
+
+#include <godot_cpp/core/class_db.hpp>
+
+#include <godot_cpp/classes/os.hpp>
+#include <godot_cpp/classes/global_constants.hpp>
+#include <godot_cpp/classes/label.hpp>
+#include <godot_cpp/variant/utility_functions.hpp>
 
 using namespace godot;
 
-void Gdpd::_register_methods() {
-    register_method("get_available_input_devices", 
-					&Gdpd::get_available_input_devices);
-    register_method("get_available_output_devices", 
-					&Gdpd::get_available_output_devices);
-    register_method("init_devices", &Gdpd::init_devices);
-    register_method("init", &Gdpd::init);
-    register_method("stop", &Gdpd::stop);
-    register_method("openfile", &Gdpd::openfile);
-    register_method("closefile", &Gdpd::closefile);
-    register_method("subscribe", &Gdpd::subscribe);
-    register_method("has_message", &Gdpd::has_message);
-    register_method("get_next", &Gdpd::get_next);
-    register_method("start_message", &Gdpd::start_message);
-    register_method("add_symbol", &Gdpd::add_symbol);
-    register_method("add_float", &Gdpd::add_float);
-    register_method("finish_list", &Gdpd::finish_list);
-    register_method("set_volume", &Gdpd::set_volume);
+void GdPd::_bind_methods() {
+	ADD_GROUP("GdPd", "gdpd_");
+
+	ClassDB::bind_method(D_METHOD("get_available_input_devices"),
+					&GdPd::get_available_input_devices);
+    ClassDB::bind_method(D_METHOD("get_available_output_devices"),
+					&GdPd::get_available_output_devices);
+    ClassDB::bind_method(D_METHOD("init_devices"), &GdPd::init_devices);
+    ClassDB::bind_method(D_METHOD("init"), &GdPd::init);
+    ClassDB::bind_method(D_METHOD("stop"), &GdPd::stop);
+    ClassDB::bind_method(D_METHOD("openfile"), &GdPd::openfile);
+    ClassDB::bind_method(D_METHOD("closefile"), &GdPd::closefile);
+    ClassDB::bind_method(D_METHOD("subscribe"), &GdPd::subscribe);
+    ClassDB::bind_method(D_METHOD("has_message"), &GdPd::has_message);
+    ClassDB::bind_method(D_METHOD("get_next"), &GdPd::get_next);
+    ClassDB::bind_method(D_METHOD("start_message"), &GdPd::start_message);
+    ClassDB::bind_method(D_METHOD("add_symbol"), &GdPd::add_symbol);
+    ClassDB::bind_method(D_METHOD("add_float"), &GdPd::add_float);
+    ClassDB::bind_method(D_METHOD("finish_list"), &GdPd::finish_list);
+    ClassDB::bind_method(D_METHOD("set_volume"), &GdPd::set_volume);
 }
 
-int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer, 
-					    unsigned int nBufferFrames, double streamTime, 
-						RtAudioStreamStatus status, void *userData){
-	Gdpd* gdpd = static_cast<Gdpd*>(userData);
-	gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime,
-					   status, userData);
-	return 0;
-}
-
-Gdpd::Gdpd(): m_vol(1) {
+GdPd::GdPd() : m_vol(1) {
 	//create message array
 	m_messages = new Array();
 	m_init=false;
 }
 
-void Gdpd::_init() {
+GdPd::~GdPd() {}
 
+int GdPd::audioCallback(void *outputBuffer, void *inputBuffer, 
+					    unsigned int nBufferFrames, double streamTime, 
+						RtAudioStreamStatus status, void *userData){
+	GdPd* gdpd = static_cast<GdPd*>(userData);
+	gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime,
+					   status, userData);
+	return 0;
 }
 
-Gdpd::~Gdpd() {
-}
 
-Array Gdpd::get_available_input_devices() {
+Array GdPd::get_available_input_devices() {
 	Array gdlist;
 	for(int d=0; d<m_audio.getDeviceCount(); d++) {
 		if(m_audio.getDeviceInfo(d).inputChannels>0) {
@@ -54,7 +82,7 @@ Array Gdpd::get_available_input_devices() {
 	return gdlist;
 }
 
-Array Gdpd::get_available_output_devices() {
+Array GdPd::get_available_output_devices() {
 	Array gdlist;
 	for(int d=0; d<m_audio.getDeviceCount(); d++) {
 		if(m_audio.getDeviceInfo(d).outputChannels>0) {
@@ -65,11 +93,10 @@ Array Gdpd::get_available_output_devices() {
 }
 
 
-int Gdpd::init_devices(String inputDevice, String outputDevice) {
-	std::wstring inpWs = inputDevice.unicode_str();
-	std::string inpStr(inpWs.begin(), inpWs.end());
-	std::wstring outWs = outputDevice.unicode_str();
-	std::string outStr(outWs.begin(), outWs.end());
+int GdPd::init_devices(String inputDevice, String outputDevice) {
+	std::string inpStr(inputDevice.utf8().get_data());
+	std::string outStr(outputDevice.utf8().get_data());
+
 
 	for(int d=0; d<m_audio.getDeviceCount(); d++) {
 		std::string n = m_audio.getDeviceInfo(d).name;
@@ -90,7 +117,7 @@ int Gdpd::init_devices(String inputDevice, String outputDevice) {
 	return start();
 }
 
-int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
+int GdPd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
 	m_inputDevice = m_audio.getDefaultInputDevice();
 	m_outputDevice = m_audio.getDefaultOutputDevice();
 	RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
@@ -102,7 +129,7 @@ int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
 	return start();
 }
 
-int Gdpd::start() {
+int GdPd::start() {
 	RtAudio::StreamParameters outParams, inpParams;
 	inpParams.deviceId = m_inputDevice;
 	inpParams.nChannels = m_nbInputs;
@@ -124,7 +151,7 @@ int Gdpd::start() {
 
 	//intialize rtaudio
 	if(m_audio.getDeviceCount()==0){
-		Godot::print("There are no available sound devices.");
+		UtilityFunctions::print("There are no available sound devices.");
 	}
 
 	RtAudio::StreamOptions options;
@@ -141,7 +168,7 @@ int Gdpd::start() {
 		print("Stream started");
 	}
 	catch(RtAudioError& e) {
-		Godot::print(e.getMessage().c_str());
+		UtilityFunctions::print(e.getMessage().c_str());
 	}
 
 	//create message hook
@@ -154,14 +181,14 @@ int Gdpd::start() {
 	return 0;
 }
 
-void Gdpd::stop() {
+void GdPd::stop() {
 	m_audio.stopStream();
 	m_audio.closeStream();
 	m_pd.computeAudio(false);
 	print("Stopped");
 }
 
-void Gdpd::processAudio(void *outputBuffer, void *inputBuffer, 
+void GdPd::processAudio(void *outputBuffer, void *inputBuffer, 
 						unsigned int nBufferFrames, double streamTime, 
 						RtAudioStreamStatus status, void *userData) {
 	int ticks = nBufferFrames / libpd_blocksize();
@@ -174,19 +201,15 @@ void Gdpd::processAudio(void *outputBuffer, void *inputBuffer,
 	}
 }
 
-void Gdpd::openfile(godot::String baseStr, godot::String dirStr) {
-	std::wstring baseWs = baseStr.unicode_str();
-	std::string baseS(baseWs.begin(), baseWs.end());
-	std::wstring dirWs = dirStr.unicode_str();
-	std::string dirS(dirWs.begin(), dirWs.end());
+void GdPd::openfile(godot::String baseStr, godot::String dirStr) {
+	std::string baseS(baseStr.utf8().get_data());
+	std::string dirS(dirStr.utf8().get_data());
 
 	if(m_patchsMap.find(baseS)!=m_patchsMap.end()) {
 		print("Patch "+baseS+" already opened");
 		return;
 	}
 
-	//libpd_openfile(baseS.c_str(), dirS.c_str());
-	//m_patch = m_pd.openPatch(baseS.c_str(), dirS.c_str());
 	pd::Patch p1 = m_pd.openPatch(baseS.c_str(), dirS.c_str());
 	if(!p1.isValid()) {
 		print("Could not open patch "+baseS);
@@ -195,36 +218,23 @@ void Gdpd::openfile(godot::String baseStr, godot::String dirStr) {
 		print("Opened patch "+baseS);
 		m_patchsMap[baseS] = p1;
 	}
-
-	//m_pd.subscribe("to_gdpd");
-
-	/*
-	if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) {
-		Godot::print("GDPD : Error starting libpd");
-	}
-	m_pd.setReceiver(this);
-	m_pd.computeAudio(true);
-	*/
 }
 
-void Gdpd::closefile(godot::String baseStr) {
-	std::wstring baseWs = baseStr.unicode_str();
-	std::string baseS(baseWs.begin(), baseWs.end());
+void GdPd::closefile(godot::String baseStr) {
+	std::string baseS(baseStr.utf8().get_data());
 	if(m_patchsMap.find(baseS)!=m_patchsMap.end()) {
 		m_pd.closePatch(m_patchsMap[baseS]);
 		m_patchsMap.erase(baseS);
 		print("Closed patch "+baseS);
 	}
-	//m_pd.closePatch(baseS.c_str());
 }
 
-void Gdpd::subscribe(String symbStr) {
-	std::wstring symbWs = symbStr.unicode_str();
-	std::string symbS(symbWs.begin(), symbWs.end());
+void GdPd::subscribe(String symbStr) {
+	std::string symbS(symbStr.utf8().get_data());
 	m_pd.subscribe(symbS.c_str());
 }
 
-bool Gdpd::has_message() {
+bool GdPd::has_message() {
 	//receive new messages
 	m_pd.receiveMessages();
 
@@ -233,43 +243,41 @@ bool Gdpd::has_message() {
     return size>0;
 }
 
-Array Gdpd::get_next() {
+Array GdPd::get_next() {
 	Array msg = m_messages->pop_front();
 	return msg;
 }
 
-int Gdpd::blocksize() {
+int GdPd::blocksize() {
 	int blocksize = libpd_blocksize();
 	return blocksize;
 }
 
-int Gdpd::start_message(int nbValues) {
+int GdPd::start_message(int nbValues) {
     int res = libpd_start_message(nbValues);
 	return res;
 }
 
-void Gdpd::add_symbol(String symbStr) {
-	std::wstring symbWs = symbStr.unicode_str();
-	std::string symbS(symbWs.begin(), symbWs.end());
+void GdPd::add_symbol(String symbStr) {
+	std::string symbS(symbStr.utf8().get_data());
 	libpd_add_symbol(symbS.c_str());
 }
 
-void Gdpd::add_float(float val) {
+void GdPd::add_float(float val) {
 	libpd_add_float(val);
 }
 
-int Gdpd::finish_list(String destStr) {
-	std::wstring destWs = destStr.unicode_str();
-	std::string destS(destWs.begin(), destWs.end());
+int GdPd::finish_list(String destStr) {
+	std::string destS(destStr.utf8().get_data());
     int res = libpd_finish_list(destS.c_str());
     return res;
 }
 
-void Gdpd::print(const std::string& message) {
-	Godot::print((std::string("GDPD : ")+message).c_str());
+void GdPd::print(const std::string& message) {
+	UtilityFunctions::print((std::string("GDPD : ")+message).c_str());
 }
 
-void Gdpd::receiveList(const std::string& dest, const pd::List& list) {
+void GdPd::receiveList(const std::string& dest, const pd::List& list) {
 	Array gdlist;
 
 	for(int i = 0; i < list.len(); ++i) {
@@ -285,7 +293,8 @@ void Gdpd::receiveList(const std::string& dest, const pd::List& list) {
 	m_messages->push_back(gdlist);
 }
 
-void Gdpd::set_volume(float vol) {
+void GdPd::set_volume(float vol) {
 	m_vol=vol;
 }
 
+
diff --git a/src/godot-cpp b/src/godot-cpp
index 3ee07f652bbbe91630a8346e3fe39a05f0f1d76a..28494f0bd59f9c35289524e503648ed8b4baaa59 160000
--- a/src/godot-cpp
+++ b/src/godot-cpp
@@ -1 +1 @@
-Subproject commit 3ee07f652bbbe91630a8346e3fe39a05f0f1d76a
+Subproject commit 28494f0bd59f9c35289524e503648ed8b4baaa59
diff --git a/src/libpd b/src/libpd
index e07d211d7b7e5f8dd6d2e3ddce557ae453161a14..fb174959373d18d8bd135f6a3abf86ded82be534 160000
--- a/src/libpd
+++ b/src/libpd
@@ -1 +1 @@
-Subproject commit e07d211d7b7e5f8dd6d2e3ddce557ae453161a14
+Subproject commit fb174959373d18d8bd135f6a3abf86ded82be534
diff --git a/src/rtaudio/RtAudio.os b/src/rtaudio/RtAudio.os
index 0b9b2a139f8fa92fbdef5de69509e3323e993406..c43f4627bf2cd50d533b48f950027c44bb627e9f 100644
Binary files a/src/rtaudio/RtAudio.os and b/src/rtaudio/RtAudio.os differ
diff --git a/update.sh b/update.sh
deleted file mode 100755
index 0dc54b3ae8bbdb793715a7a074df70f96cfa27fa..0000000000000000000000000000000000000000
--- a/update.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-git config --global url."https://".insteadOf git://
-git submodule update --init --recursive
-cd src/godot-cpp
-scons platform=$1 generate_bindings=yes target=release use_mingw=yes
-cd ../..
-scons platform=$1 target=release use_mingw=yes