updated
This commit is contained in:
parent
defc59a5d2
commit
0c2fc7d192
11 changed files with 369 additions and 321 deletions
|
|
@ -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 _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() :
|
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"]
|
||||||
|
|
|
||||||
|
|
@ -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" ]
|
|
||||||
|
|
|
||||||
BIN
GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib
Executable file
BIN
GdpdExample/addons/gdpd/bin/osx/libgdpd.dylib
Executable file
Binary file not shown.
|
|
@ -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
28
GdpdExample/patch.pd
Normal 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;
|
||||||
15
GdpdExample/patch1-node.pd
Normal file
15
GdpdExample/patch1-node.pd
Normal 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;
|
||||||
|
|
@ -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;
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
393
src/gdpd.cpp
393
src/gdpd.cpp
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
102
src/gdpd.hpp
102
src/gdpd.hpp
|
|
@ -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.
Loading…
Reference in a new issue