Browse Source

Encode Port::active as channels=0. Change behavior of Port::setChannels().

tags/v1.0.0
Andrew Belt 4 years ago
parent
commit
cb3f136d51
5 changed files with 87 additions and 59 deletions
  1. +0
    -1
      include/engine/Cable.hpp
  2. +23
    -3
      include/engine/Port.hpp
  3. +0
    -21
      src/engine/Cable.cpp
  4. +61
    -31
      src/engine/Engine.cpp
  5. +3
    -3
      src/engine/Port.cpp

+ 0
- 1
include/engine/Cable.hpp View File

@@ -13,7 +13,6 @@ struct Cable {
int outputId;
Module *inputModule = NULL;
int inputId;
void step();
};




+ 23
- 3
include/engine/Port.hpp View File

@@ -23,8 +23,6 @@ struct alignas(32) Port {
May be 0 to PORT_MAX_CHANNELS.
*/
uint8_t channels = 1;
/** Unstable API. Use isConnected() instead. */
bool active = false;
/** For rendering plug lights on cables.
Green for positive, red for negative, and blue for polyphonic.
*/
@@ -79,6 +77,12 @@ struct alignas(32) Port {
}
}

void clearVoltages() {
for (int c = 0; c < channels; c++) {
voltages[c] = 0.f;
}
}

/** Returns the sum of all voltages. */
float getVoltageSum() {
float sum = 0.f;
@@ -90,10 +94,18 @@ struct alignas(32) Port {

/** Sets the number of polyphony channels. */
void setChannels(int channels) {
// If disconnected, keep the number of channels at 0.
if (this->channels == 0) {
return;
}
// Set higher channel voltages to 0
for (int c = channels; c < this->channels; c++) {
voltages[c] = 0.f;
}
// Don't allow caller to set port as disconnected
if (channels == 0) {
channels = 1;
}
this->channels = channels;
}

@@ -105,7 +117,15 @@ struct alignas(32) Port {
You can use this for skipping code that generates output voltages.
*/
bool isConnected() {
return active;
return channels > 0;
}

bool isMonophonic() {
return channels == 1;
}

bool isPolyphonic() {
return channels > 1;
}

void process(float deltaTime);


+ 0
- 21
src/engine/Cable.cpp View File

@@ -1,21 +0,0 @@
#include <engine/Cable.hpp>


namespace rack {
namespace engine {


void Cable::step() {
Output *output = &outputModule->outputs[outputId];
Input *input = &inputModule->inputs[inputId];
// Match number of polyphonic channels to output port
input->channels = output->channels;
// Copy all voltages from output to input
for (int i = 0; i < PORT_MAX_CHANNELS; i++) {
input->voltages[i] = output->voltages[i];
}
}


} // namespace engine
} // namespace rack

+ 61
- 31
src/engine/Engine.cpp View File

@@ -268,6 +268,17 @@ static void Engine_stepModules(Engine *that, int threadId) {
}
}

static void Cable_step(Cable *that) {
Output *output = &that->outputModule->outputs[that->outputId];
Input *input = &that->inputModule->inputs[that->inputId];
// Match number of polyphonic channels to output port
input->channels = output->channels;
// Copy all voltages from output to input
for (int i = 0; i < PORT_MAX_CHANNELS; i++) {
input->voltages[i] = output->voltages[i];
}
}

static void Engine_step(Engine *that) {
Engine::Internal *internal = that->internal;

@@ -292,15 +303,9 @@ static void Engine_step(Engine *that) {
}
}

// Step modules along with workers
internal->workerModuleIndex = 0;
internal->engineBarrier.wait();
Engine_stepModules(that, 0);
internal->workerBarrier.wait();

// Step cables
for (Cable *cable : that->internal->cables) {
cable->step();
Cable_step(cable);
}

// Flip messages for each module
@@ -314,6 +319,12 @@ static void Engine_step(Engine *that) {
module->rightExpander.messageFlipRequested = false;
}
}

// Step modules along with workers
internal->workerModuleIndex = 0;
internal->engineBarrier.wait();
Engine_stepModules(that, 0);
internal->workerBarrier.wait();
}

