From 20ad969f9f7d0200f6a1743e3cebcb92f8b08def Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 29 Jun 2025 15:42:30 +0000 Subject: [PATCH 1/6] feat: Add RGBW support to LedDeviceUdpE131 This commit introduces RGBW (Red, Green, Blue, White) data handling for the E1.31 UDP LED device. Key changes: 1. **LedDeviceUdpE131.h modifications:** * Included `utils/ColorRgbw.h` and `utils/RgbToRgbw.h`. * Added private member variables: * `_whiteAlgorithm` (RGBW::WhiteAlgorithm) to store the selected white calibration mode. * `_ledRGBWCount` (int) to store the total number of channels (3 for RGB, 4 for RGBW). * `_temp_rgbw` (ColorRgbw) as a temporary variable for color conversion. 2. **LedDeviceUdpE131.cpp modifications:** * Constructor now initializes `_whiteAlgorithm` to `INVALID` and `_ledRGBWCount` to 0. * `init()` method: * Reads `whiteAlgorithm` from the device configuration (defaults to "white_off"). * Converts the string to `RGBW::WhiteAlgorithm`. * Sets `_ledRGBWCount` based on `_ledCount` and whether a white channel is active (3 * _ledCount for RGB, 4 * _ledCount for RGBW). * `write()` method: * Uses `_ledRGBWCount` for `dmxChannelCount`. * Creates a temporary buffer for pixel data. * If `_whiteAlgorithm` is `WHITE_OFF`, copies RGB data directly. * Otherwise, converts RGB to RGBW using `RGBW::Rgb_to_Rgbw` and copies R,G,B,W data. * Populates E1.31 packet properties using the new (potentially RGBW) data buffer. 3. **JSON Schema Update (libsrc/leddevice/schemas/schema-e131.json):** * Added a `whiteAlgorithm` property to the E1.31 device schema. * This allows users to select the white channel calibration method ("white_off", "subtractive", "additive"). * Includes a default value of "white_off". **Compilation Status:** The project successfully configures with CMake after installing numerous dependencies (Qt6, libudev, XCB libs, ALSA, CEC, libp8-platform, libusb). However, the `make` process consistently times out after approximately 6 minutes and 40 seconds, regardless of the number of parallel jobs (`-j nproc`, `-j 2`, `-j 1`) or if a specific target (`hyperiond`) is built. This suggests a potential hang or an extremely long compilation step for a particular file/module within the project, which could not be identified due to lack of verbose output during the timeout. Further investigation or environment adjustments are needed to complete the full build. --- libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp | 60 ++++++++++++++++--- libsrc/leddevice/dev_net/LedDeviceUdpE131.h | 7 +++ libsrc/leddevice/schemas/schema-e131.json | 18 ++++++ 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp index 1be48dc3e..d52175b7a 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp @@ -39,6 +39,8 @@ const int DMX_MAX = 512; // 512 usable slots LedDeviceUdpE131::LedDeviceUdpE131(const QJsonObject &deviceConfig) : ProviderUdp(deviceConfig) + , _whiteAlgorithm(RGBW::WhiteAlgorithm::INVALID) + , _ledRGBWCount(0) { } @@ -61,6 +63,28 @@ bool LedDeviceUdpE131::init(const QJsonObject &deviceConfig) _e131_source_name = deviceConfig["source-name"].toString("hyperion on "+QHostInfo::localHostName()); QString _json_cid = deviceConfig["cid"].toString(""); + // Initialize white algorithm + QString whiteAlgorithmStr = deviceConfig["whiteAlgorithm"].toString("white_off"); + _whiteAlgorithm = RGBW::stringToWhiteAlgorithm(whiteAlgorithmStr); + if (_whiteAlgorithm == RGBW::WhiteAlgorithm::INVALID) + { + QString errortext = QString("unknown whiteAlgorithm: %1").arg(whiteAlgorithmStr); + this->setInError(errortext); + return false; + } + Debug(_log, "whiteAlgorithm : %s", QSTRING_CSTR(whiteAlgorithmStr)); + + // Calculate RGBW count + if (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) + { + _ledRGBWCount = _ledCount * 3; + } + else + { + _ledRGBWCount = _ledCount * 4; + } + + if (_json_cid.isEmpty()) { _e131_cid = QUuid::createUuid(); @@ -138,10 +162,32 @@ void LedDeviceUdpE131::prepare(unsigned this_universe, unsigned this_dmxChannelC int LedDeviceUdpE131::write(const std::vector &ledValues) { - int retVal = 0; + int retVal = 0; int thisChannelCount = 0; - int dmxChannelCount = _ledRGBCount; - const uint8_t * rawdata = reinterpret_cast(ledValues.data()); + int dmxChannelCount = _ledRGBWCount; // Use _ledRGBWCount + + // Create a temporary buffer for RGB or RGBW data + std::vector tempBuffer(dmxChannelCount); + uint8_t* rawDataPtr = tempBuffer.data(); + + int currentChannel = 0; + for (const ColorRgb& color : ledValues) + { + if (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) + { + rawDataPtr[currentChannel++] = color.red; + rawDataPtr[currentChannel++] = color.green; + rawDataPtr[currentChannel++] = color.blue; + } + else + { + RGBW::Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm); + rawDataPtr[currentChannel++] = _temp_rgbw.red; + rawDataPtr[currentChannel++] = _temp_rgbw.green; + rawDataPtr[currentChannel++] = _temp_rgbw.blue; + rawDataPtr[currentChannel++] = _temp_rgbw.white; + } + } _e131_seq++; @@ -150,16 +196,16 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) if (rawIdx % DMX_MAX == 0) // start of new packet { thisChannelCount = (dmxChannelCount - rawIdx < DMX_MAX) ? dmxChannelCount % DMX_MAX : DMX_MAX; -// is this the last packet? ? ^^ last packet : ^^ earlier packets + // is this the last packet? ? ^^ last packet : ^^ earlier packets prepare(_e131_universe + rawIdx / DMX_MAX, thisChannelCount); e131_packet.sequence_number = _e131_seq; } - e131_packet.property_values[1 + rawIdx%DMX_MAX] = rawdata[rawIdx]; + e131_packet.property_values[1 + rawIdx % DMX_MAX] = rawDataPtr[rawIdx]; -// is this the last byte of last packet || last byte of other packets - if ( (rawIdx == dmxChannelCount-1) || (rawIdx %DMX_MAX == DMX_MAX-1) ) + // is this the last byte of last packet || last byte of other packets + if ((rawIdx == dmxChannelCount - 1) || (rawIdx % DMX_MAX == DMX_MAX - 1)) { #undef e131debug #if e131debug diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h index 0397eeda7..20cc2d820 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h @@ -3,6 +3,8 @@ // hyperion includes #include "ProviderUdp.h" +#include "utils/ColorRgbw.h" +#include "utils/RgbToRgbw.h" #include @@ -142,6 +144,11 @@ class LedDeviceUdpE131 : public ProviderUdp uint8_t _acn_id[12] = {0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 }; QString _e131_source_name; QUuid _e131_cid; + + // RGBW specific members + RGBW::WhiteAlgorithm _whiteAlgorithm; + int _ledRGBWCount; + ColorRgbw _temp_rgbw; }; #endif // LEDEVICEUDPE131_H diff --git a/libsrc/leddevice/schemas/schema-e131.json b/libsrc/leddevice/schemas/schema-e131.json index 027407272..0227b1d2c 100644 --- a/libsrc/leddevice/schemas/schema-e131.json +++ b/libsrc/leddevice/schemas/schema-e131.json @@ -36,6 +36,24 @@ "type": "string", "title": "edt_dev_spec_cid_title", "propertyOrder": 5 + }, + "whiteAlgorithm": { + "type": "string", + "title": "edt_dev_spec_white_algorithm_title", + "enum": [ + "white_off", + "subtractive", + "additive" + ], + "default": "white_off", + "propertyOrder": 6, + "options": { + "enum_titles": [ + "edt_dev_spec_white_algorithm_white_off", + "edt_dev_spec_white_algorithm_subtractive", + "edt_dev_spec_white_algorithm_additive" + ] + } } }, "additionalProperties": true From b7334ad86c671631b69e350a30abe160238bda25 Mon Sep 17 00:00:00 2001 From: Alexander Lougovski Date: Mon, 30 Jun 2025 07:14:07 +0200 Subject: [PATCH 2/6] 1. Reworked the generated code. Optimized it here and there. Reused ledRGB(W)Count variable from LedDevice instead of creating a new locally 2. Fixed the problem where DMX Max channel count was hardcoded to 512. WLED e.g. in MultiRGB mode relies on 510 (3*170) channels. On other hand for MultiRGBW it expect 512 (4*128) channels. So obviously it has to be a parameter. 3. Updated corresponding configuration for WebUI --- assets/webconfig/i18n/en.json | 1 + libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp | 27 +++------- libsrc/leddevice/dev_net/LedDeviceUdpE131.h | 2 +- libsrc/leddevice/schemas/schema-e131.json | 49 +++++++++++++------ 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 8e24e7bbe..1a0f73850 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -688,6 +688,7 @@ "edt_dev_spec_devices_discovery_inprogress": "Discovery in progress", "edt_dev_spec_dithering_title": "Dithering", "edt_dev_spec_dmaNumber_title": "DMA channel", + "edt_dev_spec_dmx_max_title": "DMX maximal number of channels", "edt_dev_spec_fullBrightnessAtStart_title": "Full brightness at start", "edt_dev_spec_gamma_title": "Gamma", "edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level", diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp index d52175b7a..f27cbc831 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp @@ -40,7 +40,6 @@ const int DMX_MAX = 512; // 512 usable slots LedDeviceUdpE131::LedDeviceUdpE131(const QJsonObject &deviceConfig) : ProviderUdp(deviceConfig) , _whiteAlgorithm(RGBW::WhiteAlgorithm::INVALID) - , _ledRGBWCount(0) { } @@ -60,6 +59,7 @@ bool LedDeviceUdpE131::init(const QJsonObject &deviceConfig) _port = deviceConfig[CONFIG_PORT].toInt(E131_DEFAULT_PORT); _e131_universe = deviceConfig["universe"].toInt(1); + _e131_dmx_max = deviceConfig["dmx-max"].toInt(DMX_MAX); _e131_source_name = deviceConfig["source-name"].toString("hyperion on "+QHostInfo::localHostName()); QString _json_cid = deviceConfig["cid"].toString(""); @@ -74,17 +74,6 @@ bool LedDeviceUdpE131::init(const QJsonObject &deviceConfig) } Debug(_log, "whiteAlgorithm : %s", QSTRING_CSTR(whiteAlgorithmStr)); - // Calculate RGBW count - if (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) - { - _ledRGBWCount = _ledCount * 3; - } - else - { - _ledRGBWCount = _ledCount * 4; - } - - if (_json_cid.isEmpty()) { _e131_cid = QUuid::createUuid(); @@ -164,7 +153,7 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) { int retVal = 0; int thisChannelCount = 0; - int dmxChannelCount = _ledRGBWCount; // Use _ledRGBWCount + int dmxChannelCount = (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) ? _ledRGBCount : _ledRGBWCount; // if white_off we expect 3 channels per LED otherwise 4 // Create a temporary buffer for RGB or RGBW data std::vector tempBuffer(dmxChannelCount); @@ -193,26 +182,26 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) for (int rawIdx = 0; rawIdx < dmxChannelCount; rawIdx++) { - if (rawIdx % DMX_MAX == 0) // start of new packet + if (rawIdx % _e131_dmx_max == 0) // start of new packet { - thisChannelCount = (dmxChannelCount - rawIdx < DMX_MAX) ? dmxChannelCount % DMX_MAX : DMX_MAX; + thisChannelCount = (dmxChannelCount - rawIdx < _e131_dmx_max) ? dmxChannelCount % _e131_dmx_max : _e131_dmx_max; // is this the last packet? ? ^^ last packet : ^^ earlier packets - prepare(_e131_universe + rawIdx / DMX_MAX, thisChannelCount); + prepare(_e131_universe + rawIdx / _e131_dmx_max, thisChannelCount); e131_packet.sequence_number = _e131_seq; } - e131_packet.property_values[1 + rawIdx % DMX_MAX] = rawDataPtr[rawIdx]; + e131_packet.property_values[1 + rawIdx % _e131_dmx_max] = rawDataPtr[rawIdx]; // is this the last byte of last packet || last byte of other packets - if ((rawIdx == dmxChannelCount - 1) || (rawIdx % DMX_MAX == DMX_MAX - 1)) + if ((rawIdx == dmxChannelCount - 1) || (rawIdx % _e131_dmx_max == _e131_dmx_max - 1)) { #undef e131debug #if e131debug Debug (_log, "send packet: rawidx %d dmxchannelcount %d universe: %d, packetsz %d" , rawIdx , dmxChannelCount - , _e131_universe + rawIdx / DMX_MAX + , _e131_universe + rawIdx / _e131_dmx_max , E131_DMP_DATA + 1 + thisChannelCount ); #endif diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h index 20cc2d820..899eac57f 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h @@ -141,13 +141,13 @@ class LedDeviceUdpE131 : public ProviderUdp e131_packet_t e131_packet; uint8_t _e131_seq = 0; uint8_t _e131_universe = 1; + int _e131_dmx_max = 512; uint8_t _acn_id[12] = {0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 }; QString _e131_source_name; QUuid _e131_cid; // RGBW specific members RGBW::WhiteAlgorithm _whiteAlgorithm; - int _ledRGBWCount; ColorRgbw _temp_rgbw; }; diff --git a/libsrc/leddevice/schemas/schema-e131.json b/libsrc/leddevice/schemas/schema-e131.json index 0227b1d2c..a6637470a 100644 --- a/libsrc/leddevice/schemas/schema-e131.json +++ b/libsrc/leddevice/schemas/schema-e131.json @@ -22,6 +22,12 @@ "default": 1, "propertyOrder": 3 }, + "dmx-max": { + "type": "integer", + "title": "edt_dev_spec_dmx_max_title", + "default": 512, + "propertyOrder": 4 + }, "latchTime": { "type": "integer", "title": "edt_dev_spec_latchtime_title", @@ -30,30 +36,43 @@ "minimum": 0, "maximum": 1000, "access": "expert", - "propertyOrder": 4 + "propertyOrder": 5 }, "cid": { "type": "string", "title": "edt_dev_spec_cid_title", - "propertyOrder": 5 + "propertyOrder": 6 }, + "whiteAlgorithm": { "type": "string", - "title": "edt_dev_spec_white_algorithm_title", - "enum": [ - "white_off", - "subtractive", - "additive" + "title":"edt_dev_spec_whiteLedAlgor_title", + "enum" : [ + "subtract_minimum", + "sub_min_cool_adjust", + "sub_min_warm_adjust", + "cold_white", + "neutral_white", + "auto", + "auto_max", + "auto_accurate", + "white_off" ], "default": "white_off", - "propertyOrder": 6, - "options": { - "enum_titles": [ - "edt_dev_spec_white_algorithm_white_off", - "edt_dev_spec_white_algorithm_subtractive", - "edt_dev_spec_white_algorithm_additive" - ] - } + "options" : { + "enum_titles" : [ + "edt_dev_enum_subtract_minimum", + "edt_dev_enum_sub_min_cool_adjust", + "edt_dev_enum_sub_min_warm_adjust", + "edt_dev_enum_cold_white", + "edt_dev_enum_neutral_white", + "edt_dev_enum_auto", + "edt_dev_enum_auto_max", + "edt_dev_enum_auto_accurate", + "edt_dev_enum_white_off" + ] + }, + "propertyOrder" : 7 } }, "additionalProperties": true From e60fa6fb19b4c920f9df33af077fdb8516b340bd Mon Sep 17 00:00:00 2001 From: lougovsk Date: Mon, 30 Jun 2025 15:28:23 +0200 Subject: [PATCH 3/6] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da80f3b5..72668be8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### ✨ Added ---- +- Support of RGBW in **e1.31** led devices. ### 🔧 Changed From 4359ea962c76344aad13ba3317d7ea8469ac2abe Mon Sep 17 00:00:00 2001 From: Thomas Emmel Date: Mon, 27 Oct 2025 21:10:15 +0100 Subject: [PATCH 4/6] Enforce channel range via schema --- assets/webconfig/i18n/en.json | 2 +- libsrc/leddevice/schemas/schema-e131.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 8fbfb3bb6..f46e9b5af 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -689,7 +689,7 @@ "edt_dev_spec_devices_discovery_inprogress": "Discovery in progress", "edt_dev_spec_dithering_title": "Dithering", "edt_dev_spec_dmaNumber_title": "DMA channel", - "edt_dev_spec_dmx_max_title": "DMX maximal number of channels", + "edt_dev_spec_dmx_max_title": "DMX maximum channels supported", "edt_dev_spec_fullBrightnessAtStart_title": "Full brightness at start", "edt_dev_spec_gamma_title": "Gamma", "edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level", diff --git a/libsrc/leddevice/schemas/schema-e131.json b/libsrc/leddevice/schemas/schema-e131.json index a6637470a..1953524e5 100644 --- a/libsrc/leddevice/schemas/schema-e131.json +++ b/libsrc/leddevice/schemas/schema-e131.json @@ -25,7 +25,10 @@ "dmx-max": { "type": "integer", "title": "edt_dev_spec_dmx_max_title", + "minimum": 1, + "maximum": 512, "default": 512, + "access": "advanced", "propertyOrder": 4 }, "latchTime": { From 9f49c4d42f8853f81bf20ce25a09d0550857cc32 Mon Sep 17 00:00:00 2001 From: Thomas Emmel Date: Mon, 27 Oct 2025 21:19:49 +0100 Subject: [PATCH 5/6] Update document formatting --- libsrc/leddevice/schemas/schema-e131.json | 55 +++++++++++------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/libsrc/leddevice/schemas/schema-e131.json b/libsrc/leddevice/schemas/schema-e131.json index 1953524e5..779381aed 100644 --- a/libsrc/leddevice/schemas/schema-e131.json +++ b/libsrc/leddevice/schemas/schema-e131.json @@ -26,9 +26,9 @@ "type": "integer", "title": "edt_dev_spec_dmx_max_title", "minimum": 1, - "maximum": 512, + "maximum": 512, "default": 512, - "access": "advanced", + "access": "advanced", "propertyOrder": 4 }, "latchTime": { @@ -46,37 +46,36 @@ "title": "edt_dev_spec_cid_title", "propertyOrder": 6 }, - "whiteAlgorithm": { "type": "string", - "title":"edt_dev_spec_whiteLedAlgor_title", - "enum" : [ - "subtract_minimum", - "sub_min_cool_adjust", - "sub_min_warm_adjust", - "cold_white", - "neutral_white", - "auto", - "auto_max", - "auto_accurate", - "white_off" + "title": "edt_dev_spec_whiteLedAlgor_title", + "enum": [ + "subtract_minimum", + "sub_min_cool_adjust", + "sub_min_warm_adjust", + "cold_white", + "neutral_white", + "auto", + "auto_max", + "auto_accurate", + "white_off" ], "default": "white_off", - "options" : { - "enum_titles" : [ - "edt_dev_enum_subtract_minimum", - "edt_dev_enum_sub_min_cool_adjust", - "edt_dev_enum_sub_min_warm_adjust", - "edt_dev_enum_cold_white", - "edt_dev_enum_neutral_white", - "edt_dev_enum_auto", - "edt_dev_enum_auto_max", - "edt_dev_enum_auto_accurate", - "edt_dev_enum_white_off" - ] + "options": { + "enum_titles": [ + "edt_dev_enum_subtract_minimum", + "edt_dev_enum_sub_min_cool_adjust", + "edt_dev_enum_sub_min_warm_adjust", + "edt_dev_enum_cold_white", + "edt_dev_enum_neutral_white", + "edt_dev_enum_auto", + "edt_dev_enum_auto_max", + "edt_dev_enum_auto_accurate", + "edt_dev_enum_white_off" + ] }, - "propertyOrder" : 7 + "propertyOrder": 7 } }, "additionalProperties": true -} +} \ No newline at end of file From a535db32c52c183b27db205046b2e27d97ee4396 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 15:15:49 +0000 Subject: [PATCH 6/6] Refactor LedDeviceUdpE131 for performance Moved the dmxChannelCount calculation and the creation of the ledBuffer from the `write` function to the `init` function. This avoids repeated calculations and memory allocations on every call to `write`, improving performance. --- libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp | 17 +++++++++-------- libsrc/leddevice/dev_net/LedDeviceUdpE131.h | 3 +++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp index f27cbc831..526699026 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp @@ -40,6 +40,7 @@ const int DMX_MAX = 512; // 512 usable slots LedDeviceUdpE131::LedDeviceUdpE131(const QJsonObject &deviceConfig) : ProviderUdp(deviceConfig) , _whiteAlgorithm(RGBW::WhiteAlgorithm::INVALID) + , _dmxChannelCount(0) { } @@ -74,6 +75,9 @@ bool LedDeviceUdpE131::init(const QJsonObject &deviceConfig) } Debug(_log, "whiteAlgorithm : %s", QSTRING_CSTR(whiteAlgorithmStr)); + _dmxChannelCount = (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) ? _ledRGBCount : _ledRGBWCount; + _ledBuffer.resize(_dmxChannelCount); + if (_json_cid.isEmpty()) { _e131_cid = QUuid::createUuid(); @@ -153,11 +157,8 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) { int retVal = 0; int thisChannelCount = 0; - int dmxChannelCount = (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) ? _ledRGBCount : _ledRGBWCount; // if white_off we expect 3 channels per LED otherwise 4 - // Create a temporary buffer for RGB or RGBW data - std::vector tempBuffer(dmxChannelCount); - uint8_t* rawDataPtr = tempBuffer.data(); + uint8_t* rawDataPtr = _ledBuffer.data(); int currentChannel = 0; for (const ColorRgb& color : ledValues) @@ -180,11 +181,11 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) _e131_seq++; - for (int rawIdx = 0; rawIdx < dmxChannelCount; rawIdx++) + for (int rawIdx = 0; rawIdx < _dmxChannelCount; rawIdx++) { if (rawIdx % _e131_dmx_max == 0) // start of new packet { - thisChannelCount = (dmxChannelCount - rawIdx < _e131_dmx_max) ? dmxChannelCount % _e131_dmx_max : _e131_dmx_max; + thisChannelCount = (_dmxChannelCount - rawIdx < _e131_dmx_max) ? _dmxChannelCount % _e131_dmx_max : _e131_dmx_max; // is this the last packet? ? ^^ last packet : ^^ earlier packets prepare(_e131_universe + rawIdx / _e131_dmx_max, thisChannelCount); @@ -194,13 +195,13 @@ int LedDeviceUdpE131::write(const std::vector &ledValues) e131_packet.property_values[1 + rawIdx % _e131_dmx_max] = rawDataPtr[rawIdx]; // is this the last byte of last packet || last byte of other packets - if ((rawIdx == dmxChannelCount - 1) || (rawIdx % _e131_dmx_max == _e131_dmx_max - 1)) + if ((rawIdx == _dmxChannelCount - 1) || (rawIdx % _e131_dmx_max == _e131_dmx_max - 1)) { #undef e131debug #if e131debug Debug (_log, "send packet: rawidx %d dmxchannelcount %d universe: %d, packetsz %d" , rawIdx - , dmxChannelCount + , _dmxChannelCount , _e131_universe + rawIdx / _e131_dmx_max , E131_DMP_DATA + 1 + thisChannelCount ); diff --git a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h index 899eac57f..c239ed9b3 100644 --- a/libsrc/leddevice/dev_net/LedDeviceUdpE131.h +++ b/libsrc/leddevice/dev_net/LedDeviceUdpE131.h @@ -7,6 +7,7 @@ #include "utils/RgbToRgbw.h" #include +#include /** * @@ -149,6 +150,8 @@ class LedDeviceUdpE131 : public ProviderUdp // RGBW specific members RGBW::WhiteAlgorithm _whiteAlgorithm; ColorRgbw _temp_rgbw; + int _dmxChannelCount; + std::vector _ledBuffer; }; #endif // LEDEVICEUDPE131_H