Browse Source

Add polyphony to ports and wires

tags/v1.0.0
Andrew Belt 6 years ago
parent
commit
f40d3343fb
5 changed files with 63 additions and 26 deletions
  1. +4
    -10
      include/engine/Input.hpp
  2. +2
    -7
      include/engine/Output.hpp
  3. +34
    -0
      include/engine/Port.hpp
  4. +15
    -6
      src/app/WireWidget.cpp
  5. +8
    -3
      src/engine/Wire.cpp

+ 4
- 10
include/engine/Input.hpp View File

@@ -1,21 +1,15 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "engine/Light.hpp"
#include "engine/Port.hpp"




namespace rack { namespace rack {




struct Input {
/** Voltage of the port, zero if not plugged in. Read-only by Module */
float value = 0.f;
/** Whether a wire is plugged in */
bool active = false;
Light plugLights[2];

struct Input : Port {
/** Returns the value if a wire is plugged in, otherwise returns the given default value */ /** Returns the value if a wire is plugged in, otherwise returns the given default value */
float normalize(float normalValue) {
return active ? value : normalValue;
float normalize(float normalValue, int index = 0) {
return active ? getValue(index) : normalValue;
} }
}; };




+ 2
- 7
include/engine/Output.hpp View File

@@ -1,17 +1,12 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "engine/Light.hpp"
#include "engine/Port.hpp"




namespace rack { namespace rack {




struct Output {
/** Voltage of the port. Write-only by Module */
float value = 0.f;
/** Whether a wire is plugged in */
bool active = false;
Light plugLights[2];
struct Output : Port {
}; };






+ 34
- 0
include/engine/Port.hpp View File

@@ -0,0 +1,34 @@
#pragma once
#include "common.hpp"
#include "engine/Light.hpp"


namespace rack {


static const int PORT_MAX_CHANNELS = 16;


struct Port {
/** Voltage of the port */
union {
float value;
float values[PORT_MAX_CHANNELS];
};
/** Number of polyphonic channels */
int numChannels = 1;
/** Whether a wire is plugged in */
bool active = false;
Light plugLights[2];

float getValue(int index = 0) {
return values[index];
}

void setValue(float value, int index = 0) {
this->values[index] = value;
}
};


} // namespace rack

+ 15
- 6
src/app/WireWidget.cpp View File

@@ -31,14 +31,15 @@ static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) {
nvgFill(vg); nvgFill(vg);
} }


static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float tension, float opacity) {
static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float width, float tension, float opacity) {
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10);
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);


// Wire // Wire
if (opacity > 0.0) { if (opacity > 0.0) {
nvgSave(vg); nvgSave(vg);
nvgGlobalAlpha(vg, powf(opacity, 1.5));
// This power scaling looks more linear than actual linear scaling
nvgGlobalAlpha(vg, std::pow(opacity, 1.5));


float dist = pos1.minus(pos2).norm(); float dist = pos1.minus(pos2).norm();
math::Vec slump; math::Vec slump;
@@ -53,7 +54,7 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co
nvgMoveTo(vg, pos1.x, pos1.y); nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y);
nvgStrokeColor(vg, colorShadow); nvgStrokeColor(vg, colorShadow);
nvgStrokeWidth(vg, 5);
nvgStrokeWidth(vg, width);
nvgStroke(vg); nvgStroke(vg);


// Wire outline // Wire outline
@@ -61,12 +62,12 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co
nvgMoveTo(vg, pos1.x, pos1.y); nvgMoveTo(vg, pos1.x, pos1.y);
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y);
nvgStrokeColor(vg, colorOutline); nvgStrokeColor(vg, colorOutline);
nvgStrokeWidth(vg, 5);
nvgStrokeWidth(vg, width);
nvgStroke(vg); nvgStroke(vg);


// Wire solid // Wire solid
nvgStrokeColor(vg, color); nvgStrokeColor(vg, color);
nvgStrokeWidth(vg, 3);
nvgStrokeWidth(vg, width - 2);
nvgStroke(vg); nvgStroke(vg);


nvgRestore(vg); nvgRestore(vg);
@@ -178,9 +179,17 @@ void WireWidget::draw(NVGcontext *vg) {
opacity = 1.0; opacity = 1.0;
} }


float width = 5;
if (wire && wire->outputModule) {
Output *output = &wire->outputModule->outputs[wire->outputId];
if (output->numChannels != 1) {
width = 8;
}
}

math::Vec outputPos = getOutputPos(); math::Vec outputPos = getOutputPos();
math::Vec inputPos = getInputPos(); math::Vec inputPos = getInputPos();
drawWire(vg, outputPos, inputPos, color, tension, opacity);
drawWire(vg, outputPos, inputPos, color, width, tension, opacity);
} }


void WireWidget::drawPlugs(NVGcontext *vg) { void WireWidget::drawPlugs(NVGcontext *vg) {


+ 8
- 3
src/engine/Wire.cpp View File

@@ -5,9 +5,14 @@ namespace rack {




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






Loading…
Cancel
Save