diff --git a/GdpdExample/Main.tscn b/GdpdExample/Main.tscn index 4259064..f71fe75 100644 --- a/GdpdExample/Main.tscn +++ b/GdpdExample/Main.tscn @@ -4,14 +4,17 @@ script/source = "extends Control var _gdpd +var _patches = [] func _load_patch(pd_patch) : #separate file name from directory var patch_name = pd_patch.split(\"/\")[-1] var patch_dir = pd_patch.trim_suffix(patch_name) - + #load patch - _gdpd.openPatch(patch_name, patch_dir) + var id = _gdpd.openPatch(patch_name, patch_dir) + _patches.append(id) +# print(\"loading:\" + str(id)) func _ready() : _gdpd = load(\"res://addons/gdpd/bin/gdpd.gdns\").new() @@ -29,16 +32,29 @@ func _on_Start_pressed() : var outs = _gdpd.get_available_output_devices() # _gdpd.init(0, 2, 48000, 64) _gdpd.init_devices(inps[0], outs[0]) - + #the patch path should be the absolute one _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) - + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\")) + _gdpd.subscribe(\"toGodot\") func _on_Stop_pressed() : - - _gdpd.closeAllPatches() + print(_patches) + for id in _patches: +# print(\"closing:\" + str(id)) + _gdpd.closePatch(id) + # _patches.erase(id) # <= BAD! + # Do not erase entries while iterating over the array !! + _patches.clear() _gdpd.stop() func _on_Send_pressed() : diff --git a/GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib b/GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib index 956a2bd..40765a5 100755 Binary files a/GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib and b/GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib differ diff --git a/bin (with gui, use pd 0.53-1)/gdpd.gdns b/bin (with gui, use pd 0.53-1)/gdpd.gdns new file mode 100644 index 0000000..869b3c3 --- /dev/null +++ b/bin (with gui, use pd 0.53-1)/gdpd.gdns @@ -0,0 +1,8 @@ +[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 ) diff --git a/bin (with gui, use pd 0.53-1)/libgdpd.gdnlib b/bin (with gui, use pd 0.53-1)/libgdpd.gdnlib new file mode 100644 index 0000000..048e4af --- /dev/null +++ b/bin (with gui, use pd 0.53-1)/libgdpd.gdnlib @@ -0,0 +1,18 @@ +[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/bin (with gui, use pd 0.53-1)/osx/libgdpd.dylib b/bin (with gui, use pd 0.53-1)/osx/libgdpd.dylib new file mode 100755 index 0000000..40765a5 Binary files /dev/null and b/bin (with gui, use pd 0.53-1)/osx/libgdpd.dylib differ diff --git a/bin (without gui)/gdpd.gdns b/bin (without gui)/gdpd.gdns new file mode 100644 index 0000000..869b3c3 --- /dev/null +++ b/bin (without gui)/gdpd.gdns @@ -0,0 +1,8 @@ +[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 ) diff --git a/bin (without gui)/libgdpd.gdnlib b/bin (without gui)/libgdpd.gdnlib new file mode 100644 index 0000000..048e4af --- /dev/null +++ b/bin (without gui)/libgdpd.gdnlib @@ -0,0 +1,18 @@ +[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/bin (without gui)/osx/libgdpd.dylib b/bin (without gui)/osx/libgdpd.dylib new file mode 100755 index 0000000..af2da4d Binary files /dev/null and b/bin (without gui)/osx/libgdpd.dylib differ diff --git a/src/gdpd.cpp b/src/gdpd.cpp index ed6c842..e6185f1 100644 --- a/src/gdpd.cpp +++ b/src/gdpd.cpp @@ -9,7 +9,7 @@ void Gdpd::_register_methods() { register_method("init", &Gdpd::init); register_method("stop", &Gdpd::stop); register_method("openPatch", &Gdpd::openPatch); - register_method("closeAllPatches", &Gdpd::closeAllPatches); + register_method("closePatch", &Gdpd::closePatch); register_method("subscribe", &Gdpd::subscribe); register_method("has_message", &Gdpd::has_message); register_method("get_next", &Gdpd::get_next); @@ -117,6 +117,10 @@ int Gdpd::start() { //libpd_set_verbose(1); +#if defined(WITH_GUI) + libpd_start_gui((char*)"/Applications/Pd-0.53-1.app/Contents/Resources"); +#endif + //start dsp m_pd.computeAudio(true); @@ -170,6 +174,10 @@ void Gdpd::stop() { m_audio.closeStream(); m_pd.computeAudio(false); print("Stopped"); + +#if defined(WITH_GUI) + libpd_stop_gui(); +#endif } void Gdpd::processAudio(void *outputBuffer, void *inputBuffer, @@ -185,39 +193,32 @@ void Gdpd::processAudio(void *outputBuffer, void *inputBuffer, } } -void Gdpd::openPatch(godot::String baseStr, godot::String dirStr) { +int Gdpd::openPatch(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()); - //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); } else { - print("Opened patch "+baseS); - m_patches.push_back(p1); + print("Opened patch "+baseS+ " [" + std::to_string(p1.dollarZero()) + "]"); + m_patchsMap[p1.dollarZero()] = 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); - */ + return p1.dollarZero(); } -void Gdpd::closeAllPatches() { - for (int idx = 0; idx < m_patches.size(); idx++) { - m_pd.closePatch(m_patches[idx]); +void Gdpd::closePatch(int id) { + if(m_patchsMap.find(id) != m_patchsMap.end()) { + // print("Closing patch, id: "+ std::to_string(id)); + std::string baseS = m_patchsMap[id].filename(); + m_pd.closePatch(m_patchsMap[id]); + m_patchsMap.erase(id); + print("Closed patch "+baseS+ " ["+ std::to_string(id) + "]"); } - m_patches.clear(); } void Gdpd::subscribe(String symbStr) { diff --git a/src/gdpd.hpp b/src/gdpd.hpp index 564375f..f3466ff 100644 --- a/src/gdpd.hpp +++ b/src/gdpd.hpp @@ -13,6 +13,8 @@ #include "PdReceiver.hpp" #include "RtAudio.h" +// #define WITH_GUI + namespace godot { class Gdpd : public godot::AudioStreamPlayer, public pd::PdReceiver { @@ -32,7 +34,7 @@ private: int m_sampleRate; int m_inputDevice; int m_outputDevice; - std::vector m_patches; + std::map m_patchsMap; bool m_init; @@ -51,8 +53,8 @@ public: int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); int start(); void stop(); - void openPatch(String basename, String dirname); - void closeAllPatches(); + int openPatch(String basename, String dirname); + void closePatch(int id); bool has_message(); Array get_next(); int blocksize();