This commit is contained in:
Dooho Yi 2023-09-30 19:46:43 +09:00
parent defc59a5d2
commit 0c2fc7d192
11 changed files with 369 additions and 321 deletions

View file

@ -5,47 +5,46 @@ script/source = "extends Control
var _gdpd var _gdpd
var _patch = 0
func _ready():
_gdpd = load(\"res://addons/gdpd/bin/gdpd.gdns\").new()
pass
func _process(delta):
while _gdpd.has_message() :
print(\"got msg\")
var msg = _gdpd.get_next()
print(msg)
func _load_patch(pd_patch) : func _load_patch(pd_patch) :
#separate file name from directory #separate file name from directory
var patch_name = pd_patch.split(\"/\")[-1] var patch_name = pd_patch.split(\"/\")[-1]
var patch_dir = pd_patch.trim_suffix(patch_name) var patch_dir = pd_patch.trim_suffix(patch_name)
#load patch #load patch
_gdpd.openfile(patch_name, patch_dir) _gdpd.openPatch(patch_name, patch_dir)
func _on_Start_pressed() : func _ready() :
_gdpd = load(\"res://addons/gdpd/bin/gdpd.gdns\").new()
func _process(delta) :
while _gdpd.has_message() :
var msg = _gdpd.get_next()
print(msg)
if msg[0] == \"random\" :
# print(\"r\")
pass
func _on_Start_pressed() :
var inps = _gdpd.get_available_input_devices() var inps = _gdpd.get_available_input_devices()
var outs = _gdpd.get_available_output_devices() var outs = _gdpd.get_available_output_devices()
# _gdpd.init(0, 2, 48000, 64)
_gdpd.init_devices(inps[0], outs[0]) _gdpd.init_devices(inps[0], outs[0])
#the patch path should be the absolute one #the patch path should be the absolute one
_load_patch(ProjectSettings.globalize_path(\"res://patch1.pd\")) _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\"))
_load_patch(ProjectSettings.globalize_path(\"res://patch2.pd\")) _load_patch(ProjectSettings.globalize_path(\"res://patch.pd\"))
_gdpd.start_message(1) _gdpd.subscribe(\"toGodot\")
_gdpd.add_symbol(\"from godot\")
_gdpd.finish_list(\"blup\")
_gdpd.subscribe(\"toBfWeb\") func _on_Stop_pressed() :
func _on_Stop_pressed(): _gdpd.closeAllPatches()
_gdpd.closefile(\"patch1.pd\")
_gdpd.closefile(\"patch2.pd\")
_gdpd.stop() _gdpd.stop()
func _on_Send_pressed() :
_gdpd.start_message(1)
_gdpd.add_float(300)
_gdpd.finish_list(\"fromGodot\")
" "
@ -58,28 +57,38 @@ __meta__ = {
} }
[node name="Stop" type="Button" parent="."] [node name="Stop" type="Button" parent="."]
margin_left = 73.0 anchor_left = 0.5
margin_top = 198.0 anchor_top = 0.5
margin_right = 176.0 anchor_right = 0.5
margin_bottom = 244.0 anchor_bottom = 0.5
margin_left = -50.0
margin_top = 75.0
margin_right = 50.0
margin_bottom = 125.0
text = "Stop" text = "Stop"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Start" type="Button" parent="."] [node name="Start" type="Button" parent="."]
margin_left = 83.0 anchor_left = 0.5
margin_top = 93.0 anchor_top = 0.5
margin_right = 187.0 anchor_right = 0.5
margin_bottom = 144.0 anchor_bottom = 0.5
margin_left = -50.0
margin_top = -125.0
margin_right = 50.0
margin_bottom = -75.0
text = "Start" text = "Start"
[node name="Load" type="Button" parent="."] [node name="Send" type="Button" parent="."]
margin_left = 103.0 anchor_left = 0.5
margin_top = 159.0 anchor_top = 0.5
margin_right = 145.0 anchor_right = 0.5
margin_bottom = 179.0 anchor_bottom = 0.5
text = "Load" margin_left = -50.0
margin_top = -25.0
margin_right = 50.0
margin_bottom = 25.0
text = "send"
[connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"] [connection signal="pressed" from="Stop" to="." method="_on_Stop_pressed"]
[connection signal="pressed" from="Start" to="." method="_on_Start_pressed"] [connection signal="pressed" from="Start" to="." method="_on_Start_pressed"]
[connection signal="pressed" from="Load" to="." method="_on_Load_pressed"] [connection signal="pressed" from="Send" to="." method="_on_Send_pressed"]

View file

@ -6,4 +6,3 @@
resource_name = "gdpd" resource_name = "gdpd"
class_name = "Gdpd" class_name = "Gdpd"
library = ExtResource( 1 ) library = ExtResource( 1 )
_sections_unfolded = [ "Resource" ]

Binary file not shown.

View file

@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false process/premult_alpha=false
process/HDR_as_SRGB=false process/HDR_as_SRGB=false
process/invert_color=false process/invert_color=false
process/normal_map_invert_y=false
stream=false stream=false
size_limit=0 size_limit=0
detect_3d=true detect_3d=true

28
GdpdExample/patch.pd Normal file
View file

@ -0,0 +1,28 @@
#N canvas 427 209 450 357 12;
#X obj 292 61 loadbang;
#X msg 292 91 \; pd dsp 1;
#X obj 92 86 t b;
#X obj 61 38 bng 19 250 50 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000;
#X obj 300 299 dac~;
#X obj 300 239 osc~ 440;
#X obj 300 269 *~ 0.1;
#X obj 300 142 random 900;
#X obj 300 166 + 500;
#X floatatom 300 190 5 0 0 0 - - - 0;
#X obj 187 39 r fromGodot;
#X obj 117 308 s toGodot;
#X obj 117 278 list;
#X msg 117 248 random \$1;
#X connect 0 0 1 0;
#X connect 2 0 7 0;
#X connect 3 0 2 0;
#X connect 5 0 6 0;
#X connect 6 0 4 0;
#X connect 6 0 4 1;
#X connect 7 0 8 0;
#X connect 8 0 9 0;
#X connect 9 0 5 0;
#X connect 9 0 13 0;
#X connect 10 0 2 0;
#X connect 12 0 11 0;
#X connect 13 0 12 0;

View file

@ -0,0 +1,15 @@
#N canvas 436 326 450 300 12;
#X obj 116 235 dac~;
#X obj 116 175 osc~ 440;
#X obj 116 205 *~ 0.1;
#X obj 116 78 random 900;
#X obj 116 102 + 500;
#X floatatom 116 126 5 0 0 0 - - - 0;
#X obj 99 29 inlet;
#X connect 1 0 2 0;
#X connect 2 0 0 0;
#X connect 2 0 0 1;
#X connect 3 0 4 0;
#X connect 4 0 5 0;
#X connect 5 0 1 0;
#X connect 6 0 3 0;

View file

@ -1,29 +1,17 @@
#N canvas 2 268 738 330 12; #N canvas 203 306 402 347 12;
#X obj 344 82 s pd; #X obj 292 61 loadbang;
#X obj 344 31 loadbang; #X obj 187 39 r blup;
#X msg 344 55 dsp 1; #X msg 292 91 \; pd dsp 1;
#X obj 152 134 dac~; #X obj 145 207 clone patch1-node 2;
#X obj 152 86 osc~ 440; #X floatatom 41 256 5 0 0 0 - - - 0;
#X obj 152 110 *~ 0.1; #X msg 41 279 vis \$1 1;
#X obj 240 91 loadbang; #X msg 180 128 all bang;
#X obj 241 141 metro 1000; #X obj 92 86 t b;
#X msg 240 168 patch1 0; #X obj 61 38 bng 19 250 50 0 empty empty empty 0 -10 0 12 #fcfcfc #000000 #000000;
#X obj 564 191 print patch1; #X connect 0 0 2 0;
#X obj 491 27 r blup; #X connect 1 0 7 0;
#X obj 506 91 print patch1;
#X obj 239 255 s toBfWeb;
#X obj 559 148 r toBfWeb;
#X obj 240 193 list append;
#X obj 491 51 t b b;
#X connect 1 0 2 0;
#X connect 2 0 0 0;
#X connect 4 0 5 0; #X connect 4 0 5 0;
#X connect 5 0 3 0; #X connect 5 0 3 0;
#X connect 5 0 3 1; #X connect 6 0 3 0;
#X connect 6 0 7 0; #X connect 7 0 6 0;
#X connect 7 0 8 0; #X connect 8 0 7 0;
#X connect 8 0 14 0;
#X connect 10 0 15 0;
#X connect 13 0 9 0;
#X connect 14 0 12 0;
#X connect 15 1 11 0;

View file

@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]
@ -20,9 +19,15 @@ run/main_scene="res://Main.tscn"
run/low_processor_mode=true run/low_processor_mode=true
config/icon="res://icon.png" config/icon="res://icon.png"
[display]
window/size/width=480
window/size/height=640
window/stretch/mode="2d"
window/stretch/aspect="keep"
[rendering] [rendering]
quality/driver/driver_name="GLES2"
vram_compression/import_etc=true vram_compression/import_etc=true
vram_compression/import_etc2=false vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres" environment/default_environment="res://default_env.tres"

View file

@ -3,38 +3,36 @@
using namespace godot; using namespace godot;
void Gdpd::_register_methods() { void Gdpd::_register_methods() {
register_method("get_available_input_devices", register_method("get_available_input_devices", &Gdpd::get_available_input_devices);
&Gdpd::get_available_input_devices); register_method("get_available_output_devices", &Gdpd::get_available_output_devices);
register_method("get_available_output_devices", register_method("init_devices", &Gdpd::init_devices);
&Gdpd::get_available_output_devices); register_method("init", &Gdpd::init);
register_method("init_devices", &Gdpd::init_devices); register_method("stop", &Gdpd::stop);
register_method("init", &Gdpd::init); register_method("openPatch", &Gdpd::openPatch);
register_method("stop", &Gdpd::stop); register_method("closeAllPatches", &Gdpd::closeAllPatches);
register_method("openfile", &Gdpd::openfile); register_method("subscribe", &Gdpd::subscribe);
register_method("closefile", &Gdpd::closefile); register_method("has_message", &Gdpd::has_message);
register_method("subscribe", &Gdpd::subscribe); register_method("get_next", &Gdpd::get_next);
register_method("has_message", &Gdpd::has_message); register_method("start_message", &Gdpd::start_message);
register_method("get_next", &Gdpd::get_next); register_method("add_symbol", &Gdpd::add_symbol);
register_method("start_message", &Gdpd::start_message); register_method("add_float", &Gdpd::add_float);
register_method("add_symbol", &Gdpd::add_symbol); register_method("finish_list", &Gdpd::finish_list);
register_method("add_float", &Gdpd::add_float); register_method("set_volume", &Gdpd::set_volume);
register_method("finish_list", &Gdpd::finish_list);
register_method("set_volume", &Gdpd::set_volume);
} }
int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer, int Gdpd::audioCallback(void *outputBuffer, void *inputBuffer,
unsigned int nBufferFrames, double streamTime, unsigned int nBufferFrames, double streamTime,
RtAudioStreamStatus status, void *userData){ RtAudioStreamStatus status, void *userData){
Gdpd* gdpd = static_cast<Gdpd*>(userData); Gdpd* gdpd = static_cast<Gdpd*>(userData);
gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime, gdpd->processAudio(outputBuffer, inputBuffer, nBufferFrames, streamTime,
status, userData); status, userData);
return 0; return 0;
} }
Gdpd::Gdpd(): m_vol(1) { Gdpd::Gdpd() : m_vol(1) {
//create message array //create message array
m_messages = new Array(); m_messages = new Array();
m_init=false; m_init=false;
} }
void Gdpd::_init() { void Gdpd::_init() {
@ -42,250 +40,253 @@ void Gdpd::_init() {
} }
Gdpd::~Gdpd() { Gdpd::~Gdpd() {
} }
Array Gdpd::get_available_input_devices() { Array Gdpd::get_available_input_devices() {
Array gdlist; Array gdlist;
for(int d=0; d<m_audio.getDeviceCount(); d++) { for(int d=0; d<m_audio.getDeviceCount(); d++) {
if(m_audio.getDeviceInfo(d).inputChannels>0) { if(m_audio.getDeviceInfo(d).inputChannels>0) {
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str()); gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
} }
} }
return gdlist; return gdlist;
} }
Array Gdpd::get_available_output_devices() { Array Gdpd::get_available_output_devices() {
Array gdlist; Array gdlist;
for(int d=0; d<m_audio.getDeviceCount(); d++) { for(int d=0; d<m_audio.getDeviceCount(); d++) {
if(m_audio.getDeviceInfo(d).outputChannels>0) { if(m_audio.getDeviceInfo(d).outputChannels>0) {
gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str()); gdlist.push_back(m_audio.getDeviceInfo(d).name.c_str());
} }
} }
return gdlist; return gdlist;
} }
int Gdpd::init_devices(String inputDevice, String outputDevice) { int Gdpd::init_devices(String inputDevice, String outputDevice) {
std::wstring inpWs = inputDevice.unicode_str(); std::wstring inpWs = inputDevice.unicode_str();
std::string inpStr(inpWs.begin(), inpWs.end()); std::string inpStr(inpWs.begin(), inpWs.end());
std::wstring outWs = outputDevice.unicode_str(); std::wstring outWs = outputDevice.unicode_str();
std::string outStr(outWs.begin(), outWs.end()); std::string outStr(outWs.begin(), outWs.end());
for(int d=0; d<m_audio.getDeviceCount(); d++) { for(int d=0; d<m_audio.getDeviceCount(); d++) {
std::string n = m_audio.getDeviceInfo(d).name; std::string n = m_audio.getDeviceInfo(d).name;
if(n.compare(inpStr)==0) { if(n.compare(inpStr)==0) {
m_inputDevice = d; m_inputDevice = d;
} }
if(n.compare(outStr)==0) { if(n.compare(outStr)==0) {
m_outputDevice = d; m_outputDevice = d;
} }
} }
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice); RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice); RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
m_nbInputs = inpInfo.inputChannels; m_nbInputs = inpInfo.inputChannels;
m_nbOutputs = outInfo.outputChannels; m_nbOutputs = outInfo.outputChannels;
m_sampleRate = outInfo.preferredSampleRate; m_sampleRate = outInfo.preferredSampleRate;
m_bufferFrames = 128; m_bufferFrames = 128;
return start(); return start();
} }
int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) { int Gdpd::init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize) {
m_inputDevice = m_audio.getDefaultInputDevice(); m_inputDevice = m_audio.getDefaultInputDevice();
m_outputDevice = m_audio.getDefaultOutputDevice(); m_outputDevice = m_audio.getDefaultOutputDevice();
RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice); RtAudio::DeviceInfo inpInfo = m_audio.getDeviceInfo(m_inputDevice);
RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice); RtAudio::DeviceInfo outInfo = m_audio.getDeviceInfo(m_outputDevice);
m_nbInputs = std::min<int>(nbInputs, inpInfo.inputChannels); m_nbInputs = std::min<int>(nbInputs, inpInfo.inputChannels);
m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels); m_nbOutputs = std::min<int>(nbOutputs, outInfo.outputChannels);
m_sampleRate = sampleRate; m_sampleRate = sampleRate;
m_bufferFrames = std::max<int>(64, bufferSize); m_bufferFrames = std::max<int>(64, bufferSize);
return start(); return start();
} }
int Gdpd::start() { int Gdpd::start() {
RtAudio::StreamParameters outParams, inpParams; RtAudio::StreamParameters outParams, inpParams;
inpParams.deviceId = m_inputDevice; inpParams.deviceId = m_inputDevice;
inpParams.nChannels = m_nbInputs; inpParams.nChannels = m_nbInputs;
outParams.deviceId = m_outputDevice; outParams.deviceId = m_outputDevice;
outParams.nChannels = m_nbOutputs; outParams.nChannels = m_nbOutputs;
print("Output channels = "+std::to_string(outParams.nChannels)); print("Output channels = "+std::to_string(outParams.nChannels));
print("Input channels = "+std::to_string(inpParams.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;
}
if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) { //libpd_set_verbose(1);
print("GDPD : Error starting libpd");
return 1;
}
//libpd_set_verbose(1); //start dsp
m_pd.computeAudio(true);
//start dsp //intialize rtaudio
m_pd.computeAudio(true); if(m_audio.getDeviceCount()==0){
Godot::print("There are no available sound devices.");
}
//intialize rtaudio RtAudio::StreamOptions options;
if(m_audio.getDeviceCount()==0){ options.streamName = "gdpd";
Godot::print("There are no available sound devices."); options.flags = RTAUDIO_SCHEDULE_REALTIME;
} if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) {
options.flags |= RTAUDIO_MINIMIZE_LATENCY;
}
if (m_nbInputs == 0) {
try {
m_audio.openStream(&outParams, NULL, RTAUDIO_FLOAT32,
m_sampleRate, &m_bufferFrames, &audioCallback,
this, &options);
m_audio.startStream();
print("Stream started");
}
catch(RtAudioError& e) {
Godot::print(e.getMessage().c_str());
}
} else {
try {
m_audio.openStream(&outParams, &inpParams, RTAUDIO_FLOAT32,
m_sampleRate, &m_bufferFrames, &audioCallback,
this, &options);
m_audio.startStream();
print("Stream started");
}
catch(RtAudioError& e) {
Godot::print(e.getMessage().c_str());
}
}
RtAudio::StreamOptions options; //create message hook
options.streamName = "gdpd"; m_pd.subscribe("to_gdpd");
options.flags = RTAUDIO_SCHEDULE_REALTIME; m_pd.setReceiver(this);
if(m_audio.getCurrentApi() != RtAudio::MACOSX_CORE) { m_init=true;
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) {
Godot::print(e.getMessage().c_str());
}
//create message hook print("Initialized");
m_pd.subscribe("to_gdpd");
m_pd.setReceiver(this);
m_init=true;
print("Initialized"); return 0;
return 0;
} }
void Gdpd::stop() { void Gdpd::stop() {
m_audio.stopStream(); m_audio.stopStream();
m_audio.closeStream(); m_audio.closeStream();
m_pd.computeAudio(false); m_pd.computeAudio(false);
print("Stopped"); print("Stopped");
} }
void Gdpd::processAudio(void *outputBuffer, void *inputBuffer, void Gdpd::processAudio(void *outputBuffer, void *inputBuffer,
unsigned int nBufferFrames, double streamTime, unsigned int nBufferFrames, double streamTime,
RtAudioStreamStatus status, void *userData) { RtAudioStreamStatus status, void *userData) {
int ticks = nBufferFrames / libpd_blocksize(); int ticks = nBufferFrames / libpd_blocksize();
m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer); m_pd.processFloat(ticks, (float*)inputBuffer, (float*)outputBuffer);
//volume control on the output //volume control on the output
for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) { for(int b=0; b<nBufferFrames*m_nbOutputs; ++b) {
((float*)outputBuffer)[b]*=m_vol; ((float*)outputBuffer)[b]*=m_vol;
} }
} }
void Gdpd::openfile(godot::String baseStr, godot::String dirStr) { void Gdpd::openPatch(godot::String baseStr, godot::String dirStr) {
std::wstring baseWs = baseStr.unicode_str(); std::wstring baseWs = baseStr.unicode_str();
std::string baseS(baseWs.begin(), baseWs.end()); std::string baseS(baseWs.begin(), baseWs.end());
std::wstring dirWs = dirStr.unicode_str(); std::wstring dirWs = dirStr.unicode_str();
std::string dirS(dirWs.begin(), dirWs.end()); std::string dirS(dirWs.begin(), dirWs.end());
if(m_patchsMap.find(baseS)!=m_patchsMap.end()) { //libpd_openfile(baseS.c_str(), dirS.c_str());
print("Patch "+baseS+" already opened"); //m_patch = m_pd.openPatch(baseS.c_str(), dirS.c_str());
return; 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);
}
//libpd_openfile(baseS.c_str(), dirS.c_str()); //m_pd.subscribe("to_gdpd");
//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_patchsMap[baseS] = p1;
}
//m_pd.subscribe("to_gdpd"); /*
if(!m_pd.init(m_nbInputs, m_nbOutputs, m_sampleRate, true)) {
/* Godot::print("GDPD : Error starting libpd");
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);
m_pd.setReceiver(this); */
m_pd.computeAudio(true);
*/
} }
void Gdpd::closefile(godot::String baseStr) { void Gdpd::closeAllPatches() {
std::wstring baseWs = baseStr.unicode_str(); for (int idx = 0; idx < m_patches.size(); idx++) {
std::string baseS(baseWs.begin(), baseWs.end()); m_pd.closePatch(m_patches[idx]);
if(m_patchsMap.find(baseS)!=m_patchsMap.end()) { }
m_pd.closePatch(m_patchsMap[baseS]); m_patches.clear();
m_patchsMap.erase(baseS);
print("Closed patch "+baseS);
}
//m_pd.closePatch(baseS.c_str());
} }
void Gdpd::subscribe(String symbStr) { void Gdpd::subscribe(String symbStr) {
std::wstring symbWs = symbStr.unicode_str(); std::wstring symbWs = symbStr.unicode_str();
std::string symbS(symbWs.begin(), symbWs.end()); std::string symbS(symbWs.begin(), symbWs.end());
m_pd.subscribe(symbS.c_str()); m_pd.subscribe(symbS.c_str());
} }
bool Gdpd::has_message() { bool Gdpd::has_message() {
//receive new messages //receive new messages
m_pd.receiveMessages(); m_pd.receiveMessages();
//return if more than one message //return if more than one message
int size = m_messages->size(); int size = m_messages->size();
return size>0; return size>0;
} }
Array Gdpd::get_next() { Array Gdpd::get_next() {
Array msg = m_messages->pop_front(); Array msg = m_messages->pop_front();
return msg; return msg;
} }
int Gdpd::blocksize() { int Gdpd::blocksize() {
int blocksize = libpd_blocksize(); int blocksize = libpd_blocksize();
return blocksize; return blocksize;
} }
int Gdpd::start_message(int nbValues) { int Gdpd::start_message(int nbValues) {
int res = libpd_start_message(nbValues); int res = libpd_start_message(nbValues);
return res; return res;
} }
void Gdpd::add_symbol(String symbStr) { void Gdpd::add_symbol(String symbStr) {
std::wstring symbWs = symbStr.unicode_str(); std::wstring symbWs = symbStr.unicode_str();
std::string symbS(symbWs.begin(), symbWs.end()); std::string symbS(symbWs.begin(), symbWs.end());
libpd_add_symbol(symbS.c_str()); libpd_add_symbol(symbS.c_str());
} }
void Gdpd::add_float(float val) { void Gdpd::add_float(float val) {
libpd_add_float(val); libpd_add_float(val);
} }
int Gdpd::finish_list(String destStr) { int Gdpd::finish_list(String destStr) {
std::wstring destWs = destStr.unicode_str(); std::wstring destWs = destStr.unicode_str();
std::string destS(destWs.begin(), destWs.end()); std::string destS(destWs.begin(), destWs.end());
int res = libpd_finish_list(destS.c_str()); int res = libpd_finish_list(destS.c_str());
return res; return res;
} }
void Gdpd::print(const std::string& message) { void Gdpd::print(const std::string& message) {
Godot::print((std::string("GDPD : ")+message).c_str()); Godot::print((std::string("GDPD : ")+message).c_str());
} }
void Gdpd::receiveList(const std::string& dest, const pd::List& list) { void Gdpd::receiveList(const std::string& dest, const pd::List& list) {
Array gdlist; Array gdlist;
for(int i = 0; i < list.len(); ++i) { for(int i = 0; i < list.len(); ++i) {
if(list.isFloat(i)) { if(list.isFloat(i)) {
gdlist.push_back(list.getFloat(i)); gdlist.push_back(list.getFloat(i));
} }
else if(list.isSymbol(i)) { else if(list.isSymbol(i)) {
String symbStr(list.getSymbol(i).c_str()); String symbStr(list.getSymbol(i).c_str());
gdlist.push_back(symbStr); gdlist.push_back(symbStr);
} }
} }
m_messages->push_back(gdlist); m_messages->push_back(gdlist);
} }
void Gdpd::set_volume(float vol) { void Gdpd::set_volume(float vol) {
m_vol=vol; m_vol=vol;
} }

