common ledbuffer for color transform (#77)

* common ledbuffer for color transform

hyperion class uses a common buffer for all operations on ledColors got from muxer
all color transforms uses new ledBuffer instead of making copies of ledbuffer

other fixes:
fix compile bug in profiler
update doxygen config

* migrate logging for color transform classes

* prepare new logger in hyperion class

* implement hwledcount

* Update Hyperion.cpp

Fix off color

* remove ledscount equivalent from apa102
migrate logging in hyperion.cpp
remove unused and duuplicate colorcorrection - but same is available through tempertature

* remove colorcorrection completly
fix compile

* set colororder back to static

* in remote: using correction is the same as using temperature - correction is obsolete, command not delete atm for compat reasons
This commit is contained in:
redPanther 2016-07-01 23:20:41 +02:00 committed by brindosch
parent 9101d7f604
commit 36b4d072c5
16 changed files with 1728 additions and 1017 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@
// hyperion-utils includes // hyperion-utils includes
#include <utils/Image.h> #include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/Logger.h>
// Hyperion includes // Hyperion includes
#include <hyperion/LedString.h> #include <hyperion/LedString.h>
@ -33,7 +35,6 @@ class RgbChannelCorrection;
class RgbChannelAdjustment; class RgbChannelAdjustment;
class MultiColorTransform; class MultiColorTransform;
class MultiColorCorrection; class MultiColorCorrection;
class MultiColorTemperature;
class MultiColorAdjustment; class MultiColorAdjustment;
/// ///
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
@ -138,12 +139,6 @@ public slots:
/// ///
const std::vector<std::string> & getTransformIds() const; const std::vector<std::string> & getTransformIds() const;
///
/// Returns the list with unique correction identifiers
/// @return The list with correction identifiers
///
const std::vector<std::string> & getCorrectionIds() const;
/// ///
/// Returns the list with unique correction identifiers /// Returns the list with unique correction identifiers
/// @return The list with correction identifiers /// @return The list with correction identifiers
@ -162,12 +157,6 @@ public slots:
/// ///
ColorTransform * getTransform(const std::string& id); ColorTransform * getTransform(const std::string& id);
///
/// Returns the ColorCorrection with the given identifier
/// @return The correction with the given identifier (or nullptr if the identifier does not exist)
///
ColorCorrection * getCorrection(const std::string& id);
/// ///
/// Returns the ColorCorrection with the given identifier /// Returns the ColorCorrection with the given identifier
/// @return The correction with the given identifier (or nullptr if the identifier does not exist) /// @return The correction with the given identifier (or nullptr if the identifier does not exist)
@ -238,7 +227,6 @@ public:
static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder); static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder);
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig); static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
static MultiColorCorrection * createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorCorrectionConfig);
static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig); static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig);
static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorAdjustmentConfig); static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorAdjustmentConfig);
static ColorTransform * createColorTransform(const Json::Value & transformConfig); static ColorTransform * createColorTransform(const Json::Value & transformConfig);
@ -287,9 +275,6 @@ private:
/// The transformation from raw colors to led colors /// The transformation from raw colors to led colors
MultiColorTransform * _raw2ledTransform; MultiColorTransform * _raw2ledTransform;
/// The correction from raw colors to led colors
MultiColorCorrection * _raw2ledCorrection;
/// The temperature from raw colors to led colors /// The temperature from raw colors to led colors
MultiColorCorrection * _raw2ledTemperature; MultiColorCorrection * _raw2ledTemperature;
@ -313,4 +298,13 @@ private:
/// The timer for handling priority channel timeouts /// The timer for handling priority channel timeouts
QTimer _timer; QTimer _timer;
/// buffer for leds
std::vector<ColorRgb> _ledBuffer;
/// Logger instance
Logger * _log;
/// count of hardware leds
unsigned _hwLedCount;
}; };

View File

@ -1,9 +1,10 @@
#include "utils/Logger.h"
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>
#include <map> #include <map>
#include <utils/Logger.h>
#include <HyperionConfig.h>
#ifndef ENABLE_PROFILER #ifndef ENABLE_PROFILER
#error "Profiler is not for productive code, enable it via cmake or remove header include" #error "Profiler is not for productive code, enable it via cmake or remove header include"

View File

