| @@ -4,6 +4,7 @@ | |||
| #include "LangSource/SC_LanguageConfig.hpp" | |||
| #include "LangSource/SCBase.h" | |||
| #include "LangSource/VMGlobals.h" | |||
| #include "LangSource/PyrObject.h" | |||
| #include <thread> | |||
| #include <atomic> | |||
| @@ -52,6 +53,10 @@ public: | |||
| private: | |||
| std::string buildScProcessBlockString(const ProcessBlock* block) const noexcept; | |||
| int getResultAsInt(const char* text) noexcept; | |||
| bool isVcvPrototypeProcessBlock(const PyrSlot* slot) const noexcept; | |||
| // converts top of stack back to ProcessBlock data | |||
| void readScProcessBlockResult(ProcessBlock* block) noexcept; | |||
| SuperColliderEngine* _engine; | |||
| bool _ok = true; | |||
| @@ -151,6 +156,7 @@ std::string SC_VcvPrototypeClient::buildScProcessBlockString(const ProcessBlock* | |||
| std::ostringstream builder; | |||
| // TODO so expensive | |||
| builder << std::fixed; // to ensure floats aren't actually treated as Integers | |||
| builder << "^~vcv_process.value(VcvPrototypeProcessBlock.new(" | |||
| << block->sampleRate << ',' | |||
| << block->sampleTime << ',' | |||
| @@ -214,6 +220,92 @@ std::string SC_VcvPrototypeClient::buildScProcessBlockString(const ProcessBlock* | |||
| return builder.str(); | |||
| } | |||
| bool SC_VcvPrototypeClient::isVcvPrototypeProcessBlock(const PyrSlot* slot) const noexcept { | |||
| // TODO | |||
| return true; | |||
| } | |||
| void SC_VcvPrototypeClient::readScProcessBlockResult(ProcessBlock* block) noexcept { | |||
| auto* resultSlot = &scGlobals()->result; | |||
| if (!isVcvPrototypeProcessBlock(resultSlot)) { | |||
| FAIL("Result of ~vcv_process must be an instance of VcvPrototypeProcessBlock"); | |||
| return; | |||
| } | |||
| constexpr unsigned outputsSlotIndex = 4; | |||
| constexpr unsigned knobsSlotIndex = 5; | |||
| constexpr unsigned lightsSlotIndex = 7; | |||
| constexpr unsigned switchLightsSlotIndex = 8; | |||
| PyrObject* object = slotRawObject(resultSlot); | |||
| { | |||
| // 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]; | |||
| } | |||
| } | |||
| { | |||
| // 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]; | |||
| } | |||
| } | |||
| } | |||
| // TODO test code | |||
| static long long int gmax = 0; | |||
| @@ -222,6 +314,7 @@ void SC_VcvPrototypeClient::evaluateProcessBlock(ProcessBlock* block) noexcept { | |||
| auto start = std::chrono::high_resolution_clock::now(); | |||
| auto&& string = buildScProcessBlockString(block); | |||
| interpret(string.c_str()); | |||
| readScProcessBlockResult(block); | |||
| auto end = std::chrono::high_resolution_clock::now(); | |||
| auto ticks = (end - start).count(); | |||
| if (gmax < ticks) | |||