|
|
@@ -5,6 +5,7 @@ |
|
|
|
#include "LangSource/SCBase.h" |
|
|
|
#include "LangSource/VMGlobals.h" |
|
|
|
#include "LangSource/PyrObject.h" |
|
|
|
#include "LangSource/PyrKernel.h" |
|
|
|
|
|
|
|
#include <thread> |
|
|
|
#include <atomic> |
|
|
@@ -62,10 +63,11 @@ private: |
|
|
|
// converts top of stack back to ProcessBlock data |
|
|
|
void readScProcessBlockResult(ProcessBlock* block) noexcept; |
|
|
|
|
|
|
|
void fail(const std::string& msg) noexcept { |
|
|
|
_engine->display(msg); |
|
|
|
_ok = false; |
|
|
|
} |
|
|
|
void fail(const std::string& msg) noexcept; |
|
|
|
|
|
|
|
template <typename Array> |
|
|
|
bool copyArrayOfFloatArrays(const PyrSlot& inSlot, const char* context, Array& array, int size) noexcept; |
|
|
|
bool copyFloatArray(const PyrSlot& inSlot, const char* context, float* outArray, int size) noexcept; |
|
|
|
|
|
|
|
SuperColliderEngine* _engine; |
|
|
|
bool _ok = true; |
|
|
@@ -226,7 +228,56 @@ std::string SC_VcvPrototypeClient::buildScProcessBlockString(const ProcessBlock* |
|
|
|
} |
|
|
|
|
|
|
|
bool SC_VcvPrototypeClient::isVcvPrototypeProcessBlock(const PyrSlot* slot) const noexcept { |
|
|
|
// TODO |
|
|
|
if (NotObj(slot)) |
|
|
|
return false; |
|
|
|
|
|
|
|
auto* klass = slotRawObject(slot)->classptr; |
|
|
|
auto* klassNameSymbol = slotRawSymbol(&klass->name); |
|
|
|
return klassNameSymbol == getsym("VcvPrototypeProcessBlock"); |
|
|
|
} |
|
|
|
|
|
|
|
template <typename Array> |
|
|
|
bool SC_VcvPrototypeClient::copyArrayOfFloatArrays(const PyrSlot& inSlot, const char* context, Array& outArray, int size) noexcept |
|
|
|
{ |
|
|
|
// OUTPUTS |
|
|
|
if (!isKindOfSlot(const_cast<PyrSlot*>(&inSlot), class_array)) { |
|
|
|
fail(std::string(context) + " must be a Array"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
auto* inObj = slotRawObject(&inSlot); |
|
|
|
if (inObj->size != NUM_ROWS) { |
|
|
|
fail(std::string(context) + " must be of size " + std::to_string(NUM_ROWS)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
const auto subContext = std::string(context) + " subarray"; |
|
|
|
for (int i = 0; i < NUM_ROWS; ++i) { |
|
|
|
if (!copyFloatArray(inObj->slots[i], subContext.c_str(), outArray[i], size)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool SC_VcvPrototypeClient::copyFloatArray(const PyrSlot& inSlot, const char* context, float* outArray, int size) noexcept |
|
|
|
{ |
|
|
|
if (!isKindOfSlot(const_cast<PyrSlot*>(&inSlot), class_floatarray)) { |
|
|
|
fail(std::string(context) + " must be a FloatArray"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
auto* floatArrayObj = slotRawObject(&inSlot); |
|
|
|
if (floatArrayObj->size != size) { |
|
|
|
fail(std::string(context) + " must be of size " + std::to_string(size)); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
auto* floatArray = reinterpret_cast<const PyrFloatArray*>(floatArrayObj); |
|
|
|
auto* rawArray = static_cast<const float*>(floatArray->f); |
|
|
|
for (int i = 0; i < size; ++i) { |
|
|
|
outArray[i] = rawArray[i]; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
@@ -244,72 +295,21 @@ void SC_VcvPrototypeClient::readScProcessBlockResult(ProcessBlock* block) noexce |
|
|
|
constexpr unsigned switchLightsSlotIndex = 8; |
|
|
|
|
|
|
|
PyrObject* object = slotRawObject(resultSlot); |
|
|
|
auto* rawSlots = static_cast<PyrSlot*>(object->slots); |
|
|
|
|
|
|
|
{ |
|
|
|
// OUTPUTS |
|
|
|
PyrSlot* outputsSlot = &object->slots[outputsSlotIndex]; |
|
|
|
// TODO check is array |
|
|
|
// TODO check size |
|
|
|
PyrObject* outputsObj = slotRawObject(outputsSlot); |
|
|
|
for (int i = 0; i < NUM_ROWS; ++i) { |
|
|
|
PyrSlot* floatArraySlot = &outputsObj->slots[i]; |
|
|
|
// TODO check is floatarray |
|
|
|
// TODO check size |
|
|
|
PyrObject* floatArrayObj = slotRawObject(floatArraySlot); |
|
|
|
PyrFloatArray* floatArray = reinterpret_cast<PyrFloatArray*>(floatArrayObj); |
|
|
|
for (int j = 0; j < block->bufferSize; ++j) { |
|
|
|
block->outputs[i][j] = floatArray->f[j]; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
// KNOBS |
|
|
|
PyrSlot* knobsSlot = &object->slots[knobsSlotIndex]; |
|
|
|
// TODO check is floatarray |
|
|
|
// TODO check size |
|
|
|
PyrObject* knobsObj = slotRawObject(knobsSlot); |
|
|
|
PyrFloatArray* floatArray = reinterpret_cast<PyrFloatArray*>(knobsObj); |
|
|
|
for (int i = 0; i < NUM_ROWS; ++i) { |
|
|
|
block->knobs[i] = floatArray->f[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
// LIGHTS |
|
|
|
PyrSlot* lightsSlot = &object->slots[lightsSlotIndex]; |
|
|
|
// TODO check is array |
|
|
|
// TODO check size |
|
|
|
PyrObject* lightsObj = slotRawObject(lightsSlot); |
|
|
|
for (int i = 0; i < NUM_ROWS; ++i) { |
|
|
|
PyrSlot* floatArraySlot = &lightsObj->slots[i]; |
|
|
|
// TODO check is floatarray |
|
|
|
// TODO check size |
|
|
|
PyrObject* floatArrayObj = slotRawObject(floatArraySlot); |
|
|
|
PyrFloatArray* floatArray = reinterpret_cast<PyrFloatArray*>(floatArrayObj); |
|
|
|
block->lights[i][0] = floatArray->f[0]; |
|
|
|
block->lights[i][1] = floatArray->f[1]; |
|
|
|
block->lights[i][2] = floatArray->f[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!copyArrayOfFloatArrays(rawSlots[outputsSlotIndex], "outputs", block->outputs, block->bufferSize)) |
|
|
|
return; |
|
|
|
if (!copyArrayOfFloatArrays(rawSlots[lightsSlotIndex], "lights", block->lights, 3)) |
|
|
|
return; |
|
|
|
if (!copyArrayOfFloatArrays(rawSlots[switchLightsSlotIndex], "switchLights", block->switchLights, 3)) |
|
|
|
return; |
|
|
|
if (!copyFloatArray(rawSlots[knobsSlotIndex], "knobs", block->knobs, NUM_ROWS)) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
// SWITCH LIGHTS |
|
|
|
PyrSlot* switchLightsSlot = &object->slots[switchLightsSlotIndex]; |
|
|
|
// TODO check is array |
|
|
|
// TODO check size |
|
|
|
PyrObject* switchLightsObj = slotRawObject(switchLightsSlot); |
|
|
|
for (int i = 0; i < NUM_ROWS; ++i) { |
|
|
|
PyrSlot* floatArraySlot = &switchLightsObj->slots[i]; |
|
|
|
// TODO check is floatarray |
|
|
|
// TODO check size |
|
|
|
PyrObject* floatArrayObj = slotRawObject(floatArraySlot); |
|
|
|
PyrFloatArray* floatArray = reinterpret_cast<PyrFloatArray*>(floatArrayObj); |
|
|
|
block->switchLights[i][0] = floatArray->f[0]; |
|
|
|
block->switchLights[i][1] = floatArray->f[1]; |
|
|
|
block->switchLights[i][2] = floatArray->f[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
void SC_VcvPrototypeClient::fail(const std::string& msg) noexcept { |
|
|
|
_engine->display(msg); |
|
|
|
_ok = false; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO test code |
|
|
|