@ -2,6 +2,7 @@
// STL includes // STL includes
#include <cassert> #include <cassert>
#include <exception> #include <exception>
#include <sstream>
// QT includes // QT includes
#include <QDateTime> #include <QDateTime>
@ -53,41 +54,29 @@ Hyperion* Hyperion::getInstance()
ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig) ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
{ {
// deprecated: force BGR when the deprecated flag is present and set to true
if (deviceConfig.get("bgr-output", false).asBool())
{
return ORDER_BGR;
}
std::string order = deviceConfig.get("colorOrder", "rgb").asString(); std::string order = deviceConfig.get("colorOrder", "rgb").asString();
if (order == "rgb") if (order == "bgr")
{
return ORDER_RGB;
}
else if (order == "bgr")
{ {
return ORDER_BGR; return ORDER_BGR;
} }
else if (order == "rbg") if (order == "rbg")
{ {
return ORDER_RBG; return ORDER_RBG;
} }
else if (order == "brg") if (order == "brg")
{ {
return ORDER_BRG; return ORDER_BRG;
} }
else if (order == "gbr") if (order == "gbr")
{ {
return ORDER_GBR; return ORDER_GBR;
} }
else if (order == "grb") if (order == "grb")
{ {
return ORDER_GRB; return ORDER_GRB;
} }
else
{ WarningIf( order != "rgb", Logger::getInstance("Core"), "Unknown color order defined (%s). Using RGB.", order.c_str());
std::cout << "HYPERION ERROR: Unknown color order defined (" << order << "). Using RGB." << std::endl;
}
return ORDER_RGB; return ORDER_RGB;
} }
@ -167,6 +156,7 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
{ {
// Create the result, the transforms are added to this // Create the result, the transforms are added to this
MultiColorTransform * transform = new MultiColorTransform(ledCnt); MultiColorTransform * transform = new MultiColorTransform(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue); const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue);
if (transformConfig.isNull()) if (transformConfig.isNull())
@ -197,18 +187,17 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
{ {
// Special case for indices '*' => all leds // Special case for indices '*' => all leds
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1); transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; Info(log, "ColorTransform '%s' => [0; %d]", colorTransform->_id.c_str(), ledCnt-1);
continue; continue;
} }
if (!overallExp.exactMatch(ledIndicesStr)) if (!overallExp.exactMatch(ledIndicesStr))
{ {
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue; continue;
} }
std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => ["; std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(","); const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) { for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0) if (i > 0)
@ -231,92 +220,20 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
std::cout << index; std::cout << index;
} }
} }
std::cout << "]" << std::endl; Info(log, "ColorTransform '%s' => [%s]", colorTransform->_id.c_str(), ss.str().c_str());
} }
} }
return transform; return transform;
} }
MultiColorCorrection * Hyperion::createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorConfig)
{
// Create the result, the corrections are added to this
MultiColorCorrection * correction = new MultiColorCorrection(ledCnt);
const Json::Value correctionConfig = colorConfig.get("correction", Json::nullValue);
if (correctionConfig.isNull())
{
// Old style color correction config (just one for all leds)
ColorCorrection * colorCorrection = createColorCorrection(colorConfig);
correction->addCorrection(colorCorrection);
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
}
else if (!correctionConfig.isArray())
{
ColorCorrection * colorCorrection = createColorCorrection(correctionConfig);
correction->addCorrection(colorCorrection);
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
}
else
{
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
for (Json::UInt i = 0; i < correctionConfig.size(); ++i)
{
const Json::Value & config = correctionConfig[i];
ColorCorrection * colorCorrection = createColorCorrection(config);
correction->addCorrection(colorCorrection);
const QString ledIndicesStr = QString(config.get("leds", "").asCString()).trimmed();
if (ledIndicesStr.compare("*") == 0)
{
// Special case for indices '*' => all leds
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
continue;
}
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [";
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
std::cout << ", ";
}
if (ledIndexList[i].contains("-"))
{
QStringList ledIndices = ledIndexList[i].split("-");
int startInd = ledIndices[0].toInt();
int endInd = ledIndices[1].toInt();
correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd);
std::cout << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
correction->setCorrectionForLed(colorCorrection->_id, index, index);
std::cout << index;
}
}
std::cout << "]" << std::endl;
}
}
return correction;
}
MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorConfig) MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorConfig)
{ {
// Create the result, the corrections are added to this // Create the result, the corrections are added to this
MultiColorCorrection * correction = new MultiColorCorrection(ledCnt); MultiColorCorrection * correction = new MultiColorCorrection(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value correctionConfig = colorConfig.get("temperature", Json::nullValue); const std::string jsonKey = colorConfig.isMember("temperature") ? "temperature" : "correction";
const Json::Value correctionConfig = colorConfig.get(jsonKey, Json::nullValue);
if (correctionConfig.isNull()) if (correctionConfig.isNull())
{ {
// Old style color correction config (just one for all leds) // Old style color correction config (just one for all leds)
@ -345,23 +262,22 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
{ {
// Special case for indices '*' => all leds // Special case for indices '*' => all leds
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1); correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; Info(log, "ColorTemperature '%s' => [0; %d]", colorCorrection->_id.c_str(), ledCnt-1);
continue; continue;
} }
if (!overallExp.exactMatch(ledIndicesStr)) if (!overallExp.exactMatch(ledIndicesStr))
{ {
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue; continue;
} }
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => ["; std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(","); const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) { for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0) if (i > 0)
{ {
std::cout << ", "; ss << ", ";
} }
if (ledIndexList[i].contains("-")) if (ledIndexList[i].contains("-"))
{ {
@ -370,25 +286,27 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
int endInd = ledIndices[1].toInt(); int endInd = ledIndices[1].toInt();
correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd); correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd);
std::cout << startInd << "-" << endInd; ss << startInd << "-" << endInd;
} }
else else
{ {
int index = ledIndexList[i].toInt(); int index = ledIndexList[i].toInt();
correction->setCorrectionForLed(colorCorrection->_id, index, index); correction->setCorrectionForLed(colorCorrection->_id, index, index);
std::cout << index; ss << index;
} }
} }
std::cout << "]" << std::endl; Info(log, "ColorTemperature '%s' => [%s]", colorCorrection->_id.c_str(), ss.str().c_str());
} }
} }
return correction; return correction;
} }
MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorConfig) MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorConfig)
{ {
// Create the result, the transforms are added to this // Create the result, the transforms are added to this
MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt); MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value adjustmentConfig = colorConfig.get("channelAdjustment", Json::nullValue); const Json::Value adjustmentConfig = colorConfig.get("channelAdjustment", Json::nullValue);
if (adjustmentConfig.isNull()) if (adjustmentConfig.isNull())
@ -419,23 +337,22 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
{ {
// Special case for indices '*' => all leds // Special case for indices '*' => all leds
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1); adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; Info(log, "ColorAdjustment '%s' => [0; %d]", colorAdjustment->_id.c_str(), ledCnt-1);
continue; continue;
} }
if (!overallExp.exactMatch(ledIndicesStr)) if (!overallExp.exactMatch(ledIndicesStr))
{ {
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue; continue;
} }
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => ["; std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(","); const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) { for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0) if (i > 0)
{ {
std::cout << ", "; ss << ", ";
} }
if (ledIndexList[i].contains("-")) if (ledIndexList[i].contains("-"))
{ {
@ -444,16 +361,16 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
int endInd = ledIndices[1].toInt(); int endInd = ledIndices[1].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd); adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
std::cout << startInd << "-" << endInd; ss << startInd << "-" << endInd;
} }
else else
{ {
int index = ledIndexList[i].toInt(); int index = ledIndexList[i].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index); adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
std::cout << index; ss << index;
} }
} }
std::cout << "]" << std::endl; Info(log, "ColorAdjustment '%s' => [%s]", colorAdjustment->_id.c_str(), ss.str().c_str());
} }
} }
return adjustment; return adjustment;
@ -611,7 +528,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde
{ {
for (const Json::Value& addr : forwarderConfig["json"]) for (const Json::Value& addr : forwarderConfig["json"])
{ {
std::cout << "HYPERION INFO: Json forward to " << addr.asString() << std::endl; Info(Logger::getInstance("Core"), "Json forward to %s", addr.asString().c_str());
forwarder->addJsonSlave(addr.asString()); forwarder->addJsonSlave(addr.asString());
} }
} }
@ -620,7 +537,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde
{ {
for (const Json::Value& addr : forwarderConfig["proto"]) for (const Json::Value& addr : forwarderConfig["proto"])
{ {
std::cout << "HYPERION INFO: Proto forward to " << addr.asString() << std::endl; Info(Logger::getInstance("Core"), "Proto forward to %s", addr.asString().c_str());
forwarder->addProtoSlave(addr.asString()); forwarder->addProtoSlave(addr.asString());
} }
} }
@ -638,7 +555,6 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))), _ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))),
_muxer(_ledString.leds().size()), _muxer(_ledString.leds().size()),
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])), _raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledCorrection(createLedColorsCorrection(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"])), _raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), jsonConfig["color"])), _raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), jsonConfig["color"])),
_device(LedDeviceFactory::construct(jsonConfig["device"])), _device(LedDeviceFactory::construct(jsonConfig["device"])),
@ -646,16 +562,14 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
_messageForwarder(createMessageForwarder(jsonConfig["forwarder"])), _messageForwarder(createMessageForwarder(jsonConfig["forwarder"])),
_jsonConfig(jsonConfig), _jsonConfig(jsonConfig),
_configFile(configFile), _configFile(configFile),
_timer() _timer(),
_log(Logger::getInstance("Core")),
_hwLedCount(_ledString.leds().size())
{ {
if (!_raw2ledAdjustment->verifyAdjustments()) if (!_raw2ledAdjustment->verifyAdjustments())
{ {
throw std::runtime_error("HYPERION ERROR: Color adjustment incorrectly set"); throw std::runtime_error("HYPERION ERROR: Color adjustment incorrectly set");
} }
if (!_raw2ledCorrection->verifyCorrections())
{
throw std::runtime_error("HYPERION ERROR: Color correction incorrectly set");
}
if (!_raw2ledTemperature->verifyCorrections()) if (!_raw2ledTemperature->verifyCorrections())
{ {
throw std::runtime_error("HYPERION ERROR: Color temperature incorrectly set"); throw std::runtime_error("HYPERION ERROR: Color temperature incorrectly set");
@ -680,6 +594,11 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
// create the effect engine // create the effect engine
_effectEngine = new EffectEngine(this, jsonConfig["effects"]); _effectEngine = new EffectEngine(this, jsonConfig["effects"]);
unsigned int hwLedCount = jsonConfig["device"].get("ledCount",getLedCount()).asUInt();
_hwLedCount = std::max(hwLedCount, getLedCount());
Debug(_log,"configured leds: %d hw leds: %d", getLedCount(), _hwLedCount);
WarningIf(hwLedCount < getLedCount(), _log, "more leds configured than available. check 'ledCount' in 'device' section");
// initialize the leds // initialize the leds
update(); update();
} }
@ -691,25 +610,12 @@ Hyperion::~Hyperion()
clearall(); clearall();
_device->switchOff(); _device->switchOff();
// delete the effect engine // delete components on exit of hyperion core
delete _effectEngine; delete _effectEngine;
// Delete the Led-String
delete _device; delete _device;
// delete the color transform
delete _raw2ledTransform; delete _raw2ledTransform;
// delete the color correction
delete _raw2ledCorrection;
// delete the color temperature correction
delete _raw2ledTemperature; delete _raw2ledTemperature;
// delete the color adjustment
delete _raw2ledAdjustment; delete _raw2ledAdjustment;
// delete the message forwarder
delete _messageForwarder; delete _messageForwarder;
} }
@ -756,11 +662,6 @@ const std::vector<std::string> & Hyperion::getTransformIds() const
return _raw2ledTransform->getTransformIds(); return _raw2ledTransform->getTransformIds();
} }
const std::vector<std::string> & Hyperion::getCorrectionIds() const
{
return _raw2ledCorrection->getCorrectionIds();
}
const std::vector<std::string> & Hyperion::getTemperatureIds() const const std::vector<std::string> & Hyperion::getTemperatureIds() const
{ {
return _raw2ledTemperature->getCorrectionIds(); return _raw2ledTemperature->getCorrectionIds();
@ -776,11 +677,6 @@ ColorTransform * Hyperion::getTransform(const std::string& id)
return _raw2ledTransform->getTransform(id); return _raw2ledTransform->getTransform(id);
} }
ColorCorrection * Hyperion::getCorrection(const std::string& id)
{
return _raw2ledCorrection->getCorrection(id);
}
ColorCorrection * Hyperion::getTemperature(const std::string& id) ColorCorrection * Hyperion::getTemperature(const std::string& id)
{ {
return _raw2ledTemperature->getCorrection(id); return _raw2ledTemperature->getCorrection(id);
@ -884,15 +780,20 @@ void Hyperion::update()
int priority = _muxer.getCurrentPriority(); int priority = _muxer.getCurrentPriority();
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority); const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
// copy ledcolors to local buffer
_ledBuffer.reserve(_hwLedCount);
_ledBuffer = priorityInfo.ledColors;
// Apply the correction and the transform to each led and color-channel // Apply the correction and the transform to each led and color-channel
// Avoid applying correction, the same task is performed by adjustment // Avoid applying correction, the same task is performed by adjustment
// std::vector<ColorRgb> correctedColors = _raw2ledCorrection->applyCorrection(priorityInfo.ledColors); _raw2ledTransform->applyTransform(_ledBuffer);
std::vector<ColorRgb> transformColors =_raw2ledTransform->applyTransform(priorityInfo.ledColors); _raw2ledAdjustment->applyAdjustment(_ledBuffer);
std::vector<ColorRgb> adjustedColors = _raw2ledAdjustment->applyAdjustment(transformColors); _raw2ledTemperature->applyCorrection(_ledBuffer);
std::vector<ColorRgb> ledColors = _raw2ledTemperature->applyCorrection(adjustedColors);
const std::vector<Led>& leds = _ledString.leds(); const std::vector<Led>& leds = _ledString.leds();
int i = 0; int i = 0;
for (ColorRgb& color : ledColors) for (ColorRgb& color : _ledBuffer)
{ {
const ColorOrder ledColorOrder = leds.at(i).colorOrder; const ColorOrder ledColorOrder = leds.at(i).colorOrder;
// correct the color byte order // correct the color byte order
@ -926,8 +827,13 @@ void Hyperion::update()
i++; i++;
} }
if ( _hwLedCount > _ledBuffer.size() )
{
_ledBuffer.resize(_hwLedCount, ColorRgb::BLACK);
}
// Write the data to the device // Write the data to the device
_device->write(ledColors); _device->write(_ledBuffer);
// Start the timeout-timer // Start the timeout-timer
if (priorityInfo.timeoutTime_ms == -1) if (priorityInfo.timeoutTime_ms == -1)

View File

@ -3,10 +3,11 @@
#include <cassert> #include <cassert>
// Hyperion includes // Hyperion includes
#include <utils/Logger.h>
#include "MultiColorAdjustment.h" #include "MultiColorAdjustment.h"
MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt) : MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt)
_ledAdjustments(ledCnt, nullptr) : _ledAdjustments(ledCnt, nullptr)
{ {
} }
@ -40,16 +41,15 @@ void MultiColorAdjustment::setAdjustmentForLed(const std::string& id, const unsi
bool MultiColorAdjustment::verifyAdjustments() const bool MultiColorAdjustment::verifyAdjustments() const
{ {
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledAdjustments.size(); ++iLed) for (unsigned iLed=0; iLed<_ledAdjustments.size(); ++iLed)
{ {
if (_ledAdjustments[iLed] == nullptr) if (_ledAdjustments[iLed] == nullptr)
{ {
std::cerr << "HYPERION (C.adjustment) ERROR: No adjustment set for " << iLed << std::endl; Warning(Logger::getInstance("ColorAdjust"), "No adjustment set for %d", iLed);
allLedsSet = false; return false;
} }
} }
return allLedsSet; return true;
} }
const std::vector<std::string> & MultiColorAdjustment::getAdjustmentIds() const std::vector<std::string> & MultiColorAdjustment::getAdjustmentIds()
@ -72,12 +72,9 @@ ColorAdjustment* MultiColorAdjustment::getAdjustment(const std::string& id)
return nullptr; return nullptr;
} }
std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<ColorRgb>& rawColors) void MultiColorAdjustment::applyAdjustment(std::vector<ColorRgb>& ledColors)
{ {
// Create a copy, as we will do the rest of the adjustment in place const size_t itCnt = std::min(_ledAdjustments.size(), ledColors.size());
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledAdjustments.size(), rawColors.size());
for (size_t i=0; i<itCnt; ++i) for (size_t i=0; i<itCnt; ++i)
{ {
ColorAdjustment* adjustment = _ledAdjustments[i]; ColorAdjustment* adjustment = _ledAdjustments[i];
@ -122,5 +119,4 @@ std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<Co
else else
color.blue = (uint8_t)ledB; color.blue = (uint8_t)ledB;
} }
return ledColors;
} }