static void Engine_updateExpander(Engine *that, Module::Expander *expander) {
@@ -569,36 +580,58 @@ void Engine::bypassModule(Module *module, bool bypass) {
assert(module);
VIPLock vipLock(internal->vipMutex);
std::lock_guard<std::recursive_mutex> lock(internal->mutex);
if (bypass) {
for (Output &output : module->outputs) {
// This also zeros all voltages
output.setChannels(0);
}
module->cpuTime = 0.f;
}
else {
// Set all outputs to 1 channel
for (Output &output : module->outputs) {
output.setChannels(1);
}
}
if (module->bypass == bypass)
return;
// Clear outputs and set to 1 channel
for (Output &output : module->outputs) {
// This zeros all voltages, but the channel is set to 1 if connected
output.setChannels(0);
}
module->cpuTime = 0.f;
module->bypass = bypass;
}

static void Port_setDisconnected(Port *that) {
that->channels = 0;
for (int c = 0; c < PORT_MAX_CHANNELS; c++) {
that->voltages[c] = 0.f;
}
}

static void Port_setConnected(Port *that) {
if (that->channels > 0)
return;
that->channels = 1;
}

static void Engine_updateConnected(Engine *that) {
// Set everything to unconnected
// Find disconnected ports
std::set<Port*> disconnectedPorts;
for (Module *module : that->internal->modules) {
for (Input &input : module->inputs) {
input.active = false;
}
for (Output &output : module->outputs) {
output.active = false;
disconnectedPorts.insert(&output);
}
for (Input &input : module->inputs) {
disconnectedPorts.insert(&input);
}
}
// Set inputs/outputs to active
for (Cable *cable : that->internal->cables) {
cable->outputModule->outputs[cable->outputId].active = true;
cable->inputModule->inputs[cable->inputId].active = true;
// Connect output
Output &output = cable->outputModule->outputs[cable->outputId];
auto outputIt = disconnectedPorts.find(&output);
if (outputIt != disconnectedPorts.end())
disconnectedPorts.erase(outputIt);
Port_setConnected(&output);
// Connect input
Input &input = cable->inputModule->inputs[cable->inputId];
auto inputIt = disconnectedPorts.find(&input);
if (inputIt != disconnectedPorts.end())
disconnectedPorts.erase(inputIt);
Port_setConnected(&input);
}
// Disconnect ports that have no cable
for (Port *port : disconnectedPorts) {
Port_setDisconnected(port);
}
}

@@ -641,9 +674,6 @@ void Engine::removeCable(Cable *cable) {
// Check that the cable is already added
auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
assert(it != internal->cables.end());
// Set input to inactive
Input &input = cable->inputModule->inputs[cable->inputId];
input.setChannels(0);
// Remove the cable
internal->cables.erase(it);
Engine_updateConnected(this);


+ 3
- 3
src/engine/Port.cpp View File

@@ -7,12 +7,12 @@ namespace engine {

void Port::process(float deltaTime) {
// Set plug lights
if (!isConnected() || getChannels() == 0) {
if (channels == 0) {
plugLights[0].setBrightness(0.f);
plugLights[1].setBrightness(0.f);
plugLights[2].setBrightness(0.f);
}
else if (getChannels() == 1) {
else if (channels == 1) {
float v = getVoltage() / 10.f;
plugLights[0].setSmoothBrightness(v, deltaTime);
plugLights[1].setSmoothBrightness(-v, deltaTime);
@@ -20,7 +20,7 @@ void Port::process(float deltaTime) {
}
else {
float v2 = 0.f;
for (int c = 0; c < getChannels(); c++) {
for (int c = 0; c < channels; c++) {
v2 += std::pow(getVoltage(c), 2);
}
float v = std::sqrt(v2) / 10.f;


Loading…
Cancel
Save