diff --git a/src/gdpd.h b/src/gdpd.h
new file mode 100644
index 0000000000000000000000000000000000000000..bde2e850b59729c697b4802be5c01337788538a7
--- /dev/null
+++ b/src/gdpd.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ *  gd4pd.h
+ *  Part of GdPd
+ *  2023- see README for AUTHORS
+ ****************************************************************************/
+/*
+ *  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.
+ */
+
+
+
+#ifndef GDPD_CLASS_H
+#define GDPD_CLASS_H
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <godot_cpp/classes/node3d.hpp>
+#include <godot_cpp/classes/global_constants.hpp>
+#include <godot_cpp/classes/viewport.hpp>
+#include <godot_cpp/core/binder_common.hpp>
+#include <godot_cpp/classes/engine.hpp>
+#include <godot_cpp/classes/audio_stream_player.hpp>
+
+#include "PdBase.hpp"
+#include "RtAudio.h"
+
+using namespace godot;
+
+class GdPd : public AudioStreamPlayer, public pd::PdReceiver {
+	GDCLASS(GdPd, AudioStreamPlayer);
+
+protected:
+	static void _bind_methods();
+
+private:
+	float *m_inBuf; 
+	float *m_outBuf;
+	Array* m_messages;
+	pd::PdBase m_pd;
+	pd::Patch m_patch;
+	RtAudio m_audio;
+	unsigned int m_bufferFrames;
+	float m_vol;
+	int m_nbInputs;
+	int m_nbOutputs;
+	int m_sampleRate;
+	int m_inputDevice;
+	int m_outputDevice;
+	std::map<std::string, pd::Patch> m_patchsMap;
+
+	bool m_init;
+
+public:
+
+	GdPd();
+	virtual ~GdPd();
+
+	//libpd functions
+	Array get_available_input_devices();
+	Array get_available_output_devices();
+	int init_devices(String inputDevice, String outputDevice);
+	int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize);
+	int start();
+	void stop();
+	void openfile(String basename, String dirname);
+	void closefile(String basename);
+	bool has_message();
+	Array get_next();
+	int blocksize();
+	void subscribe(String symbStr);
+	int start_message(int nbValues);
+	void add_symbol(String symbStr);
+	void add_float(float val);
+	int finish_list(String destStr);
+
+	//libpd hooks
+	virtual void print(const std::string& message);
+	void receiveList(const std::string& dest, const pd::List& list);
+
+	//godot functions
+	void set_volume(float vol);
+	inline const float& get_volume(){return m_vol;}
+
+
+	//rtaudio
+	static int audioCallback(void *outputBuffer, void *inputBuffer, 
+							 unsigned int nBufferFrames, double streamTime, 
+							 RtAudioStreamStatus status, void *userData);
+	void processAudio(void *outputBuffer, void *inputBuffer, 
+					   unsigned int nBufferFrames, double streamTime, 
+					   RtAudioStreamStatus status, void *userData);
+};
+
+
+#endif
diff --git a/src/register_types.cpp b/src/register_types.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3097aa76755a0ca5256cbc0f1c282e5fdc7f5bad
--- /dev/null
+++ b/src/register_types.cpp
@@ -0,0 +1,37 @@
+#include "register_types.h"
+
+#include <gdextension_interface.h>
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/defs.hpp>
+#include <godot_cpp/godot.hpp>
+
+#include "gdpd.h"
+
+using namespace godot;
+
+void initialize_gdpd_module(ModuleInitializationLevel p_level) {
+	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
+		return;
+	}
+	ClassDB::register_class<GdPd>();
+}
+
+void uninitialize_gdpd_module(ModuleInitializationLevel p_level) {
+	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
+		return;
+	}
+}
+
+extern "C" {
+// Initialization.
+GDExtensionBool GDE_EXPORT gdpd_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
+	godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
+
+	init_obj.register_initializer(initialize_gdpd_module);
+	init_obj.register_terminator(uninitialize_gdpd_module);
+	init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
+
+	return init_obj.init();
+}
+}
diff --git a/src/register_types.h b/src/register_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..08159027394b3779c1344d4e4548566acdba0edd
--- /dev/null
+++ b/src/register_types.h
@@ -0,0 +1,11 @@
+#ifndef GD4PD_REGISTER_TYPES_H
+#define GD4PD_REGISTER_TYPES_H
+
+#include <godot_cpp/core/class_db.hpp>
+
+using namespace godot;
+
+void initialize_gdpd_module(ModuleInitializationLevel p_level);
+void uninitialize_gdpd_module(ModuleInitializationLevel p_level);
+
+#endif