View File

@ -48,11 +48,9 @@ public:
/// ///
/// Performs the color adjustment from raw-color to led-color /// Performs the color adjustment from raw-color to led-color
/// ///
/// @param rawColors The list with raw colors /// @param ledColors The list with raw colors
/// ///
/// @return The list with led-colors void applyAdjustment(std::vector<ColorRgb>& ledColors);
///
std::vector<ColorRgb> applyAdjustment(const std::vector<ColorRgb>& rawColors);
private: private:
/// List with transform ids /// List with transform ids

View File

@ -3,6 +3,7 @@
#include <cassert> #include <cassert>
// Hyperion includes // Hyperion includes
#include <utils/Logger.h>
#include "MultiColorCorrection.h" #include "MultiColorCorrection.h"
MultiColorCorrection::MultiColorCorrection(const unsigned ledCnt) : MultiColorCorrection::MultiColorCorrection(const unsigned ledCnt) :
@ -40,16 +41,15 @@ void MultiColorCorrection::setCorrectionForLed(const std::string& id, const unsi
bool MultiColorCorrection::verifyCorrections() const bool MultiColorCorrection::verifyCorrections() const
{ {
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledCorrections.size(); ++iLed) for (unsigned iLed=0; iLed<_ledCorrections.size(); ++iLed)
{ {
if (_ledCorrections[iLed] == nullptr) if (_ledCorrections[iLed] == nullptr)
{ {
std::cerr << "HYPERION (C.correction) ERROR: No correction set for " << iLed << std::endl; Warning(Logger::getInstance("ColorCorrect"), "No adjustment set for %d", iLed);
allLedsSet = false; return false;
} }
} }
return allLedsSet; return true;
} }
const std::vector<std::string> & MultiColorCorrection::getCorrectionIds() const std::vector<std::string> & MultiColorCorrection::getCorrectionIds()
@ -72,12 +72,9 @@ ColorCorrection* MultiColorCorrection::getCorrection(const std::string& id)
return nullptr; return nullptr;
} }
std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<ColorRgb>& rawColors) void MultiColorCorrection::applyCorrection(std::vector<ColorRgb>& ledColors)
{ {
// Create a copy, as we will do the rest of the correction in place const size_t itCnt = std::min(_ledCorrections.size(), ledColors.size());
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledCorrections.size(), rawColors.size());
for (size_t i=0; i<itCnt; ++i) for (size_t i=0; i<itCnt; ++i)
{ {
ColorCorrection * correction = _ledCorrections[i]; ColorCorrection * correction = _ledCorrections[i];
@ -92,5 +89,4 @@ std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<Co
color.green = correction->_rgbCorrection.correctionG(color.green); color.green = correction->_rgbCorrection.correctionG(color.green);
color.blue = correction->_rgbCorrection.correctionB(color.blue); color.blue = correction->_rgbCorrection.correctionB(color.blue);
} }
return ledColors;
} }

