Skip to content

Commit

Permalink
Output processors: allow overlay models for all except Fold
Browse files Browse the repository at this point in the history
  • Loading branch information
darylc committed Feb 22, 2025
1 parent a7a88ea commit 2fe5c51
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 63 deletions.
31 changes: 3 additions & 28 deletions src/channeloutput/processors/BrightnessOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "../../log.h"

#include "BrightnessOutputProcessor.h"
#include "OutputProcessor.h"

BrightnessOutputProcessor::BrightnessOutputProcessor(const Json::Value& config) {
description = config["desription"].asString();
Expand All @@ -35,33 +36,10 @@ BrightnessOutputProcessor::BrightnessOutputProcessor(const Json::Value& config)
brightness = config["brightness"].asInt();
gamma = config["gamma"].asFloat();

if (config.isMember("model")) {
model = config["model"].asString();
if (model != "<Use Start Channel>") {
auto m_model = PixelOverlayManager::INSTANCE.getModel(model);
if (!m_model) {
LogErr(VB_CHANNELOUT, "Invalid Pixel Overlay Model: '%s'\n", model.c_str());
} else {
int m_channel = m_model->getChannelCount();
LogDebug(VB_CHANNELOUT, "Before Model applied Brightness: %d-%d => Brightness:%d Gamma: %f Model: %s model\n",
start, start + count - 1,
brightness, gamma, model.c_str(),m_channel);
int offset = start;
start = m_model->getStartChannel() + start + 1;
if (count > m_channel) {
count = m_channel - offset;
LogWarn(VB_CHANNELOUT, "Output processor tried to go past end channel of model. Restricting to %d channels\n", count);
} else if (count < m_channel) {
LogInfo(VB_CHANNELOUT, "Output processor tried to use less channels (%d) than overlay model has (%d). This may be intentional\n",count, m_channel);
}
}
}
} else {
model = "";
}
ProcessModelConfig(config, model, start, count);

LogInfo(VB_CHANNELOUT, "Brightness: %d-%d => Brightness:%d Gamma: %f Model: %s\n",
start, start + count - 1,
start + 1, start + count,
brightness, gamma, model.c_str());

float bf = brightness;
Expand All @@ -77,9 +55,6 @@ BrightnessOutputProcessor::BrightnessOutputProcessor(const Json::Value& config)
}
table[x] = round(f);
}

// channel numbers need to be 0 based
--start;
}

BrightnessOutputProcessor::~BrightnessOutputProcessor() {
Expand Down
9 changes: 4 additions & 5 deletions src/channeloutput/processors/ColorOrderOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ ColorOrderOutputProcessor::ColorOrderOutputProcessor(const Json::Value& config)
start = config["start"].asInt();
count = config["count"].asInt();
order = config["colorOrder"].asInt();
LogInfo(VB_CHANNELOUT, "Color Order: %d-%d => %d\n",
start, start + (count * 3) - 1,
order);
ProcessModelConfig(config, model, start, count);

//channel numbers need to be 0 based
--start;
LogInfo(VB_CHANNELOUT, "Color Order: %d-%d => %d, Model: %s\n",
start + 1, start + (count * 3),
order, model.c_str());
}

