diff --git a/SConstruct b/SConstruct index ba310745cb14a1ab5b333f7837c5e32bbe1fe8dd..5326d1cb623a2b7bd51f57c30c09116a5d6a78e0 100644 --- a/SConstruct +++ b/SConstruct @@ -112,7 +112,7 @@ env.Append(CPPDEFINES=[ 'LO_SO_VERSION={11,1,4}', 'PRINTF_LL=""']) if env["platform"] == "linux": - env.Append(CPPDEFINES=['__UNIX_JACK__', 'HAVE_LIBDL']) + env.Append(CPPDEFINES=['__UNIX_JACK__', 'HAVE_LIBDL', 'HAVE_POLL=1']) 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', @@ -129,7 +129,8 @@ elif env["platform"] == "android": '-fomit-frame-pointer']) env.Append(CXXFLAGS=['-std=c++17']) elif env["platform"] == "windows": - env.Append(CPPDEFINES=['NOMINMAX', '__WINDOWS_DS__', 'PD_INTERNAL']) + env.Append(CPPDEFINES=['NOMINMAX', '__WINDOWS_DS__', + 'PD_INTERNAL', 'HAVE_SELECT=1']) elif env["platform"] == "macos": env.Append(CPPDEFINES=['NOMINMAX', '__MACOSX_CORE__', 'PD_INTERNAL']) @@ -146,4 +147,6 @@ else: source=sources, ) +# Copy pd patches + Default(library) diff --git a/demo/Main.tscn b/demo/Main.tscn index 83f3d8ac51beb03629177421266daaba5164646c..a9b4740d96e5fbcaf8b9f000030b0cb00fa66a7c 100644 --- a/demo/Main.tscn +++ b/demo/Main.tscn @@ -3,102 +3,59 @@ [sub_resource type="GDScript" id="1"] script/source = "extends Control -@onready var _gdpd = GdPd.new() +@onready var _gdpd = $GdPd func _ready(): - add_child(_gdpd) + pass func _process(delta): # Get messages from the patch - while _gdpd.has_message() : - var msg = _gdpd.get_next() - print(\"got message from pd \", msg) - -func _load_patch(pd_patch : String) : - - - var fullpath = \"\" - if OS.has_feature(\"editor\"): - fullpath = ProjectSettings.globalize_path(pd_patch) - else: - var file = pd_patch.split(\"/\")[-1] - var path = pd_patch.trim_suffix(file) - # Copy files from the patches folder from res to user - if OS.get_name() == \"Android\" : - fullpath = \"/sdcard/Android/data/com.example.gdpd/files/\" - else : - fullpath = OS.get_user_data_dir() - var dir = DirAccess.open(\"res://\") - fullpath = fullpath.path_join(file) - # FIXME do that in C++, and for all .pd and .wav files of the project, on start - dir.copy(\"res://\"+path+\"/\"+file, fullpath) - - - print(\"fullpath = \", fullpath) - - # separate file name from directory - var patch_name = fullpath.split(\"/\")[-1] - var patch_dir = fullpath.trim_suffix(patch_name) - - # load patch - _gdpd.openfile(patch_name, patch_dir) - -func _on_Start_pressed() : - # retrieve the list of available input and outputs - var inps = _gdpd.get_available_input_devices() - var outs = _gdpd.get_available_output_devices() - - # initialise the first ones - _gdpd.init_devices(inps[0], outs[0]) - - # the patch path should be absolute - _load_patch(\"patches/patch1.pd\") - _load_patch(\"patches/patch2.pd\") - - # send message to [receive from_godot] with one symbol - _gdpd.start_message(1) - _gdpd.add_symbol(\"hello\") - _gdpd.finish_list(\"from_godot\") - - # listen to messages sent with [send to_godot] - _gdpd.subscribe(\"to_godot\") - - -func _on_start_non_rt_pressed(): - # initialise without realtime - _gdpd.init_nort() - - # the patch path should be absolute - _load_patch(\"patches/patch1.pd\") - _load_patch(\"patches/patch2.pd\") - - # send message to [receive from_godot] with one symbol - _gdpd.start_message(1) - _gdpd.add_symbol(\"hello\") - _gdpd.finish_list(\"from_godot\") - - # listen to messages sent with [send to_godot] - _gdpd.subscribe(\"to_godot\") - + #while $GdPd.has_message() : + # var msg = _gdpd.get_next() + # print(\"got message from pd \", msg) + pass + func _on_Stop_pressed(): - _gdpd.closefile(\"patches/patch1.pd\") - _gdpd.closefile(\"patches/patch2.pd\") + _gdpd.close_patch(\"patches/patch1.pd\") + #_gdpd.close_patch(\"patches/patch2.pd\") _gdpd.stop() func _on_HSlider_value_changed(value): + _gdpd.send(\"patch1\", [\"pitch\", value]) # send message to [receive from_godot] with three elements - _gdpd.start_message(3) - _gdpd.add_symbol(\"patch1\") - _gdpd.add_symbol(\"pitch\") - _gdpd.add_float(value) - _gdpd.finish_list(\"from_godot\") + #_gdpd.start_message(3) + #_gdpd.add_symbol(\"patch1\") + #_gdpd.add_symbol(\"pitch\") + #_gdpd.add_float(value) + #_gdpd.finish_list(\"from_godot\") + pass func _on_HSlider2_value_changed(value): - _gdpd.start_message(3) - _gdpd.add_symbol(\"patch2\") - _gdpd.add_symbol(\"pitch\") - _gdpd.add_float(value) - _gdpd.finish_list(\"from_godot\") + #_gdpd.start_message(3) + #_gdpd.add_symbol(\"patch2\") + #_gdpd.add_symbol(\"pitch\") + #_gdpd.add_float(value) + #_gdpd.finish_list(\"from_godot\") + pass + +func _on_gd_pd_got_message(address: String, arguments: Array) -> void: + print(\"got message \", address, arguments) + +func _on_start_osc_pressed() -> void: + _gdpd.set_mode(0) + _gdpd.start() + +func _on_start_audio_no_rt_pressed() -> void: + _gdpd.set_mode(1) + _gdpd.open_patch(\"patches/patch1.pd\") + #_load_patch(\"patches/patch2.pd\") + _gdpd.start() + +func _on_start_audio_rt_pressed() -> void: + _gdpd.set_mode(2) + _gdpd.open_patch(\"patches/patch1.pd\") + #_load_patch(\"patches/patch2.pd\") + _gdpd.start() " [node name="Control" type="Control"] @@ -110,29 +67,37 @@ grow_horizontal = 2 grow_vertical = 2 script = SubResource("1") -[node name="Start" type="Button" parent="."] +[node name="StartOSC" type="Button" parent="."] layout_mode = 0 offset_left = 72.0 offset_top = 80.0 offset_right = 176.0 offset_bottom = 128.0 -text = "Start" +text = "Start OSC" -[node name="Stop" type="Button" parent="."] +[node name="StartAudioNoRT" type="Button" parent="."] +layout_mode = 0 +offset_left = 184.0 +offset_top = 80.0 +offset_right = 288.0 +offset_bottom = 128.0 +text = "Start Audio" + +[node name="StartAudioRT" type="Button" parent="."] layout_mode = 0 offset_left = 296.0 offset_top = 80.0 -offset_right = 399.0 +offset_right = 402.0 offset_bottom = 128.0 -text = "Stop" +text = "Start Audio RT" -[node name="StartNonRT" type="Button" parent="."] +[node name="Stop" type="Button" parent="."] layout_mode = 0 -offset_left = 184.0 +offset_left = 424.0 offset_top = 80.0 -offset_right = 290.0 +offset_right = 527.0 offset_bottom = 128.0 -text = "Start Non RT" +text = "Stop" [node name="HSlider" type="HSlider" parent="."] layout_mode = 0 @@ -166,8 +131,12 @@ offset_right = 204.0 offset_bottom = 260.0 text = "Send pitch to patch2" -[connection signal="pressed" from="Start" to="." method="_on_Start_pressed"] +[node name="GdPd" type="GdPd" parent="."] + +[connection signal="pressed" from="StartOSC" to="." method="_on_start_osc_pressed"] +[connection signal="pressed" from="StartAudioNoRT" to="." method="_on_start_audio_no_rt_pressed"] +[connection signal="pressed" from="StartAudioRT" to="." method="_on_start_audio_rt_pressed"] [connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"] -[connection signal="pressed" from="StartNonRT" to="." method="_on_start_non_rt_pressed"] [connection signal="value_changed" from="HSlider" to="." method="_on_HSlider_value_changed"] [connection signal="value_changed" from="HSlider2" to="." method="_on_HSlider2_value_changed"] +[connection signal="got_message" from="GdPd" to="." method="_on_gd_pd_got_message"] diff --git a/demo/patches/patch1.pd b/demo/patches/patch1.pd index bee8fcfdb3037ab223c4eb996dfd8858c0f2d870..f1d010c8f321d83c238049dde8fe6d065bccbc77 100644 Binary files a/demo/patches/patch1.pd and b/demo/patches/patch1.pd differ diff --git a/patches/gdpd.pd b/patches/gdpd.pd index 952c2b7a6e0b70d2284d1c748246add79a565407..8d7aefbadbc8185576f6f091f5a2c131fae9377b 100644 Binary files a/patches/gdpd.pd and b/patches/gdpd.pd differ diff --git a/src/gdpd.cpp b/src/gdpd.cpp index fd6f6fabee20b6fbda511abb5864fe080f84df2b..4a470d8c9a6c7bf8e012f3b1c99dfac06a051e66 100644 --- a/src/gdpd.cpp +++ b/src/gdpd.cpp @@ -37,16 +37,34 @@ const int PCM_BUFFER_SIZE = 4096 * 4; void GdPd::_bind_methods() { ADD_GROUP("GdPd", "gdpd_"); + /* + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_RANGE, "0,2"), + "set_mode", "get_mode"); +*/ + /* + ClassDB::add_property(get_class_static(), PropertyInfo(Variant::INT, "mode", + PROPERTY_HINT_ENUM, "OSC, AUDIO, AUDIO_RT", + PROPERTY_USAGE_DEFAULT), "set_mode", "get_mode"); + */ + 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_parameters"), &GdPd::init_parameters); - ClassDB::bind_method(D_METHOD("init_nort"), &GdPd::init_nort); + ClassDB::bind_method(D_METHOD("set_rt_devices"), &GdPd::set_rt_devices); + ClassDB::bind_method(D_METHOD("set_rt_parameters"), &GdPd::set_rt_parameters); + ClassDB::bind_method(D_METHOD("set_rt_defaults"), &GdPd::set_rt_defaults); + ClassDB::bind_method(D_METHOD("start"), &GdPd::start); 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("open_patch"), &GdPd::open_patch); + ClassDB::bind_method(D_METHOD("close_patch"), &GdPd::close_patch); + + ClassDB::bind_method(D_METHOD("set_mode", "p_mode"), &GdPd::set_mode); + ClassDB::bind_method(D_METHOD("get_mode"), &GdPd::get_mode); + + ClassDB::bind_method(D_METHOD("send"), &GdPd::send); + + /* 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); @@ -55,11 +73,22 @@ void GdPd::_bind_methods() { 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); + */ + + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", + PROPERTY_HINT_ENUM, "OSC, AUDIO, AUDIO_RT", + PROPERTY_USAGE_DEFAULT), + "set_mode", "get_mode"); + ADD_SIGNAL(MethodInfo("got_message", + PropertyInfo(Variant::STRING, "address"), + PropertyInfo(Variant::ARRAY, "arguments"))); } -GdPd::GdPd() : m_vol(1) { - //create message array +GdPd::GdPd() { + mode = 0; + m_receiver = NULL; + //m_sender = NULL; m_messages = new Array(); m_init=false; } @@ -67,6 +96,14 @@ GdPd::GdPd() : m_vol(1) { GdPd::~GdPd() {} +void GdPd::set_mode(const int p_mode) { + std::cout<<"mode "<<p_mode<<std::endl; + mode = p_mode; +} + +int GdPd::get_mode() const { + return mode; +} int GdPd::audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, @@ -79,26 +116,29 @@ int GdPd::audioCallback(void *outputBuffer, void *inputBuffer, Array GdPd::get_available_input_devices() { Array gdlist; + /* for(int d=0; d<m_audio.getDeviceCount(); d++) { if(m_audio.getDeviceInfo(d).inputChannels>0) { gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str()); } - } + }*/ return gdlist; } Array GdPd::get_available_output_devices() { Array gdlist; + /* for(int d=0; d<m_audio.getDeviceCount(); d++) { if(m_audio.getDeviceInfo(d).outputChannels>0) { gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str()); } - } + }*/ return gdlist; } -void GdPd::init_devices(String inputDevice, String outputDevice) { +void GdPd::set_rt_devices(String inputDevice, String outputDevice) { + /* std::string inpStr(inputDevice.utf8().get_data()); std::string outStr(outputDevice.utf8().get_data()); @@ -118,11 +158,12 @@ void GdPd::init_devices(String inputDevice, String outputDevice) { m_nbOutputs = outInfo.outputChannels; m_sampleRate = outInfo.preferredSampleRate; m_bufferFrames = 128; - - m_realtime=true; + */ } -void GdPd::init_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) { +void GdPd::set_rt_parameters(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); @@ -131,11 +172,15 @@ void GdPd::init_parameters(int nbInputs, int nbOutputs, int sampleRate, int buff m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels); m_sampleRate = sampleRate; m_bufferFrames = std::max<int>(64, bufferSize); + */ +} + +void GdPd::set_rt_defaults() { - m_realtime=true; } -int GdPd::init_nort() { +/* +int GdPd::start() { m_nbInputs=0; m_nbOutputs=2; m_sampleRate=44100; @@ -152,45 +197,44 @@ int GdPd::init_nort() { m_pd.setReceiver(this); m_init=true; - // Create stream player - AudioStreamPlayer* p = memnew(AudioStreamPlayer()); - add_child(p); - - Ref<GdPdStream> s = memnew(GdPdStream()); - s->setGdPd(this); - - p->set_stream(s); - p->play(); print("Initialized"); return 0; -} +}*/ int GdPd::start() { + print("Starting with mode "+std::to_string(mode)); - if(m_mode==OSC) { - - //Create OSC sender - m_sender = NULL; + if(mode==OSC) {//OSC MODE + //Create OSC sender and receiver (multicast if no address has been set) + /* m_sender = lo_server_new_multicast( - MULTICAST_ADDRESS.c_str(), SENDER_PORT, NULL); - m_receiver = NULL; + MULTICAST_ADDRESS.c_str(), + std::to_string(SENDER_PORT).c_str(), + errorHandler); + */ + m_destination = lo_address_new(MULTICAST_ADDRESS.c_str(), + std::to_string(SENDER_PORT).c_str()); m_receiver = lo_server_new_multicast( - MULTICAST_ADDRESS.c_str(), RECEIVER_PORT, NULL); + MULTICAST_ADDRESS.c_str(), + std::to_string(RECEIVER_PORT).c_str(), + errorHandler); /* - m_sender = lo_server_new_with_proto( - to_string(UDP_SERVER_PORT).c_str(), + m_receiver = lo_server_new_with_proto( + std::to_string(RECEIVER_PORT).c_str(), LO_UDP, NULL); - */ + */ if(m_receiver!=NULL) { lo_server_add_method(m_receiver, NULL, NULL, oscHandler, this); + m_init = true; } else { - cout<<"GdPd : Could not create UDP connection"<<endl; + print("Could not create UDP connection"); } } - else { + /* + else { //AUDIO MODE RtAudio::StreamParameters outParams, inpParams; inpParams.deviceId = m_inputDevice; inpParams.nChannels = m_nbInputs; @@ -209,7 +253,7 @@ int GdPd::start() { //start dsp m_pd.computeAudio(true); - if(m_mode==AUDIO_RT) { + if(mode==AUDIO_RT) { //intialize rtaudio if(m_audio.getDeviceCount()==0){ UtilityFunctions::print("There are no available sound devices."); @@ -234,44 +278,91 @@ int GdPd::start() { } } else { + // Create stream player + AudioStreamPlayer* p = memnew(AudioStreamPlayer()); + add_child(p); + + Ref<GdPdStream> s = memnew(GdPdStream()); + s->setGdPd(this); + + p->set_stream(s); + p->play(); } //create message hook - m_pd.subscribe("to_gdpd"); + m_pd.subscribe("to_godot"); m_pd.setReceiver(this); m_init=true; } print("Initialized"); + */ return 0; } void GdPd::stop() { m_init=false; - if(m_realtime) { - m_audio.stopStream(); - m_audio.closeStream(); + if(mode==OSC) { + lo_server_del_method(m_receiver, NULL, NULL); + lo_server_free(m_receiver); + lo_address_free(m_destination); } + /* else { + if(mode==AUDIO_RT) { + m_audio.stopStream(); + m_audio.closeStream(); + } + else { + } + m_pd.computeAudio(false); } - m_pd.computeAudio(false); + */ print("Stopped"); } -void GdPd::process(float delta) { +void GdPd::send(String address, Array arguments) { + if(mode==OSC) { + lo_message msg = lo_message_new(); + lo_message_add_int32(msg, 10); + std::string addrStr(address.utf8().get_data()); + addrStr = std::string("/gdpd/patch/")+addrStr; + lo_send_message(m_destination, addrStr.c_str(), msg); + } +} + +void GdPd::_process(double delta) { + if(!m_init) { + return; + } + + if(mode==OSC) { + if(m_receiver!=NULL) { + int res = lo_server_recv_noblock(m_receiver, 1); + //print("received "+std::to_string(res)); + } + } /* - if(m_udpServer!=NULL) { - lo_server_recv_noblock(m_udpServer, 10); - }*/ + else { + m_pd.receiveMessages(); + + //FIXME for each message, call signal with address and arguments + emit_signal("got_message", "blup"); + } + */ } void GdPd::handleOSC(const char* path, const char* types, - lo_arg** argv, int argc, lo_message msg) { + lo_arg** argv, int argc, lo_message msg) { + print(path); + //FIXME call signal with address and arguments + emit_signal("got_message", "blup"); } void GdPd::processAudio(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames) { + /* int ticks = nBufferFrames / libpd_blocksize(); m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer); @@ -280,9 +371,32 @@ void GdPd::processAudio(void *outputBuffer, void *inputBuffer, for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) { ((float*)outputBuffer)[b]*=m_vol; } + */ } -bool GdPd::openfile(godot::String baseStr, godot::String dirStr) { +bool GdPd::open_patch(godot::String patch) { + std::string patchStr(patch.utf8().get_data()); + + /* + var fullpath = "" + if OS.has_feature("editor"): + fullpath = ProjectSettings.globalize_path(pd_patch) + else: + var file = pd_patch.split("/")[-1] + var path = pd_patch.trim_suffix(file) + # Copy files from the patches folder from res to user + if OS.get_name() == "Android" : + fullpath = "/sdcard/Android/data/com.example.gdpd/files/" + else : + fullpath = OS.get_user_data_dir() + var dir = DirAccess.open("res://") + fullpath = fullpath.path_join(file) + # FIXME do that in C++, and for all .pd and .wav files of the project, on start + dir.copy("res://"+path+"/"+file, fullpath) + var patch_name = fullpath.split("/")[-1] + var patch_dir = fullpath.trim_suffix(patch_name) +*/ + /* std::string baseS(baseStr.utf8().get_data()); std::string dirS(dirStr.utf8().get_data()); @@ -299,24 +413,27 @@ bool GdPd::openfile(godot::String baseStr, godot::String dirStr) { else { print("Opened patch "+baseS); m_patchsMap[baseS] = p1; - } + }*/ return true; } -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); - } +void GdPd::close_patch(godot::String patch) { + std::string patchStr(patch.utf8().get_data()); + /* + if(m_patchsMap.find(patchStr)!=m_patchsMap.end()) { + m_pd.closePatch(m_patchsMap[patchStr]); + m_patchsMap.erase(patchStr); + print("Closed patch "+patchStr); + }*/ } +/* void GdPd::subscribe(String symbStr) { std::string symbS(symbStr.utf8().get_data()); m_pd.subscribe(symbS.c_str()); -} +}*/ +/* bool GdPd::has_message() { if(m_init) { //receive new messages @@ -357,9 +474,10 @@ int GdPd::finish_list(String destStr) { int res = libpd_finish_list(destS.c_str()); return res; } +*/ void GdPd::print(const std::string& message) { - UtilityFunctions::print((std::string("GDPD : ")+message).c_str()); + UtilityFunctions::print((std::string("GdPd : ")+message).c_str()); } void GdPd::receiveList(const std::string& dest, const pd::List& list) { @@ -378,10 +496,6 @@ void GdPd::receiveList(const std::string& dest, const pd::List& list) { m_messages->push_back(gdlist); } -void GdPd::set_volume(float vol) { - m_vol=vol; -} - /* GdPdStream */ GdPdStream::GdPdStream() { @@ -423,3 +537,5 @@ int32_t GdPdStreamPlayback::_mix_resampled(AudioFrame *buffer, float GdPdStreamPlayback::_get_stream_sampling_rate() const { return AudioServer::get_singleton()->get_mix_rate(); } + + diff --git a/src/gdpd.h b/src/gdpd.h index b092b32a6ed8a420eb5e86d0b4ec1b6c57241a0e..f41ff85ca9beb68e7ebf4d30b8c239b2689e64d6 100644 --- a/src/gdpd.h +++ b/src/gdpd.h @@ -58,14 +58,15 @@ protected: lo_arg ** argv, int argc, lo_message msg, void *user_data) { GdPd* gdpd = (GdPd*)user_data; + std::cout<<"got osc message"<<std::endl; gdpd->handleOSC(path, types, argv, argc, msg); return 0; } static void errorHandler(int num, const char *msg, const char *path){ std::cout<<"GdPd Error : "<<msg<<" "<<path<<std::endl; } - virtual void handleOSC(const char* path, const char* types, - lo_arg** argv, int argc, lo_message msg){}; + void handleOSC(const char* path, const char* types, + lo_arg** argv, int argc, lo_message msg); private: bool m_realtime; @@ -87,33 +88,42 @@ private: bool m_init; enum Mode {OSC, AUDIO, AUDIO_RT}; - int m_mode; + int mode; const int SENDER_PORT = 9211; const int RECEIVER_PORT = 9212; const std::string MULTICAST_ADDRESS = "239.210.211.212"; - lo_server m_sender; + //lo_server m_sender; lo_server m_receiver; + lo_address m_destination; int m_senderPort; int m_receiverPort; -private: - int start(); - public: GdPd(); virtual ~GdPd(); - //libpd functions + void set_mode(const int p_mode); + int get_mode() const; + Array get_available_input_devices(); Array get_available_output_devices(); - int init_nort(); - int init_devices(String inputDevice, String outputDevice); - int init_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); + void set_rt_devices(String inputDevice, String outputDevice); + void set_rt_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); + void set_rt_defaults(); + + int start(); void stop(); - bool openfile(String basename, String dirname); - void closefile(String basename); + + void _process(double delta) override; + + bool open_patch(String basename); + void close_patch(String basename); + + void send(String destination, Array arguments); + + /* bool has_message(); Array get_next(); int blocksize(); @@ -122,15 +132,12 @@ public: 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;} + //libpd hooks + void receiveList(const std::string& dest, const pd::List& list); //rtaudio static int audioCallback(void *outputBuffer, void *inputBuffer,