diff --git a/SConstruct b/SConstruct index 5326d1cb623a2b7bd51f57c30c09116a5d6a78e0..b3cc802e1e487eb5da5d0196075580ae062fa7e7 100644 --- a/SConstruct +++ b/SConstruct @@ -1,6 +1,7 @@ #!/usr/bin/env python import os import sys +import shutil # Update submodules @@ -122,7 +123,7 @@ if env["platform"] == "linux": env.Append(CXXFLAGS=['-std=c++17']) elif env["platform"] == "android": env.Append(CPPDEFINES=['__UNSPECIFIED__', 'HAVE_LIBDL', 'ANDROID', - 'HAS_SOCKLEN_T']) + 'HAS_SOCKLEN_T', 'HAVE_POLL=1']) env.Append(CFLAGS=['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast', '-Wno-discarded-qualifiers', '-fPIC', '-O3', '-ffast-math', '-funroll-loops', @@ -148,5 +149,6 @@ else: ) # Copy pd patches +shutil.copytree("patches", "demo/addons/gdpd/patches", dirs_exist_ok=True) Default(library) diff --git a/demo/Main.tscn b/demo/Main.tscn index a9b4740d96e5fbcaf8b9f000030b0cb00fa66a7c..edf9279133338c411db2b7801c99d7f35a8bc617 100644 --- a/demo/Main.tscn +++ b/demo/Main.tscn @@ -9,37 +9,20 @@ func _ready(): pass func _process(delta): - # Get messages from the patch - #while $GdPd.has_message() : - # var msg = _gdpd.get_next() - # print(\"got message from pd \", msg) pass func _on_Stop_pressed(): - _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\") 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\") pass func _on_gd_pd_got_message(address: String, arguments: Array) -> void: - print(\"got message \", address, arguments) + print(\"got message \", address, \" \", arguments) func _on_start_osc_pressed() -> void: _gdpd.set_mode(0) @@ -47,14 +30,10 @@ func _on_start_osc_pressed() -> void: 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() " @@ -132,6 +111,7 @@ offset_bottom = 260.0 text = "Send pitch to patch2" [node name="GdPd" type="GdPd" parent="."] +pd_patch = "res://patches/patch1.pd" [connection signal="pressed" from="StartOSC" to="." method="_on_start_osc_pressed"] [connection signal="pressed" from="StartAudioNoRT" to="." method="_on_start_audio_no_rt_pressed"] diff --git a/demo/addons/gdpd/patches/gdpd.pd b/demo/addons/gdpd/patches/gdpd.pd new file mode 100644 index 0000000000000000000000000000000000000000..a0843bc7bb6e8f312ae3e9bb1a4e3cf9d447f2d2 Binary files /dev/null and b/demo/addons/gdpd/patches/gdpd.pd differ diff --git a/demo/addons/gdpd/patches/gdpd_receive.pd b/demo/addons/gdpd/patches/gdpd_receive.pd new file mode 100644 index 0000000000000000000000000000000000000000..d5fa2d14c1273045d6dd60cd2a1e9e5a1a37b48f Binary files /dev/null and b/demo/addons/gdpd/patches/gdpd_receive.pd differ diff --git a/demo/addons/gdpd/patches/gdpd_send.pd b/demo/addons/gdpd/patches/gdpd_send.pd new file mode 100644 index 0000000000000000000000000000000000000000..61e18c7c8ea264bcef5e1d3525271bb6a4d40f0f Binary files /dev/null and b/demo/addons/gdpd/patches/gdpd_send.pd differ diff --git a/demo/patches/patch1.pd b/demo/patches/patch1.pd index f1d010c8f321d83c238049dde8fe6d065bccbc77..7df27b00fd91b2d0dd544afe94a08aa442cc4ef7 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 8d7aefbadbc8185576f6f091f5a2c131fae9377b..a0843bc7bb6e8f312ae3e9bb1a4e3cf9d447f2d2 100644 Binary files a/patches/gdpd.pd and b/patches/gdpd.pd differ diff --git a/src/gdpd.cpp b/src/gdpd.cpp index 4a470d8c9a6c7bf8e012f3b1c99dfac06a051e66..2d09a81045be73f85be1d1e6d4a5d47d585ecaee 100644 --- a/src/gdpd.cpp +++ b/src/gdpd.cpp @@ -25,6 +25,8 @@ #include <godot_cpp/core/class_db.hpp> #include <godot_cpp/classes/os.hpp> +#include <godot_cpp/classes/project_settings.hpp> +#include <godot_cpp/classes/dir_access.hpp> #include <godot_cpp/classes/global_constants.hpp> #include <godot_cpp/classes/label.hpp> #include <godot_cpp/variant/utility_functions.hpp> @@ -37,16 +39,6 @@ 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"), @@ -56,29 +48,33 @@ void GdPd::_bind_methods() { 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("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("set_osc_address", "p_osc_address"), + &GdPd::set_osc_address); + ClassDB::bind_method(D_METHOD("get_osc_address"), + &GdPd::get_osc_address); + + ClassDB::bind_method(D_METHOD("set_pd_patch", "p_pd_patch"), + &GdPd::set_pd_patch); + ClassDB::bind_method(D_METHOD("get_pd_patch"), + &GdPd::get_pd_patch); + + 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); - 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); - */ ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "OSC, AUDIO, AUDIO_RT", PROPERTY_USAGE_DEFAULT), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "osc_address"), + "set_osc_address", "get_osc_address"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "pd_patch", PROPERTY_HINT_FILE), + "set_pd_patch", "get_pd_patch"); ADD_SIGNAL(MethodInfo("got_message", PropertyInfo(Variant::STRING, "address"), @@ -88,23 +84,15 @@ void GdPd::_bind_methods() { GdPd::GdPd() { mode = 0; m_receiver = NULL; - //m_sender = NULL; - m_messages = new Array(); m_init=false; + m_rtDefaults=true; + m_player=NULL; + osc_address = String(MULTICAST_ADDRESS.c_str()); } 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, RtAudioStreamStatus status, void *userData){ @@ -179,30 +167,6 @@ void GdPd::set_rt_defaults() { } -/* -int GdPd::start() { - m_nbInputs=0; - m_nbOutputs=2; - m_sampleRate=44100; - m_realtime=false; - - - if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) { - print("GDPD : Error starting libpd"); - return 1; - } - - // Create message hook - m_pd.subscribe("to_gdpd"); - m_pd.setReceiver(this); - m_init=true; - - - print("Initialized"); - - return 0; -}*/ - int GdPd::start() { print("Starting with mode "+std::to_string(mode)); @@ -214,8 +178,10 @@ int GdPd::start() { std::to_string(SENDER_PORT).c_str(), errorHandler); */ + //FIXME handle given ip address m_destination = lo_address_new(MULTICAST_ADDRESS.c_str(), std::to_string(SENDER_PORT).c_str()); + //FIXME add local port in addition to multicast m_receiver = lo_server_new_multicast( MULTICAST_ADDRESS.c_str(), std::to_string(RECEIVER_PORT).c_str(), @@ -233,35 +199,54 @@ int GdPd::start() { print("Could not create UDP connection"); } } - /* else { //AUDIO MODE - RtAudio::StreamParameters outParams, inpParams; - inpParams.deviceId = m_inputDevice; - inpParams.nChannels = m_nbInputs; - outParams.deviceId = m_outputDevice; - outParams.nChannels = m_nbOutputs; - print("Output channels = "+std::to_string(outParams.nChannels)); - print("Input channels = "+std::to_string(inpParams.nChannels)); + + // Retrieve defaults audio values if needed + if(m_rtDefaults) { + m_inputDevice = m_audio.getDefaultInputDevice(); + m_outputDevice = m_audio.getDefaultOutputDevice(); + RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice); + RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice); + m_nbInputs = inpInfo.inputChannels; + m_nbOutputs = outInfo.outputChannels; + m_sampleRate = inpInfo.preferredSampleRate; + m_bufferFrames = 128; + } + if(mode==AUDIO) { + m_nbInputs=0; //FIXME Godot crashes when there are inputs + m_nbOutputs=2; + m_sampleRate=44100; + } + + //libpd_set_verbose(1); //FIXME Add verbose control if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) { print("GDPD : Error starting libpd"); return 1; } - //libpd_set_verbose(1); //start dsp m_pd.computeAudio(true); if(mode==AUDIO_RT) { + print("Starting Audio RT"); //intialize rtaudio if(m_audio.getDeviceCount()==0){ UtilityFunctions::print("There are no available sound devices."); return 1; } + RtAudio::StreamParameters outParams, inpParams; + inpParams.deviceId = m_inputDevice; + inpParams.nChannels = m_nbInputs; + outParams.deviceId = m_outputDevice; + outParams.nChannels = m_nbOutputs; + print("Output channels = "+std::to_string(outParams.nChannels)); + print("Input channels = "+std::to_string(inpParams.nChannels)); + RtAudio::StreamOptions options; - options.streamName = "gdpd"; + options.streamName = "GdPd"; options.flags = RTAUDIO_SCHEDULE_REALTIME; if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) { options.flags |= RTAUDIO_MINIMIZE_LATENCY; @@ -278,26 +263,34 @@ 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(); + print("Starting Audio non-RT"); + // Create stream player if not already there + if(!m_player) { + m_player = memnew(AudioStreamPlayer()); + add_child(m_player); + Ref<GdPdStream> s = memnew(GdPdStream()); + s->setGdPd(this); + m_player->set_stream(s); + } + m_player->play(); } //create message hook m_pd.subscribe("to_godot"); m_pd.setReceiver(this); + + // Open pd patch + if(!pd_patch.is_empty()) { + open_patch(); + } + else { + print("Please select a pd patch"); + return 1; + } + m_init=true; } - print("Initialized"); - */ - return 0; } @@ -308,28 +301,71 @@ void GdPd::stop() { lo_server_free(m_receiver); lo_address_free(m_destination); } - /* else { if(mode==AUDIO_RT) { m_audio.stopStream(); m_audio.closeStream(); } else { + if(m_player) { + m_player->stop(); + } + } + if(m_patchOpened) { + m_pd.closePatch(pd_patch.utf8().get_data()); } m_pd.computeAudio(false); } - */ print("Stopped"); } void GdPd::send(String address, Array arguments) { + if(!m_init) { + return; + } + if(mode==OSC) { lo_message msg = lo_message_new(); - lo_message_add_int32(msg, 10); + for(int i=0; i<arguments.size(); ++i) { + switch(arguments[i].get_type()) { + case Variant::INT : + lo_message_add_int32(msg, arguments[i]); + break; + case Variant::FLOAT : + lo_message_add_float(msg, arguments[i]); + break; + case Variant::STRING : + lo_message_add_string(msg, + String(arguments[i]).utf8().get_data()); + break; + } + } + std::string addrStr(address.utf8().get_data()); addrStr = std::string("/gdpd/patch/")+addrStr; lo_send_message(m_destination, addrStr.c_str(), msg); } + else { + libpd_start_message(arguments.size()+2); + libpd_add_symbol("gdpd"); + libpd_add_symbol("patch"); + libpd_add_symbol(String(address).utf8().get_data()); + for(int i=0; i<arguments.size(); ++i) { + switch(arguments[i].get_type()) { + case Variant::INT : + libpd_add_float(arguments[i]); + break; + case Variant::FLOAT : + libpd_add_float(arguments[i]); + break; + case Variant::STRING : + std::string symbS(String(arguments[i]).utf8().get_data()); + libpd_add_symbol(symbS.c_str()); + break; + } + } + libpd_finish_list("from_godot"); + } } void GdPd::_process(double delta) { @@ -339,161 +375,161 @@ void GdPd::_process(double delta) { if(mode==OSC) { if(m_receiver!=NULL) { - int res = lo_server_recv_noblock(m_receiver, 1); - //print("received "+std::to_string(res)); + lo_server_recv_noblock(m_receiver, 1); } } - /* 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) { - print(path); - //FIXME call signal with address and arguments - emit_signal("got_message", "blup"); + Array gdList; + for(int i = 0; i < argc; ++i) { + switch(types[i]) { + case 'f' : + gdList.push_back(argv[i]->f); + break; + case 'i' : + gdList.push_back(argv[i]->i); + break; + case 's' : + gdList.push_back(String(&(argv[i]->s))); + break; + } + } + emit_signal("got_message", String(path), gdList); } void GdPd::processAudio(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames) { - /* int ticks = nBufferFrames / libpd_blocksize(); m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer); - - //volume control on the output - for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) { - ((float*)outputBuffer)[b]*=m_vol; - } - */ } -bool GdPd::open_patch(godot::String patch) { - std::string patchStr(patch.utf8().get_data()); +bool GdPd::open_patch() { + std::string pdPatchStr; + std::string pdDirStr; /* - 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()); + if(OS::get_singleton()->has_feature("editor")) { + print("Loading patch from editor"); + String fullpath = ProjectSettings::get_singleton() + ->globalize_path(pd_patch); - if(m_patchsMap.find(baseS)!=m_patchsMap.end()) { - print("Patch "+baseS+" already opened"); - return true; - } + + + String pat = fullpath.get_slice("/",fullpath.get_slice_count("/")-1); + String dir = fullpath.trim_suffix(pat); - pd::Patch p1 = m_pd.openPatch(baseS.c_str(), dirS.c_str()); + pdPatchStr = std::string(pat.utf8().get_data()); + pdDirStr = std::string(dir.utf8().get_data()); + } + else {*/ + print("Loading patch from package"); + + String userPath; + + if(OS::get_singleton()->get_name() == "Android") { + print("On Android, so start copying files to user folder"); + String packageName = "com.example.gdpd"; + + //FIXME get Android package name + userPath = String("/sdcard/Android/data/") + + packageName + + String("/files/"); + } + else { + userPath = OS::get_singleton()->get_user_data_dir()+"/"; + } + + + //Get the folder containing the main pd patch + String patch = pd_patch.get_slice("/",pd_patch.get_slice_count("/")-1); + String patchDir = pd_patch.trim_suffix(patch).trim_prefix("res://"); + + //Recursively copy this folder from res to user directory + recurseCopy("res://"+patchDir, userPath+patchDir); + + //Also copy gdpd patches + std::vector<String> gdpdFiles{"gdpd.pd", "gdpd_send.pd", + "gdpd_receive.pd"}; + for(auto& f : gdpdFiles) { + DirAccess::copy_absolute("res://addons/gdpd/patches/"+f, + userPath+patchDir+"/"+f); + } + + //Define new paths + pdPatchStr = std::string(patch.utf8().get_data()); + pdDirStr = std::string((userPath+patchDir).utf8().get_data()); + //} + + + // Open the patch + m_patchOpened=false; + pd::Patch p1 = m_pd.openPatch(pdPatchStr.c_str(), pdDirStr.c_str()); if(!p1.isValid()) { - print("Could not open patch "+baseS); + print("Could not open patch "+pdPatchStr); return false; } else { - print("Opened patch "+baseS); - m_patchsMap[baseS] = p1; - }*/ - return true; -} - -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 - m_pd.receiveMessages(); + print("Opened patch "+pdPatchStr); + m_patchOpened=true; } - - //return if more than one message - int size = m_messages->size(); - return size>0; + return true; } -Array GdPd::get_next() { - Array msg = m_messages->pop_front(); - return msg; -} +void GdPd::recurseCopy(String fromPath, String toPath) { -int GdPd::blocksize() { - int blocksize = libpd_blocksize(); - return blocksize; -} + //Create the toPath folder + DirAccess::make_dir_absolute(toPath); -int GdPd::start_message(int nbValues) { - int res = libpd_start_message(nbValues); - return res; -} + //For each file inside the origin directory + PackedStringArray files = DirAccess::get_files_at(fromPath); + for(int i=0; i<files.size(); ++i) { + String fileName = files[i]; + print("File "+std::string(fileName.utf8().get_data())); + DirAccess::copy_absolute(fromPath+"/"+fileName, + toPath+"/"+fileName); + } -void GdPd::add_symbol(String symbStr) { - std::string symbS(symbStr.utf8().get_data()); - libpd_add_symbol(symbS.c_str()); -} + //For each dir, call recursCopy + PackedStringArray dirs = DirAccess::get_directories_at(fromPath); + for(int i=0; i<dirs.size(); ++i) { + String dirName = dirs[i]; + print("Dir "+std::string(dirName.utf8().get_data())); + } -void GdPd::add_float(float val) { - libpd_add_float(val); } -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::close_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::print(const std::string& message) { UtilityFunctions::print((std::string("GdPd : ")+message).c_str()); } void GdPd::receiveList(const std::string& dest, const pd::List& list) { - Array gdlist; - + Array gdList; for(int i = 0; i < list.len(); ++i) { if(list.isFloat(i)) { - gdlist.push_back(list.getFloat(i)); + gdList.push_back(list.getFloat(i)); } else if(list.isSymbol(i)) { String symbStr(list.getSymbol(i).c_str()); - gdlist.push_back(symbStr); + gdList.push_back(symbStr); } } - - m_messages->push_back(gdlist); + emit_signal("got_message", String(dest.c_str()), gdList); } /* GdPdStream */ @@ -503,7 +539,6 @@ GdPdStream::GdPdStream() { Ref<AudioStreamPlayback> GdPdStream::_instantiate_playback() const { Ref<GdPdStreamPlayback> gdPlayback = memnew(GdPdStreamPlayback()); - //gdPlayback.instantiate(); gdPlayback->m_base = Ref<GdPdStream>(this); return gdPlayback; } @@ -512,7 +547,7 @@ Ref<AudioStreamPlayback> GdPdStream::_instantiate_playback() const { /* GdPdStreamplayback */ GdPdStreamPlayback::GdPdStreamPlayback() { - m_buffer.resize(4096*2,0.0); + m_buffer.resize(PCM_BUFFER_SIZE,0.0); AudioServer::get_singleton()->lock(); pcm_buffer = memalloc(PCM_BUFFER_SIZE); zeromem(pcm_buffer, PCM_BUFFER_SIZE); @@ -525,7 +560,7 @@ GdPdStreamPlayback::~GdPdStreamPlayback() { int32_t GdPdStreamPlayback::_mix_resampled(AudioFrame *buffer, int32_t nbFrames) { - m_buffer.resize(4096*2, 0.0); + m_buffer.resize(PCM_BUFFER_SIZE, 0.0); m_base->getGdPd()->processAudio(m_buffer.data(), NULL, nbFrames); for(int i = 0; i < nbFrames; i++) { buffer[i].left = m_buffer[i*2]; diff --git a/src/gdpd.h b/src/gdpd.h index f41ff85ca9beb68e7ebf4d30b8c239b2689e64d6..7f0c7a2d698a0380dd8e04a7d111681e14770af4 100644 --- a/src/gdpd.h +++ b/src/gdpd.h @@ -67,6 +67,7 @@ protected: } void handleOSC(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg); + void recurseCopy(String fromPath, String toPath); private: bool m_realtime; @@ -84,16 +85,23 @@ private: int m_inputDevice; int m_outputDevice; std::map<std::string, pd::Patch> m_patchsMap; + bool m_rtDefaults; + + AudioStreamPlayer* m_player; bool m_init; enum Mode {OSC, AUDIO, AUDIO_RT}; int mode; + String pd_patch; + String pd_folder; + bool m_patchOpened; + const int SENDER_PORT = 9211; const int RECEIVER_PORT = 9212; const std::string MULTICAST_ADDRESS = "239.210.211.212"; - //lo_server m_sender; + String osc_address; lo_server m_receiver; lo_address m_destination; int m_senderPort; @@ -104,8 +112,8 @@ public: GdPd(); virtual ~GdPd(); - void set_mode(const int p_mode); - int get_mode() const; + inline void set_mode(const int p_mode){mode=p_mode;} + inline int get_mode() const {return mode;} Array get_available_input_devices(); Array get_available_output_devices(); @@ -118,8 +126,18 @@ public: void _process(double delta) override; - bool open_patch(String basename); - void close_patch(String basename); + bool open_patch(); + void close_patch(); + + inline void set_pd_folder(const String p_folder){pd_folder=p_folder;} + inline String get_pd_folder() const{return pd_folder;} + inline void set_pd_patch(const String p_patch){pd_patch=p_patch;} + inline String get_pd_patch() const{return pd_patch;} + + inline void set_osc_address(const String p_osc_address) { + osc_address = p_osc_address; + } + inline String get_osc_address() const{return osc_address;} void send(String destination, Array arguments);