View file

@ -16,68 +16,70 @@
namespace godot { namespace godot {
class Gdpd : public godot::AudioStreamPlayer, public pd::PdReceiver { class Gdpd : public godot::AudioStreamPlayer, public pd::PdReceiver {
GODOT_CLASS(Gdpd, AudioStreamPlayer) GODOT_CLASS(Gdpd, AudioStreamPlayer)
private: private:
float *m_inBuf; float *m_inBuf;
float *m_outBuf; float *m_outBuf;
Array* m_messages; Array* m_messages;
pd::PdBase m_pd; pd::PdBase m_pd;
pd::Patch m_patch; pd::Patch m_patch;
RtAudio m_audio; RtAudio m_audio;
unsigned int m_bufferFrames; unsigned int m_bufferFrames;
float m_vol; float m_vol;
int m_nbInputs; int m_nbInputs;
int m_nbOutputs; int m_nbOutputs;
int m_sampleRate; int m_sampleRate;
int m_inputDevice; int m_inputDevice;
int m_outputDevice; int m_outputDevice;
std::map<std::string, pd::Patch> m_patchsMap; std::vector<pd::Patch> m_patches;
bool m_init; bool m_init;
public: public:
static void _register_methods(); static void _register_methods();
Gdpd(); Gdpd();
~Gdpd(); ~Gdpd();
void _init(); void _init();
//libpd functions //libpd functions
Array get_available_input_devices(); Array get_available_input_devices();
Array get_available_output_devices(); Array get_available_output_devices();
int init_devices(String inputDevice, String outputDevice); int init_devices(String inputDevice, String outputDevice);
int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize); int init(int nbInputs, int nbOutputs, int sampleRate, int bufferSize);
int start(); int start();
void stop(); void stop();
void openfile(String basename, String dirname); void openPatch(String basename, String dirname);
void closefile(String basename); void closeAllPatches();
bool has_message(); bool has_message();
Array get_next(); Array get_next();
int blocksize(); int blocksize();
void subscribe(String symbStr); void subscribe(String symbStr);
int start_message(int nbValues); int start_message(int nbValues);
void add_symbol(String symbStr); void add_symbol(String symbStr);
void add_float(float val); void add_float(float val);
int finish_list(String destStr); int finish_list(String destStr);
//libpd hooks //libpd hooks
virtual void print(const std::string& message); virtual void print(const std::string& message);
void receiveList(const std::string& dest, const pd::List& list); void receiveList(const std::string& dest, const pd::List& list);
//godot functions //godot functions
void set_volume(float vol); void set_volume(float vol);
inline const float& get_volume(){return m_vol;} inline const float& get_volume(){
return m_vol;
}
//rtaudio //rtaudio
static int audioCallback(void *outputBuffer, void *inputBuffer, static int audioCallback(void *outputBuffer, void *inputBuffer,
unsigned int nBufferFrames, double streamTime, unsigned int nBufferFrames, double streamTime,
RtAudioStreamStatus status, void *userData); RtAudioStreamStatus status, void *userData);
void processAudio(void *outputBuffer, void *inputBuffer, void processAudio(void *outputBuffer, void *inputBuffer,
unsigned int nBufferFrames, double streamTime, unsigned int nBufferFrames, double streamTime,
RtAudioStreamStatus status, void *userData); RtAudioStreamStatus status, void *userData);
}; };

Binary file not shown.