View File

@ -48,11 +48,9 @@ public:
/// ///
/// Performs the color transoformation from raw-color to led-color /// Performs the color transoformation from raw-color to led-color
/// ///
/// @param rawColors The list with raw colors /// @param ledColors The list with led colors
/// ///
/// @return The list with led-colors void applyCorrection(std::vector<ColorRgb>& ledColors);
///
std::vector<ColorRgb> applyCorrection(const std::vector<ColorRgb>& rawColors);
private: private:
/// List with Correction ids /// List with Correction ids

View File

@ -3,6 +3,7 @@
#include <cassert> #include <cassert>
// Hyperion includes // Hyperion includes
#include <utils/Logger.h>
#include "MultiColorTransform.h" #include "MultiColorTransform.h"
MultiColorTransform::MultiColorTransform(const unsigned ledCnt) : MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
@ -40,16 +41,15 @@ void MultiColorTransform::setTransformForLed(const std::string& id, const unsign
bool MultiColorTransform::verifyTransforms() const bool MultiColorTransform::verifyTransforms() const
{ {
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed) for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
{ {
if (_ledTransforms[iLed] == nullptr) if (_ledTransforms[iLed] == nullptr)
{ {
std::cerr << "HYPERION (C.transform) ERROR: No transform set for " << iLed << std::endl; Warning(Logger::getInstance("ColorTransform"), "No adjustment set for %d", iLed);
allLedsSet = false; return false;
} }
} }
return allLedsSet; return true;
} }
const std::vector<std::string> & MultiColorTransform::getTransformIds() const std::vector<std::string> & MultiColorTransform::getTransformIds()
@ -72,12 +72,9 @@ ColorTransform* MultiColorTransform::getTransform(const std::string& id)
return nullptr; return nullptr;
} }
std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors) void MultiColorTransform::applyTransform(std::vector<ColorRgb>& ledColors)
{ {
// Create a copy, as we will do the rest of the transformation in place const size_t itCnt = std::min(_ledTransforms.size(), ledColors.size());
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
for (size_t i=0; i<itCnt; ++i) for (size_t i=0; i<itCnt; ++i)
{ {
ColorTransform* transform = _ledTransforms[i]; ColorTransform* transform = _ledTransforms[i];
@ -94,5 +91,4 @@ std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<Colo
color.green = transform->_rgbGreenTransform.transform(color.green); color.green = transform->_rgbGreenTransform.transform(color.green);
color.blue = transform->_rgbBlueTransform.transform(color.blue); color.blue = transform->_rgbBlueTransform.transform(color.blue);
} }
return ledColors;
} }

View File

@ -48,11 +48,9 @@ public:
/// ///
/// Performs the color transoformation from raw-color to led-color /// Performs the color transoformation from raw-color to led-color
/// ///
/// @param rawColors The list with raw colors /// @param ledColors The list with raw colors
/// ///
/// @return The list with led-colors void applyTransform(std::vector<ColorRgb>& ledColors);
///
std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors);
private: private:
/// List with transform ids /// List with transform ids

View File

@ -251,8 +251,6 @@ void JsonClientConnection::handleMessage(const std::string &messageString)
handleClearallCommand(message); handleClearallCommand(message);
else if (command == "transform") else if (command == "transform")
handleTransformCommand(message); handleTransformCommand(message);
else if (command == "correction")
handleCorrectionCommand(message);
else if (command == "temperature") else if (command == "temperature")
handleTemperatureCommand(message); handleTemperatureCommand(message);
else if (command == "adjustment") else if (command == "adjustment")
@ -398,26 +396,6 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
} }
} }
// collect correction information
Json::Value & correctionArray = info["correction"];
for (const std::string& correctionId : _hyperion->getCorrectionIds())
{
const ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId);
if (colorCorrection == nullptr)
{
std::cerr << "JSONCLIENT ERROR: Incorrect color correction id: " << correctionId << std::endl;
continue;
}
Json::Value & correction = correctionArray.append(Json::Value());
correction["id"] = correctionId;
Json::Value & corrValues = correction["correctionValues"];
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionR());
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionG());
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionB());
}
// collect temperature correction information // collect temperature correction information
Json::Value & temperatureArray = info["temperature"]; Json::Value & temperatureArray = info["temperature"];
for (const std::string& tempId : _hyperion->getTemperatureIds()) for (const std::string& tempId : _hyperion->getTemperatureIds())
@ -706,31 +684,6 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message)
sendSuccessReply(); sendSuccessReply();
} }
void JsonClientConnection::handleCorrectionCommand(const Json::Value &message)
{
const Json::Value & correction = message["correction"];
const std::string correctionId = correction.get("id", _hyperion->getCorrectionIds().front()).asString();
ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId);
if (colorCorrection == nullptr)
{
//sendErrorReply(std::string("Incorrect correction identifier: ") + correctionId);
return;
}
if (correction.isMember("correctionValues"))
{
const Json::Value & values = correction["correctionValues"];
colorCorrection->_rgbCorrection.setcorrectionR(values[0u].asInt());
colorCorrection->_rgbCorrection.setcorrectionG(values[1u].asInt());
colorCorrection->_rgbCorrection.setcorrectionB(values[2u].asInt());
}
// commit the changes
_hyperion->correctionsUpdated();
sendSuccessReply();
}
void JsonClientConnection::handleTemperatureCommand(const Json::Value &message) void JsonClientConnection::handleTemperatureCommand(const Json::Value &message)
{ {

View File

@ -113,13 +113,6 @@ private:
/// ///
void handleTransformCommand(const Json::Value & message); void handleTransformCommand(const Json::Value & message);
///
/// Handle an incoming JSON Correction message
///
/// @param message the incoming message
///
void handleCorrectionCommand(const Json::Value & message);
/// ///
/// Handle an incoming JSON Temperature message /// Handle an incoming JSON Temperature message
/// ///

View File

@ -12,20 +12,18 @@
// hyperion local includes // hyperion local includes
#include "LedDeviceAPA102.h" #include "LedDeviceAPA102.h"
LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate, const unsigned ledcount) : LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate)
LedSpiDevice(outputDevice, baudrate, 500000), : LedSpiDevice(outputDevice, baudrate, 500000)
_ledBuffer(0) , _ledBuffer(0)
{ {
_HW_ledcount = ledcount;
} }
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues) int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
{ {
_mLedCount = ledValues.size(); _mLedCount = ledValues.size();
const unsigned int max_leds = std::max(_mLedCount, _HW_ledcount);
const unsigned int startFrameSize = 4; const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = std::max<unsigned int>(((max_leds + 15) / 16), 4); const unsigned int endFrameSize = std::max<unsigned int>(((_mLedCount + 15) / 16), 4);
const unsigned int APAbufferSize = (max_leds * 4) + startFrameSize + endFrameSize; const unsigned int APAbufferSize = (_mLedCount * 4) + startFrameSize + endFrameSize;
if(_ledBuffer.size() != APAbufferSize){ if(_ledBuffer.size() != APAbufferSize){
_ledBuffer.resize(APAbufferSize, 0xFF); _ledBuffer.resize(APAbufferSize, 0xFF);
@ -35,8 +33,7 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[3] = 0x00; _ledBuffer[3] = 0x00;
} }
unsigned iLed=0; for (unsigned iLed=0; iLed < _mLedCount; ++iLed) {
for (iLed=0; iLed < _mLedCount; ++iLed) {
const ColorRgb& rgb = ledValues[iLed]; const ColorRgb& rgb = ledValues[iLed];
_ledBuffer[4+iLed*4] = 0xFF; _ledBuffer[4+iLed*4] = 0xFF;
_ledBuffer[4+iLed*4+1] = rgb.red; _ledBuffer[4+iLed*4+1] = rgb.red;
@ -44,13 +41,6 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[4+iLed*4+3] = rgb.blue; _ledBuffer[4+iLed*4+3] = rgb.blue;
} }
for ( ; iLed < max_leds; ++iLed) {
_ledBuffer[4+iLed*4] = 0xFF;
_ledBuffer[4+iLed*4+1] = 0x00;
_ledBuffer[4+iLed*4+2] = 0x00;
_ledBuffer[4+iLed*4+3] = 0x00;
}
return writeBytes(_ledBuffer.size(), _ledBuffer.data()); return writeBytes(_ledBuffer.size(), _ledBuffer.data());
} }

