Skip to content
Snippets Groups Projects
Commit 55c95213 authored by Florent Berthaut's avatar Florent Berthaut
Browse files

Add new branch with integrated osc

parent 4dba0088
No related branches found
No related tags found
No related merge requests found
......@@ -8,3 +8,5 @@
*.import
demo/build
demo/export_presets.cfg
demo/android
build
......@@ -6,3 +6,6 @@
path = src/godot-cpp
url = https://github.com/GodotNativeTools/godot-cpp
branch = 4.2
[submodule "src/liblo"]
path = src/liblo
url = https://github.com/radarsat1/liblo.git
......@@ -19,6 +19,21 @@ fiddle_file = open("src/libpd/pure-data/extra/fiddle~/fiddle~.c","w")
fiddle_file.writelines(out_lines)
fiddle_file.close()
#Generate liblo headers
import fileinput
#threadinclude = '#include "lo/lo_serverthread.h"'
threadinclude = ''
with open("src/liblo/lo/lo.h.in", "r") as file:
filedata = file.read()
filedata = filedata.replace("@THREADS_INCLUDE@", threadinclude)
with open("src/liblo/lo/lo.h", "w") as file:
file.write(filedata)
with open("src/liblo/lo/lo_endian.h.in", "r") as file:
filedata = file.read()
filedata = filedata.replace("@LO_BIGENDIAN@", "0")
with open("src/liblo/lo/lo_endian.h", "w") as file:
file.write(filedata)
env = SConscript("src/godot-cpp/SConstruct")
......@@ -33,6 +48,7 @@ env = SConscript("src/godot-cpp/SConstruct")
env.Append(CPPPATH=['.', 'src/libpd/libpd_wrapper',
'src/libpd/libpd_wrapper/util',
"src/liblo",
'src/libpd/cpp','src/libpd/pure-data/src', 'src/rtaudio'],
CCFLAGS=["-fexceptions"])
......@@ -85,7 +101,15 @@ sources = Glob('src/*.cpp') + Glob('src/rtaudio/*.cpp') +\
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')
Glob('src/libpd/pure-data/src/s_utf8.c') +\
Glob("src/liblo/src/*.c",\
exclude=["src/liblo/src/*test*",\
"src/liblo/src/*.cpp",\
"src/liblo/src/*thread*"])
env.Append(CPPDEFINES=[ 'LO_SO_VERSION={11,1,4}',
'PACKAGE_VERSION=\\"0.31\\"', 'PACKAGE_NAME=\\"liblo\\"',
'PRINTF_LL=""'])
if env["platform"] == "linux":
env.Append(CPPDEFINES=['__UNIX_JACK__', 'HAVE_LIBDL'])
......
......@@ -7,32 +7,41 @@ script/source = "extends Control
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)
pass
func _load_patch(pd_patch : String) :
var fullpath = \"\"
if OS.has_feature(\"editor\"):
fullpath = ProjectSettings.globalize_path(pd_patch)
else:
fullpath = OS.get_executable_path().get_base_dir().path_join(pd_patch.lstrip(\"res://\"))
#fullpath = pd_patch
#print(DirAccess.get_files_at(\"res://\"))
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)
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, \"./\")
_gdpd.openfile(patch_name, patch_dir)
func _on_Start_pressed() :
# retrieve the list of available input and outputs
......@@ -43,8 +52,8 @@ func _on_Start_pressed() :
_gdpd.init_devices(inps[0], outs[0])
# the patch path should be absolute
_load_patch(\"res://patch1.pd\")
_load_patch(\"res://patch2.pd\")
_load_patch(\"patches/patch1.pd\")
_load_patch(\"patches/patch2.pd\")
# send message to [receive from_godot] with one symbol
_gdpd.start_message(1)
......@@ -60,8 +69,8 @@ func _on_start_non_rt_pressed():
_gdpd.init_nort()
# the patch path should be absolute
_load_patch(\"res://patch1.pd\")
_load_patch(\"res://patch2.pd\")
_load_patch(\"patches/patch1.pd\")
_load_patch(\"patches/patch2.pd\")
# send message to [receive from_godot] with one symbol
_gdpd.start_message(1)
......@@ -72,8 +81,8 @@ func _on_start_non_rt_pressed():
_gdpd.subscribe(\"to_godot\")
func _on_Stop_pressed():
_gdpd.closefile(\"patch1.pd\")
_gdpd.closefile(\"patch2.pd\")
_gdpd.closefile(\"patches/patch1.pd\")
_gdpd.closefile(\"patches/patch2.pd\")
_gdpd.stop()
func _on_HSlider_value_changed(value):
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -98,7 +98,7 @@ Array GdPd::get_available_output_devices() {
}
int GdPd::init_devices(String inputDevice, String outputDevice) {
void GdPd::init_devices(String inputDevice, String outputDevice) {
std::string inpStr(inputDevice.utf8().get_data());
std::string outStr(outputDevice.utf8().get_data());
......@@ -120,11 +120,9 @@ int GdPd::init_devices(String inputDevice, String outputDevice) {
m_bufferFrames = 128;
m_realtime=true;
return start();
}
int GdPd::init_parameters(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
void GdPd::init_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);
......@@ -135,12 +133,9 @@ int GdPd::init_parameters(int nbInputs, int nbOutputs, int sampleRate, int buffe
m_bufferFrames = std::max<int>(64, bufferSize);
m_realtime=true;
return start();
}
int GdPd::init_nort() {
m_nbInputs=0;
m_nbOutputs=2;
m_sampleRate=44100;
......@@ -173,56 +168,79 @@ int GdPd::init_nort() {
}
int GdPd::start() {
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));
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(m_realtime) {
//intialize rtaudio
if(m_audio.getDeviceCount()==0){
UtilityFunctions::print("There are no available sound devices.");
if(m_mode==OSC) {
//Create OSC sender
m_sender = NULL;
m_sender = lo_server_new_multicast(
MULTICAST_ADDRESS.c_str(), SENDER_PORT, NULL);
m_receiver = NULL;
m_receiver = lo_server_new_multicast(
MULTICAST_ADDRESS.c_str(), RECEIVER_PORT, NULL);
/*
m_sender = lo_server_new_with_proto(
to_string(UDP_SERVER_PORT).c_str(),
LO_UDP, NULL);
*/
if(m_receiver!=NULL) {
lo_server_add_method(m_receiver, NULL, NULL, oscHandler, this);
}
else {
cout<<"GdPd : Could not create UDP connection"<<endl;
}
}
else {
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));
if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) {
print("GDPD : Error starting libpd");
return 1;
}
RtAudio::StreamOptions options;
options.streamName = "gdpd";
options.flags = RTAUDIO_SCHEDULE_REALTIME;
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
options.flags |= RTAUDIO_MINIMIZE_LATENCY;
//libpd_set_verbose(1);
//start dsp
m_pd.computeAudio(true);
if(m_mode==AUDIO_RT) {
//intialize rtaudio
if(m_audio.getDeviceCount()==0){
UtilityFunctions::print("There are no available sound devices.");
return 1;
}
RtAudio::StreamOptions options;
options.streamName = "gdpd";
options.flags = RTAUDIO_SCHEDULE_REALTIME;
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
options.flags |= RTAUDIO_MINIMIZE_LATENCY;
}
try {
m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32,
m_sampleRate, &m_bufferFrames, &audioCallback,
this, &options);
m_audio.startStream();
print("Stream started");
}
catch(RtAudioError& e) {
UtilityFunctions::print(e.getMessage().c_str());
}
}
try {
m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32,
m_sampleRate, &m_bufferFrames, &audioCallback,
this, &options);
m_audio.startStream();
print("Stream started");
else {
}
catch(RtAudioError& e) {
UtilityFunctions::print(e.getMessage().c_str());
}
}
else {
}
//create message hook
m_pd.subscribe("to_gdpd");
m_pd.setReceiver(this);
m_init=true;
//create message hook
m_pd.subscribe("to_gdpd");
m_pd.setReceiver(this);
m_init=true;
}
print("Initialized");
......@@ -241,6 +259,17 @@ void GdPd::stop() {
print("Stopped");
}
void GdPd::process(float delta) {
/*
if(m_udpServer!=NULL) {
lo_server_recv_noblock(m_udpServer, 10);
}*/
}
void GdPd::handleOSC(const char* path, const char* types,
lo_arg** argv, int argc, lo_message msg) {
}
void GdPd::processAudio(void *outputBuffer, void *inputBuffer,
unsigned int nBufferFrames) {
int ticks = nBufferFrames / libpd_blocksize();
......
......@@ -42,6 +42,8 @@
#include "PdBase.hpp"
#include "RtAudio.h"
#include <lo/lo.h>
using namespace godot;
class GdPdStreamPlayback;
......@@ -52,6 +54,18 @@ class GdPd : public Node, public pd::PdReceiver {
protected:
static void _bind_methods();
static int oscHandler(const char *path, const char *types,
lo_arg ** argv,
int argc, lo_message msg, void *user_data) {
GdPd* gdpd = (GdPd*)user_data;
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){};
private:
bool m_realtime;
......@@ -75,6 +89,13 @@ private:
enum Mode {OSC, AUDIO, AUDIO_RT};
int m_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_receiver;
int m_senderPort;
int m_receiverPort;
private:
int start();
......
Subproject commit a3dc0cb3b73d0cfdf31463f26df72342f3c26e2b
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment