@@ -19,6 +19,7 @@ LUAJIT ?= 1 | |||||
PYTHON ?= 0 | PYTHON ?= 0 | ||||
SUPERCOLLIDER ?= 0 | SUPERCOLLIDER ?= 0 | ||||
VULT ?= 1 | VULT ?= 1 | ||||
LIBPD ?= 1 | |||||
# Vult depends on both LuaJIT and QuickJS | # Vult depends on both LuaJIT and QuickJS | ||||
ifeq ($(VULT), 1) | ifeq ($(VULT), 1) | ||||
@@ -37,6 +38,32 @@ $(efsw): | |||||
cd efsw && cp lib/libefsw-static-release.a $(DEP_PATH)/lib/ | cd efsw && cp lib/libefsw-static-release.a $(DEP_PATH)/lib/ | ||||
cd efsw && cp -R include/efsw $(DEP_PATH)/include/ | cd efsw && cp -R include/efsw $(DEP_PATH)/include/ | ||||
# LibPD | |||||
ifeq ($(LIBPD), 1) | |||||
libpd := dep/lib/libpd.a | |||||
SOURCES += src/LibPDEngine.cpp | |||||
OBJECTS += $(libpd) | |||||
DEPS += $(libpd) | |||||
FLAGS += -Idep/include/libpd | |||||
ifdef ARCH_WIN | |||||
FLAGS += -DPD_INTERNAL -D_WIN32 | |||||
LDFLAGS += -shared -Wl,--export-all-symbols -lws2_32 -lkernel32 -static-libgcc | |||||
endif | |||||
$(libpd): | |||||
$(WGET) "https://github.com/chairaudio/libpd/archive/master.tar.gz" | |||||
$(SHA256) master.tar.gz 9edfd4a7423009a61069fb4b2fa027a62705ffa0dcf23bbb6c220f1c6e709d3d | |||||
cd dep && $(UNTAR) ../master.tar.gz | |||||
$(WGET) "https://github.com/pure-data/pure-data/archive/0.50-2.tar.gz" | |||||
$(SHA256) 0.50-2.tar.gz 0bdc9503d25f71e05ce6d321dd853f4e8082fdea211a59439eddd8105cc8761e | |||||
cd dep/libpd-master/pure-data && $(UNTAR) ../../../0.50-2.tar.gz --strip-components=1 | |||||
cd dep/libpd-master && make MULTI=true BUILD_LIBPD_STATIC=true ADDITIONAL_CFLAGS='-DPD_LONGINTTYPE="long long"' | |||||
cd dep/libpd-master && $(MAKE) install prefix="$(DEP_PATH)" | |||||
endif | |||||
# Duktape | # Duktape | ||||
ifeq ($(DUKTAPE), 1) | ifeq ($(DUKTAPE), 1) | ||||
SOURCES += src/DuktapeEngine.cpp | SOURCES += src/DuktapeEngine.cpp | ||||
@@ -63,7 +90,6 @@ endif | |||||
$(quickjs): | $(quickjs): | ||||
cd dep && git clone "https://github.com/JerrySievert/QuickJS.git" | cd dep && git clone "https://github.com/JerrySievert/QuickJS.git" | ||||
cd dep/QuickJS && git checkout 807adc8ca9010502853d471bd8331cdc1d376b94 | cd dep/QuickJS && git checkout 807adc8ca9010502853d471bd8331cdc1d376b94 | ||||
cd dep/QuickJS && $(MAKE) $(QUICKJS_MAKE_FLAGS) | |||||
cd dep/QuickJS && $(MAKE) $(QUICKJS_MAKE_FLAGS) install | cd dep/QuickJS && $(MAKE) $(QUICKJS_MAKE_FLAGS) install | ||||
endif | endif | ||||
@@ -11,6 +11,7 @@ Supported scripting languages: | |||||
- JavaScript (ES2020) (.js) | - JavaScript (ES2020) (.js) | ||||
- [Lua](https://www.lua.org/) (.lua) | - [Lua](https://www.lua.org/) (.lua) | ||||
- [Vult](https://github.com/modlfo/vult) (.vult) | - [Vult](https://github.com/modlfo/vult) (.vult) | ||||
- [Pure Data](https://puredata.info) (.pd) | |||||
- [Add your own below](#adding-a-script-engine) | - [Add your own below](#adding-a-script-engine) | ||||
[Discussion thread](https://community.vcvrack.com/t/vcv-prototype/3271) | [Discussion thread](https://community.vcvrack.com/t/vcv-prototype/3271) | ||||
@@ -116,6 +117,23 @@ sudo apt install premake4 | |||||
sudo pacman -S premake | sudo pacman -S premake | ||||
``` | ``` | ||||
## Build | |||||
### Add path to Rack-SDK | |||||
```bash | |||||
export RACK_DIR=/set/path/to/Rack-SDK/ | |||||
``` | |||||
### load submodules | |||||
```bash | |||||
git submodule update --init --recursive | |||||
``` | |||||
### Make | |||||
```bash | |||||
make dep | |||||
make | |||||
``` | |||||
## Adding a script engine | ## Adding a script engine | ||||
- Add your scripting language library to the build system so it builds with `make dep`, following the Duktape example in `Makefile`. | - Add your scripting language library to the build system so it builds with `make dep`, following the Duktape example in `Makefile`. | ||||
@@ -131,4 +149,5 @@ sudo pacman -S premake | |||||
- [Andrew Belt](https://github.com/AndrewBelt): host code, Duktape (JavaScript, not used), LuaJIT (Lua), Python (in development) | - [Andrew Belt](https://github.com/AndrewBelt): host code, Duktape (JavaScript, not used), LuaJIT (Lua), Python (in development) | ||||
- [Jerry Sievert](https://github.com/JerrySievert): QuickJS (JavaScript) | - [Jerry Sievert](https://github.com/JerrySievert): QuickJS (JavaScript) | ||||
- [Leonardo Laguna Ruiz](https://github.com/modlfo): Vult | - [Leonardo Laguna Ruiz](https://github.com/modlfo): Vult | ||||
- [CHAIR](https://chair.audio) [Clemens Wegener (libpd), Max Neupert (patches)] : libpd | |||||
- add your name here | - add your name here |
@@ -0,0 +1,113 @@ | |||||
#N canvas 860 318 890 742 12; | |||||
#X obj 117 30 adc~ 1 2 3 4 5 6, f 47; | |||||
#X obj 118 261 dac~ 1 2 3 4 5 6, f 47; | |||||
#X obj 117 98 *~ 1; | |||||
#X obj 182 98 *~ 1; | |||||
#X obj 246 98 *~ 1; | |||||
#X obj 312 98 *~ 1; | |||||
#X obj 376 98 *~ 1; | |||||
#X obj 442 98 *~ 1; | |||||
#X obj 21 422 print toVCV; | |||||
#X msg 171 365 L3 \$1 0 0; | |||||
#X msg 247 365 L4 \$1 0 0; | |||||
#X msg 397 365 L6 \$1 0 0; | |||||
#X msg 21 365 L1 \$1 0 0; | |||||
#X msg 96 365 L2 \$1 0 0; | |||||
#X msg 322 365 L5 \$1 0 0; | |||||
#X obj 118 229 *~ 1; | |||||
#X obj 183 228 *~ 1; | |||||
#X obj 247 228 *~ 1; | |||||
#X obj 313 228 *~ 1; | |||||
#X obj 377 228 *~ 1; | |||||
#X obj 443 228 *~ 1; | |||||
#X msg 21 521 S1 \$1 0 0; | |||||
#X msg 96 522 S2 \$1 0 0; | |||||
#X msg 171 522 S3 \$1 0 0; | |||||
#X msg 247 523 S4 \$1 0 0; | |||||
#X msg 322 523 S5 \$1 0 0; | |||||
#X msg 397 523 S6 \$1 0 0; | |||||
#X obj 20 30 r fromVCV; | |||||
#X obj 142 70 route K1 K2 K3 K4 K5 K6, f 56; | |||||
#X obj 143 169 route S1 S2 S3 S4 S5 S6, f 56; | |||||
#X obj 143 198 == 0; | |||||
#X obj 208 198 == 0; | |||||
#X obj 272 198 == 0; | |||||
#X obj 338 198 == 0; | |||||
#X obj 402 198 == 0; | |||||
#X obj 468 198 == 0; | |||||
#X obj 21 307 r fromVCV; | |||||
#X obj 21 336 route K1 K2 K3 K4 K5 K6, f 65; | |||||
#X obj 21 492 route S1 S2 S3 S4 S5 S6, f 65; | |||||
#X obj 21 463 r fromVCV; | |||||
#X obj 19 134 r fromVCV; | |||||
#X obj 21 569 print toVCV; | |||||
#X text 558 52 Usually we'd interpolate here with line~ but VCVRack | |||||
is already sending one message persample so there seems hardly a point | |||||
to complicate this example., f 38; | |||||
#X text 560 368 Just using the red channels in the RGB triplet for | |||||
the LED., f 35; | |||||
#X text 561 492 Same for the switch., f 35; | |||||
#X connect 0 0 2 0; | |||||
#X connect 0 1 3 0; | |||||
#X connect 0 2 4 0; | |||||
#X connect 0 3 5 0; | |||||
#X connect 0 4 6 0; | |||||
#X connect 0 5 7 0; | |||||
#X connect 2 0 15 0; | |||||
#X connect 3 0 16 0; | |||||
#X connect 4 0 17 0; | |||||
#X connect 5 0 18 0; | |||||
#X connect 6 0 19 0; | |||||
#X connect 7 0 20 0; | |||||
#X connect 9 0 8 0; | |||||
#X connect 10 0 8 0; | |||||
#X connect 11 0 8 0; | |||||
#X connect 12 0 8 0; | |||||
#X connect 13 0 8 0; | |||||
#X connect 14 0 8 0; | |||||
#X connect 15 0 1 0; | |||||
#X connect 16 0 1 1; | |||||
#X connect 17 0 1 2; | |||||
#X connect 18 0 1 3; | |||||
#X connect 19 0 1 4; | |||||
#X connect 20 0 1 5; | |||||
#X connect 21 0 41 0; | |||||
#X connect 22 0 41 0; | |||||
#X connect 23 0 41 0; | |||||
#X connect 24 0 41 0; | |||||
#X connect 25 0 41 0; | |||||
#X connect 26 0 41 0; | |||||
#X connect 27 0 28 0; | |||||
#X connect 28 0 2 1; | |||||
#X connect 28 1 3 1; | |||||
#X connect 28 2 4 1; | |||||
#X connect 28 3 5 1; | |||||
#X connect 28 4 6 1; | |||||
#X connect 28 5 7 1; | |||||
#X connect 29 0 30 0; | |||||
#X connect 29 1 31 0; | |||||
#X connect 29 2 32 0; | |||||
#X connect 29 3 33 0; | |||||
#X connect 29 4 34 0; | |||||
#X connect 29 5 35 0; | |||||
#X connect 30 0 15 1; | |||||
#X connect 31 0 16 1; | |||||
#X connect 32 0 17 1; | |||||
#X connect 33 0 18 1; | |||||
#X connect 34 0 19 1; | |||||
#X connect 35 0 20 1; | |||||
#X connect 36 0 37 0; | |||||
#X connect 37 0 12 0; | |||||
#X connect 37 1 13 0; | |||||
#X connect 37 2 9 0; | |||||
#X connect 37 3 10 0; | |||||
#X connect 37 4 14 0; | |||||
#X connect 37 5 11 0; | |||||
#X connect 38 0 21 0; | |||||
#X connect 38 1 22 0; | |||||
#X connect 38 2 23 0; | |||||
#X connect 38 3 24 0; | |||||
#X connect 38 4 25 0; | |||||
#X connect 38 5 26 0; | |||||
#X connect 39 0 38 0; | |||||
#X connect 40 0 29 0; |
@@ -0,0 +1,44 @@ | |||||
#N canvas 698 144 821 731 12; | |||||
#X obj 32 367 print toVCV; | |||||
#X obj 32 448 dac~ 1 2 3 4 5 6; | |||||
#X obj 32 401 adc~ 1 2 3 4 5 6; | |||||
#X text 158 401 audio from VCVRack; | |||||
#X text 158 448 audio to VCVRack; | |||||
#X obj 36 25 r fromVCV; | |||||
#X obj 36 62 route K1 K2 K3 K4 K5 K6; | |||||
#X obj 194 106 route S1 S2 S3 S4 S5 S6; | |||||
#X text 214 60 knobs; | |||||
#X text 369 104 buttons; | |||||
#X msg 134 333 display this text will print; | |||||
#X msg 32 227 K1 \$1; | |||||
#X obj 35 166 hsl 128 15 0 1 0 0 empty empty empty -2 -8 0 10 -262144 | |||||
-1 -1 0 1; | |||||
#X msg 102 226 S1 \$1; | |||||
#X obj 102 198 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 | |||||
1; | |||||
#X msg 132 297 L1 \$1 \$2 \$3; | |||||
#X obj 188 268 pack f f f; | |||||
#X obj 211 240 t b f; | |||||
#X obj 253 241 t b f; | |||||
#X obj 201 161 vsl 15 50 0 1 0 0 empty empty empty 0 -9 0 10 -258113 | |||||
-1 -1 0 1; | |||||
#X obj 216 161 vsl 15 50 0 1 0 0 empty empty empty 0 -9 0 10 -4034 | |||||
-1 -1 0 1; | |||||
#X obj 231 161 vsl 15 50 0 1 0 0 empty empty empty 0 -9 0 10 -4160 | |||||
-1 -1 0 1; | |||||
#X connect 5 0 6 0; | |||||
#X connect 6 6 7 0; | |||||
#X connect 10 0 0 0; | |||||
#X connect 11 0 0 0; | |||||
#X connect 12 0 11 0; | |||||
#X connect 13 0 0 0; | |||||
#X connect 14 0 13 0; | |||||
#X connect 15 0 0 0; | |||||
#X connect 16 0 15 0; | |||||
#X connect 17 0 16 0; | |||||
#X connect 17 1 16 1; | |||||
#X connect 18 0 16 0; | |||||
#X connect 18 1 16 2; | |||||
#X connect 19 0 16 0; | |||||
#X connect 20 0 17 0; | |||||
#X connect 21 0 18 0; |
@@ -0,0 +1,44 @@ | |||||
#N canvas 1290 443 439 466 12; | |||||
#X obj 69 7 r fromVCV; | |||||
#X obj 69 32 route K1; | |||||
#X obj 16 321 osc~; | |||||
#X obj 101 370 print toVCV; | |||||
#X msg 101 346 display Freq: \$1 Hz; | |||||
#X obj 115 112 adc~ 1; | |||||
#X obj 69 111 sig~; | |||||
#X obj 120 201 loadbang; | |||||
#X msg 120 226 1; | |||||
#X obj 120 251 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 | |||||
1; | |||||
#X obj 120 272 metro 50; | |||||
#X obj 101 297 snapshot~; | |||||
#X obj 101 323 change; | |||||
#X obj 69 138 +~, f 7; | |||||
#X obj 69 60 * 10; | |||||
#X obj 69 85 - 5; | |||||
#X obj 16 185 *~ 261.626; | |||||
#X obj 16 161 pow~ 2, f 8; | |||||
#X obj 16 137 sig~ 2; | |||||
#X obj 16 370 dac~ 1; | |||||
#X text 145 162 <--- FM with CV signal from IN1; | |||||
#X obj 15 346 *~ 5; | |||||
#X connect 0 0 1 0; | |||||
#X connect 1 0 14 0; | |||||
#X connect 2 0 21 0; | |||||
#X connect 4 0 3 0; | |||||
#X connect 5 0 13 1; | |||||
#X connect 6 0 13 0; | |||||
#X connect 7 0 8 0; | |||||
#X connect 8 0 9 0; | |||||
#X connect 9 0 10 0; | |||||
#X connect 10 0 11 0; | |||||
#X connect 11 0 12 0; | |||||
#X connect 12 0 4 0; | |||||
#X connect 13 0 17 1; | |||||
#X connect 14 0 15 0; | |||||
#X connect 15 0 6 0; | |||||
#X connect 16 0 2 0; | |||||
#X connect 16 0 11 0; | |||||
#X connect 17 0 16 0; | |||||
#X connect 18 0 17 0; | |||||
#X connect 21 0 19 0; |
@@ -0,0 +1,322 @@ | |||||
#include "ScriptEngine.hpp" | |||||
#include "z_libpd.h" | |||||
#include "util/z_print_util.h" | |||||
using namespace rack; | |||||
#define BUFFERSIZE MAX_BUFFER_SIZE * NUM_ROWS | |||||
// there is no multi-instance support for receiving messages from libpd | |||||
// for now, received values for the prototype gui will be stored in global variables | |||||
float g_lights[NUM_ROWS][3] = {}; | |||||
float g_switchLights[NUM_ROWS][3] = {}; | |||||
std::string g_utility[2] = {}; | |||||
bool g_display_is_valid = false; | |||||
std::vector<std::string> split (const std::string &s, char delim) { | |||||
std::vector<std::string> result; | |||||
std::stringstream ss (s); | |||||
std::string item; | |||||
while (getline (ss, item, delim)) { | |||||
result.push_back (item); | |||||
} | |||||
return result; | |||||
} | |||||
struct LibPDEngine : ScriptEngine { | |||||
~LibPDEngine() { | |||||
libpd_free_instance(_lpd); | |||||
} | |||||
void sendInitialStates(const ProcessBlock* block); | |||||
static void receiveLights(const char *s); | |||||
bool knobChanged(const float* knobs, int idx); | |||||
bool switchChanged(const bool* knobs, int idx); | |||||
void sendKnob(const int idx, const float value); | |||||
void sendSwitch(const int idx, const bool value); | |||||
t_pdinstance *_lpd; | |||||
int _pd_block_size = 64; | |||||
int _sampleRate = 0; | |||||
int _ticks = 0; | |||||
bool _init = true; | |||||
float _old_knobs[NUM_ROWS] = {}; | |||||
bool _old_switches[NUM_ROWS] = {}; | |||||
float _output[BUFFERSIZE] = {}; | |||||
float _input[BUFFERSIZE] = {};// = (float*)malloc(1024*2*sizeof(float)); | |||||
const static std::map<std::string, int> _light_map; | |||||
const static std::map<std::string, int> _switchLight_map; | |||||
const static std::map<std::string, int> _utility_map; | |||||
std::string getEngineName() override { | |||||
return "Pure Data"; | |||||
} | |||||
int run(const std::string& path, const std::string& script) override { | |||||
ProcessBlock* block = getProcessBlock(); | |||||
_sampleRate = block->sampleRate; | |||||
setBufferSize(_pd_block_size); | |||||
setFrameDivider(1); | |||||
libpd_init(); | |||||
_lpd = libpd_new_instance(); | |||||
libpd_set_printhook((t_libpd_printhook)libpd_print_concatenator); | |||||
libpd_set_concatenated_printhook( receiveLights ); | |||||
if(libpd_num_instances()>2) | |||||
{ | |||||
display("Sorry, multi instance support in libpd is under development!"); | |||||
return -1; | |||||
} | |||||
//display(std::to_string(libpd_num_instances())); | |||||
libpd_init_audio(NUM_ROWS, NUM_ROWS, _sampleRate); | |||||
// compute audio [; pd dsp 1( | |||||
libpd_start_message(1); // one enstry in list | |||||
libpd_add_float(1.0f); | |||||
libpd_finish_message("pd", "dsp"); | |||||
std::string version = "pd "+std::to_string(PD_MAJOR_VERSION)+"."+ | |||||
std::to_string(PD_MINOR_VERSION)+"."+ | |||||
std::to_string(PD_BUGFIX_VERSION); | |||||
display(version); | |||||
std::string name = string::filename(path); | |||||
std::string dir = string::directory(path); | |||||
libpd_openfile(name.c_str(), dir.c_str()); | |||||
sendInitialStates(block); | |||||
return 0; | |||||
} | |||||
int process() override { | |||||
// block | |||||
ProcessBlock* block = getProcessBlock(); | |||||
// get samples prototype | |||||
int rows = NUM_ROWS; | |||||
for (int s = 0; s < _pd_block_size; s++) { | |||||
for (int r = 0; r < rows; r++) { | |||||
_input[s*rows+r] = block->inputs[r][s]; | |||||
} | |||||
} | |||||
libpd_set_instance(_lpd); | |||||
// knobs | |||||
for (int i=0; i<NUM_ROWS; i++){ | |||||
if( knobChanged(block->knobs, i) ){ | |||||
sendKnob(i, block->knobs[i]); | |||||
} | |||||
} | |||||
// lights | |||||
for(int i=0; i<NUM_ROWS; i++){ | |||||
block->lights[i][0] = g_lights[i][0]; | |||||
block->lights[i][1] = g_lights[i][1]; | |||||
block->lights[i][2] = g_lights[i][2]; | |||||
} | |||||
// switch lights | |||||
for(int i=0; i<NUM_ROWS; i++){ | |||||
block->switchLights[i][0] = g_switchLights[i][0]; | |||||
block->switchLights[i][1] = g_switchLights[i][1]; | |||||
block->switchLights[i][2] = g_switchLights[i][2]; | |||||
} | |||||
// switches | |||||
for(int i=0; i<NUM_ROWS; i++){ | |||||
if( switchChanged(block->switches, i) ){ | |||||
sendSwitch(i, block->switches[i]); | |||||
} | |||||
} | |||||
// display | |||||
if(g_display_is_valid){ | |||||
display(g_utility[1]); | |||||
g_display_is_valid = false; | |||||
} | |||||
// process samples in libpd | |||||
_ticks = 1; | |||||
libpd_process_float(_ticks, _input, _output); | |||||
//return samples to prototype | |||||
for (int s = 0; s < _pd_block_size; s++) { | |||||
for (int r = 0; r < rows; r++) { | |||||
block->outputs[r][s] = _output[s*rows+r]; // scale up again to +-5V signal | |||||
// there is a correction multilpier, because libpd's output is too quiet(?) | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
}; | |||||
__attribute__((constructor(1000))) | |||||
static void constructor() { | |||||
addScriptEngine<LibPDEngine>("pd"); | |||||
} | |||||
void LibPDEngine::receiveLights(const char *s) { | |||||
std::string str = std::string(s); | |||||
std::vector<std::string> atoms = split (str, ' '); | |||||
if(atoms[0]=="toVCV:"){ | |||||
// parse lights list | |||||
bool light_is_valid = true; | |||||
int light_idx = -1; | |||||
try { | |||||
light_idx = _light_map.at(atoms[1]); // map::at throws an out-of-range | |||||
} | |||||
catch (const std::out_of_range& oor) { | |||||
light_is_valid = false; | |||||
//display("Warning:"+atoms[1]+" not found!"); | |||||
} | |||||
//std::cout << v[1] << ", " << g_led_map[v[1]] << std::endl; | |||||
if(light_is_valid && atoms.size()==5){ | |||||
g_lights[light_idx][0] = stof(atoms[2]); // red | |||||
g_lights[light_idx][1] = stof(atoms[3]); // green | |||||
g_lights[light_idx][2] = stof(atoms[4]); // blue | |||||
} | |||||
else { | |||||
// error | |||||
} | |||||
// parse switch lights list | |||||
bool switchLight_is_valid = true; | |||||
int switchLight_idx = -1; | |||||
try { | |||||
switchLight_idx = _switchLight_map.at(atoms[1]); // map::at throws an out-of-range | |||||
} | |||||
catch (const std::out_of_range& oor) { | |||||
switchLight_is_valid = false; | |||||
//display("Warning:"+atoms[1]+" not found!"); | |||||
} | |||||
//std::cout << v[1] << ", " << g_led_map[v[1]] << std::endl; | |||||
if(switchLight_is_valid && atoms.size()==5){ | |||||
g_switchLights[switchLight_idx][0] = stof(atoms[2]); // red | |||||
g_switchLights[switchLight_idx][1] = stof(atoms[3]); // green | |||||
g_switchLights[switchLight_idx][2] = stof(atoms[4]); // blue | |||||
} | |||||
else { | |||||
// error | |||||
} | |||||
// parse switch lights list | |||||
bool utility_is_valid = true; | |||||
try { | |||||
_utility_map.at(atoms[1]); // map::at throws an out-of-range | |||||
} | |||||
catch (const std::out_of_range& oor) { | |||||
utility_is_valid = false; | |||||
//g_display_is_valid = true; | |||||
//display("Warning:"+atoms[1]+" not found!"); | |||||
} | |||||
//std::cout << v[1] << ", " << g_led_map[v[1]] << std::endl; | |||||
if(utility_is_valid && atoms.size()>=3){ | |||||
g_utility[0] = atoms[1]; // display | |||||
g_utility[1] = {""}; | |||||
for(unsigned i=0; i<atoms.size()-2; i++){ | |||||
g_utility[1] += " " +atoms[i+2]; // concatenate message | |||||
} | |||||
g_display_is_valid = true; | |||||
} | |||||
else { | |||||
// error | |||||
} | |||||
} | |||||
else { | |||||
// print out on command line | |||||
std::cout << "libpd prototype unrecognizes message: " << std::string(s) << std::endl; | |||||
} | |||||
} | |||||
bool LibPDEngine::knobChanged(const float* knobs, int i){ | |||||
bool knob_changed = false; | |||||
if (_old_knobs[i] != knobs[i]){ | |||||
knob_changed = true; | |||||
_old_knobs[i] = knobs[i]; | |||||
} | |||||
return knob_changed; | |||||
} | |||||
bool LibPDEngine::switchChanged(const bool* switches, int i){ | |||||
bool switch_changed = false; | |||||
if (_old_switches[i] != switches[i]){ | |||||
switch_changed = true; | |||||
_old_switches[i] = switches[i]; | |||||
} | |||||
return switch_changed; | |||||
} | |||||
const std::map<std::string, int> LibPDEngine::_light_map{ | |||||
{ "L1", 0 }, | |||||
{ "L2", 1 }, | |||||
{ "L3", 2 }, | |||||
{ "L4", 3 }, | |||||
{ "L5", 4 }, | |||||
{ "L6", 5 } | |||||
}; | |||||
const std::map<std::string, int> LibPDEngine::_switchLight_map{ | |||||
{ "S1", 0 }, | |||||
{ "S2", 1 }, | |||||
{ "S3", 2 }, | |||||
{ "S4", 3 }, | |||||
{ "S5", 4 }, | |||||
{ "S6", 5 } | |||||
}; | |||||
const std::map<std::string, int> LibPDEngine::_utility_map{ | |||||
{ "display", 0 } | |||||
}; | |||||
void LibPDEngine::sendKnob(const int idx, const float value){ | |||||
std::string knob = "K"+std::to_string(idx+1); | |||||
libpd_start_message(1); | |||||
libpd_add_float(value); | |||||
libpd_finish_message("fromVCV", knob.c_str()); | |||||
} | |||||
void LibPDEngine::sendSwitch(const int idx, const bool value){ | |||||
std::string sw = "S"+std::to_string(idx+1); | |||||
libpd_start_message(1); | |||||
libpd_add_float(value); | |||||
libpd_finish_message("fromVCV", sw.c_str()); | |||||
} | |||||
void LibPDEngine::sendInitialStates(const ProcessBlock* block){ | |||||
// knobs | |||||
for (int i=0; i<NUM_ROWS; i++){ | |||||
sendKnob(i, block->knobs[i]); | |||||
sendSwitch(i, block->knobs[i]); | |||||
} | |||||
for(int i=0; i<NUM_ROWS; i++){ | |||||
g_lights[i][0] = 0; | |||||
g_lights[i][1] = 0; | |||||
g_lights[i][2] = 0; | |||||
g_switchLights[i][0] = 0; | |||||
g_switchLights[i][1] = 0; | |||||
g_switchLights[i][2] = 0; | |||||
} | |||||
//g_utility[0] = ""; | |||||
//g_utility[1] = ""; | |||||
//g_display_is_valid = false; | |||||
} |