View File

@ -17,11 +17,10 @@ public:
/// ///
/// Constructs the LedDevice for a string containing leds of the type APA102 /// Constructs the LedDevice for a string containing leds of the type APA102
/// ///
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') /// @param outputDevice The name of the output device (eg '/dev/spidev.0.0')
/// @param baudrate The used baudrate for writing to the output device /// @param baudrate The used baudrate for writing to the output device
/// ///
LedDeviceAPA102(const std::string& outputDevice, LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate );
const unsigned baudrate, const unsigned ledcount );
/// ///
@ -39,7 +38,6 @@ private:
/// The buffer containing the packed RGB values /// The buffer containing the packed RGB values
std::vector<uint8_t> _ledBuffer; std::vector<uint8_t> _ledBuffer;
unsigned int _HW_ledcount;
unsigned int _mLedCount; unsigned int _mLedCount;
}; };

View File

@ -120,9 +120,8 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
{ {
const std::string output = deviceConfig["output"].asString(); const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig["rate"].asInt(); const unsigned rate = deviceConfig["rate"].asInt();
const unsigned ledcount = deviceConfig.get("leds",0).asInt();
LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate, ledcount); LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate);
deviceAPA102->open(); deviceAPA102->open();
device = deviceAPA102; device = deviceAPA102;

View File

@ -175,7 +175,7 @@ int main(int argc, char * argv[])
if (argIdC.isSet()) corrId = argIdC.getValue(); if (argIdC.isSet()) corrId = argIdC.getValue();
if (argCorrection.isSet()) correction = argCorrection.getValue(); if (argCorrection.isSet()) correction = argCorrection.getValue();
connection.setCorrection( connection.setTemperature(
argIdC.isSet() ? &corrId : nullptr, argIdC.isSet() ? &corrId : nullptr,
argCorrection.isSet() ? &correction : nullptr); argCorrection.isSet() ? &correction : nullptr);
} }