ColorOrderOutputProcessor::~ColorOrderOutputProcessor() {
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/ColorOrderOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ class ColorOrderOutputProcessor : public OutputProcessor {
int start;
int count;
int order;
std::string model;
};
7 changes: 3 additions & 4 deletions src/channeloutput/processors/HoldValueOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ HoldValueOutputProcessor::HoldValueOutputProcessor(const Json::Value& config) {
active = config["active"].asInt() ? true : false;
start = config["start"].asInt();
count = config["count"].asInt();
LogInfo(VB_CHANNELOUT, "Hold Channel Values: %d-%d\n",
start, start + count - 1);
ProcessModelConfig(config, model, start, count);

// channel numbers need to be 0 based
--start;
LogInfo(VB_CHANNELOUT, "Hold Channel Values: %d-%d, Model: %S\n",
start + 1, start + count, model.c_str());

lastValues = new unsigned char[count];
}
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/HoldValueOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ class HoldValueOutputProcessor : public OutputProcessor {
int start;
int count;
unsigned char* lastValues;
std::string model;
};
33 changes: 33 additions & 0 deletions src/channeloutput/processors/OutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "RemapOutputProcessor.h"
#include "SetValueOutputProcessor.h"
#include "ThreeToFourOutputProcessor.h"
#include "../../overlays/PixelOverlay.h"
#include "../../overlays/PixelOverlayModel.h"

OutputProcessors::OutputProcessors() {
}
Expand Down Expand Up @@ -132,3 +134,34 @@ OutputProcessor::OutputProcessor() :

OutputProcessor::~OutputProcessor() {
}

void ProcessModelConfig(const Json::Value& config, std::string& model, int& start, int& count) {
if (config.isMember("model")) {
model = config["model"].asString();
if (model != "<Use Start Channel>") {
auto m_model = PixelOverlayManager::INSTANCE.getModel(model);
if (!m_model) {
LogErr(VB_CHANNELOUT, "Invalid Pixel Overlay Model: '%s'\n", model.c_str());
} else {
int m_channel = m_model->getChannelCount();
LogDebug(VB_CHANNELOUT, "Before Model applied: %d-%d => Model: %s model\n",
start, start + count - 1,
model.c_str(), m_channel);

int offset = start;
start = m_model->getStartChannel() + start - 1;

if (count > m_channel) {
count = m_channel - offset;
LogWarn(VB_CHANNELOUT, "Output processor for Model: %s tried to go past end channel of model. Restricting to %d channels\n", model.c_str(), count);
} else if (count < m_channel) {
LogInfo(VB_CHANNELOUT, "Output processor for Model: %s is using less channels (%d) than overlay model has (%d). This may be intentional\n",
model.c_str(), count, m_channel);
}
}
}
} else {
model = "";
--start;
}
}
2 changes: 2 additions & 0 deletions src/channeloutput/processors/OutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ class OutputProcessors {
mutable std::mutex processorsLock;
std::list<OutputProcessor*> processors;
};

void ProcessModelConfig(const Json::Value& config, std::string& model, int& start, int& count);
8 changes: 3 additions & 5 deletions src/channeloutput/processors/OverrideZeroOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ OverrideZeroOutputProcessor::OverrideZeroOutputProcessor(const Json::Value& conf
start = config["start"].asInt();
count = config["count"].asInt();
value = config["value"].asInt();
LogInfo(VB_CHANNELOUT, "Override Zero Channel Range: %d-%d Value: %d\n",
start, start + count - 1, value);

//channel numbers need to be 0 based
--start;
ProcessModelConfig(config, model, start, count);
LogInfo(VB_CHANNELOUT, "Override Zero Channel Range: %d-%d Value: %d, Model: %s\n",
start + 1, start + count, value, model.c_str());
}

OverrideZeroOutputProcessor::~OverrideZeroOutputProcessor() {
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/OverrideZeroOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ class OverrideZeroOutputProcessor : public OutputProcessor {
int start;
int count;
unsigned char value;
std::string model;
};
7 changes: 5 additions & 2 deletions src/channeloutput/processors/RemapOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "../../log.h"

#include "RemapOutputProcessor.h"
#include "OutputProcessor.h"

RemapOutputProcessor::RemapOutputProcessor(const Json::Value& config) {
description = config["desription"].asString();
Expand All @@ -24,13 +25,15 @@ RemapOutputProcessor::RemapOutputProcessor(const Json::Value& config) {
count = config["count"].asInt();
loops = config["loops"].asInt();
reverse = config["reverse"].asInt();

ProcessModelConfig(config, model, sourceChannel, count);

LogInfo(VB_CHANNELOUT, "Remapped Channels: %d-%d => %d-%d (%d total channels copied in %d loop(s))\n",
sourceChannel, sourceChannel + count - 1,
sourceChannel + 1, sourceChannel + count,
destChannel, destChannel + (count * loops) - 1, (count * loops), loops);

// channel numbers need to be 0 based
--destChannel;
--sourceChannel;
}

RemapOutputProcessor::RemapOutputProcessor(int src, int dst, int c, int l, int r) {
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/RemapOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ class RemapOutputProcessor : public OutputProcessor {
int count;
int loops;
int reverse;
std::string model;
};
10 changes: 4 additions & 6 deletions src/channeloutput/processors/SetValueOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ SetValueOutputProcessor::SetValueOutputProcessor(const Json::Value& config) {
start = config["start"].asInt();
count = config["count"].asInt();
value = config["value"].asInt();
LogInfo(VB_CHANNELOUT, "Set Channel Value: %d-%d => %d\n",
start, start + count - 1,
value);

//channel numbers need to be 0 based
--start;
ProcessModelConfig(config, model, start, count);
LogInfo(VB_CHANNELOUT, "Set Channel Value: %d-%d => %d, Model: %s\n",
start + 1, start + count,
value, model.c_str());
}

SetValueOutputProcessor::~SetValueOutputProcessor() {
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/SetValueOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ class SetValueOutputProcessor : public OutputProcessor {
int start;
int count;
int value;
std::string model;
};
6 changes: 4 additions & 2 deletions src/channeloutput/processors/ThreeToFourOutputProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ ThreeToFourOutputProcessor::ThreeToFourOutputProcessor(const Json::Value& config

order = config["colorOrder"].asInt();
algorithm = config["algorithm"].asInt();
ProcessModelConfig(config, model, start, count);

//channel numbers need to be 0 based
--start;
LogInfo(VB_CHANNELOUT, "ThreeToFour: %d-%d, Model: %s\n",
start + 1, start + count,
model.c_str());
}

ThreeToFourOutputProcessor::~ThreeToFourOutputProcessor() {
Expand Down
1 change: 1 addition & 0 deletions src/channeloutput/processors/ThreeToFourOutputProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ class ThreeToFourOutputProcessor : public OutputProcessor {
int count;
int order;
int algorithm;
std::string model;
};
38 changes: 27 additions & 11 deletions www/outputprocessors.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,20 @@ function outputOption(val, def) {
function HTMLForOutputProcessorConfig(output, models) {
var html = "";
var type = output.type;
if (type != "Fold") {
html += "Model: <select class='model'>";
models.forEach(function(model) {
html += "<option value='" + model + "'";
if (output.model === model) {
html += " selected";
}
html += ">" + model + "</option>";
});
html += "</select>&nbsp;";
}

if (type == "Remap") {
html += "Source Channel: <input class='source' type=text size='7' maxlength='7' value='" + output.source + "'/>&nbsp;"
html += "Start Channel: <input class='source' type=text size='7' maxlength='7' value='" + output.source + "'/>&nbsp;"
+ "Destination: <input class='destination' type=text size='7' maxlength='7' value='" + output.destination + "'/>&nbsp;"
+ "Count: <input class='count' type=text size='7' maxlength='7' value='" + output.count + "' />&nbsp;"
+ "Loops: <input class='loops' type=text size='7' maxlength='7' value='" + output.loops + "'/>&nbsp;"
Expand All @@ -42,15 +53,6 @@ function HTMLForOutputProcessorConfig(output, models) {
html += ">RGBW Pixels</option>";
html += "</select>";
} else if (type == "Brightness") {
html += "Model: <select class='model'>";
models.forEach(function(model) {
html += "<option value='" + model + "'";
if (output.model === model) {
html += " selected";
}
html += ">" + model + "</option>";
});
html += "</select>&nbsp;";
html += "Start Channel: <input class='start' type=text size='7' maxlength='7' value='" + output.start + "'/>&nbsp;"
+ "Channel Count: <input class='count' type=text size='7' maxlength='7' value='" + output.count + "'/>&nbsp;"
+ "Brightness: <input class='brightness' type=number value='" + output.brightness + "' min='0' max='100'/>"
Expand Down Expand Up @@ -89,7 +91,7 @@ function HTMLForOutputProcessorConfig(output, models) {
+ "Channel Count: <input class='count' type=text size='7' maxlength='7' value='" + output.count + "'/>&nbsp;"
+ "Value: <input class='value' type=number value='" + output.value + "' min='0' max='255'/>";
} else if (type == "Fold") {
html += "Source Channel: <input class='source' type=text size='7' maxlength='7' value='" + output.source + "'/>&nbsp;"
html += "Start Channel: <input class='source' type=text size='7' maxlength='7' value='" + output.source + "'/>&nbsp;"
+ "Count: <input class='count' type=text size='7' maxlength='7' value='" + output.count + "' />&nbsp;"
+ "Node: <select class='node'>";
html += "<option value='0' ";
Expand Down Expand Up @@ -165,6 +167,7 @@ function SetOutputProcessors() {
type: "Remap",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
source: parseInt($this.find("input.source").val()),
destination: parseInt($this.find("input.destination").val()),
count: parseInt($this.find("input.count").val()),
Expand Down Expand Up @@ -205,6 +208,7 @@ function SetOutputProcessors() {
type: "Set Value",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
start: parseInt($this.find("input.start").val()),
count: parseInt($this.find("input.count").val()),
value: parseInt($this.find("input.value").val())
Expand All @@ -222,6 +226,7 @@ function SetOutputProcessors() {
type: "Hold Value",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
start: parseInt($this.find("input.start").val()),
count: parseInt($this.find("input.count").val()),
};
Expand All @@ -238,6 +243,7 @@ function SetOutputProcessors() {
type: "Reorder Colors",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
start: parseInt($this.find("input.start").val()),
count: parseInt($this.find("input.count").val()),
colorOrder: parseInt($this.find("select.colorOrder").val())
Expand All @@ -255,6 +261,7 @@ function SetOutputProcessors() {
type: "Three to Four",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
start: parseInt($this.find("input.start").val()),
count: parseInt($this.find("input.count").val()),
colorOrder: parseInt($this.find("select.colorOrder").val()),
Expand All @@ -274,6 +281,7 @@ function SetOutputProcessors() {
type: "Override Zero",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
start: parseInt($this.find("input.start").val()),
count: parseInt($this.find("input.count").val()),
value: parseInt($this.find("input.value").val())
Expand All @@ -291,6 +299,7 @@ function SetOutputProcessors() {
type: "Fold",
active: $this.find("input.active").is(':checked') ? 1 : 0,
description: $this.find("input.description").val(),
model: $this.find("select.model").val(),
source: parseInt($this.find("input.source").val()),
count: parseInt($this.find("input.count").val()),
node: parseInt($this.find("select.node").val())
Expand Down Expand Up @@ -522,6 +531,13 @@ function DeleteSelectedProcessor() {
<div class="row tablePageHeader">
<div class="col-md">
<h2>Output Processors</h2>
When applying an output process to a Model:
<br>
- Start channel is an offset from the Model start channel. Eg Start Channel 1 means use the first channel of the model.
<br>
- Count or Nodes can be set to use the x channels/nodes from the model, rather than all of the channels/nodes in a model.
<br>
<br>
</div>
<div class="col-md-auto ms-lg-auto">
<div class="form-actions">
Expand Down

0 comments on commit 2fe5c51

Please sign in to comment.