Art-Net Color Order Maps, RGBW
This commit is contained in:
@@ -448,7 +448,7 @@ uint8_t BusOnOff::getPins(uint8_t* pinArray) const {
|
||||
}
|
||||
|
||||
|
||||
BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
BusNetwork::BusNetwork(BusConfig &bc, const ColorOrderMap &com) : Bus(bc.type, bc.start, bc.autoWhite), _colorOrderMap(com) {
|
||||
_valid = false;
|
||||
USER_PRINT("[");
|
||||
switch (bc.type) {
|
||||
@@ -457,6 +457,11 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
_UDPtype = 2;
|
||||
USER_PRINT("NET_ARTNET_RGB");
|
||||
break;
|
||||
case TYPE_NET_ARTNET_RGBW:
|
||||
_rgbw = true;
|
||||
_UDPtype = 2;
|
||||
USER_PRINT("NET_ARTNET_RGBW");
|
||||
break;
|
||||
case TYPE_NET_E131_RGB:
|
||||
_rgbw = false;
|
||||
_UDPtype = 1;
|
||||
@@ -469,10 +474,11 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
break;
|
||||
}
|
||||
_UDPchannels = _rgbw ? 4 : 3;
|
||||
_data = (byte *)malloc(bc.count * _UDPchannels);
|
||||
_data = (byte*) heap_caps_calloc_prefer((bc.count * _UDPchannels)+15, sizeof(byte), 3, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM);
|
||||
|
||||
if (_data == nullptr) return;
|
||||
memset(_data, 0, bc.count * _UDPchannels);
|
||||
_len = bc.count;
|
||||
_colorOrder = bc.colorOrder;
|
||||
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
||||
_broadcastLock = false;
|
||||
_valid = true;
|
||||
@@ -482,21 +488,61 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
USER_PRINTF(" %u.%u.%u.%u]\n", bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
||||
}
|
||||
|
||||
void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
|
||||
if (!_valid || pix >= _len) return;
|
||||
if (hasWhite()) c = autoWhiteCalc(c);
|
||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||
uint16_t offset = pix * _UDPchannels;
|
||||
_data[offset] = R(c);
|
||||
_data[offset+1] = G(c);
|
||||
_data[offset+2] = B(c);
|
||||
if (_rgbw) _data[offset+3] = W(c);
|
||||
void IRAM_ATTR BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
|
||||
if (!_valid || pix >= _len) return;
|
||||
if (_rgbw) c = autoWhiteCalc(c);
|
||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); // color correction from CCT
|
||||
|
||||
uint16_t offset = pix * _UDPchannels;
|
||||
uint8_t co = _colorOrderMap.getPixelColorOrder(pix + _start, _colorOrder);
|
||||
|
||||
if (_colorOrder != co || _colorOrder != COL_ORDER_RGB) {
|
||||
switch (co) {
|
||||
case COL_ORDER_GRB:
|
||||
_data[offset] = G(c); _data[offset+1] = R(c); _data[offset+2] = B(c);
|
||||
break;
|
||||
case COL_ORDER_RGB:
|
||||
_data[offset] = R(c); _data[offset+1] = G(c); _data[offset+2] = B(c);
|
||||
break;
|
||||
case COL_ORDER_BRG:
|
||||
_data[offset] = B(c); _data[offset+1] = R(c); _data[offset+2] = G(c);
|
||||
break;
|
||||
case COL_ORDER_RBG:
|
||||
_data[offset] = R(c); _data[offset+1] = B(c); _data[offset+2] = G(c);
|
||||
break;
|
||||
case COL_ORDER_GBR:
|
||||
_data[offset] = G(c); _data[offset+1] = B(c); _data[offset+2] = R(c);
|
||||
break;
|
||||
case COL_ORDER_BGR:
|
||||
_data[offset] = B(c); _data[offset+1] = G(c); _data[offset+2] = R(c);
|
||||
break;
|
||||
}
|
||||
if (_rgbw) _data[offset+3] = W(c);
|
||||
} else {
|
||||
_data[offset] = R(c); _data[offset+1] = G(c); _data[offset+2] = B(c);
|
||||
if (_rgbw) _data[offset+3] = W(c);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t BusNetwork::getPixelColor(uint16_t pix) const {
|
||||
if (!_valid || pix >= _len) return 0;
|
||||
uint16_t offset = pix * _UDPchannels;
|
||||
return RGBW32(_data[offset], _data[offset+1], _data[offset+2], _rgbw ? (_data[offset+3] << 24) : 0);
|
||||
uint32_t IRAM_ATTR BusNetwork::getPixelColor(uint16_t pix) const {
|
||||
if (!_valid || pix >= _len) return 0;
|
||||
uint16_t offset = pix * _UDPchannels;
|
||||
uint8_t co = _colorOrderMap.getPixelColorOrder(pix + _start, _colorOrder);
|
||||
|
||||
uint8_t r = _data[offset + 0];
|
||||
uint8_t g = _data[offset + 1];
|
||||
uint8_t b = _data[offset + 2];
|
||||
uint8_t w = _rgbw ? _data[offset + 3] : 0;
|
||||
|
||||
switch (co) {
|
||||
case COL_ORDER_GRB: return RGBW32(g, r, b, w);
|
||||
case COL_ORDER_RGB: return RGBW32(r, g, b, w);
|
||||
case COL_ORDER_BRG: return RGBW32(b, r, g, w);
|
||||
case COL_ORDER_RBG: return RGBW32(r, b, g, w);
|
||||
case COL_ORDER_GBR: return RGBW32(g, b, r, w);
|
||||
case COL_ORDER_BGR: return RGBW32(b, g, r, w);
|
||||
default: return RGBW32(r, g, b, w); // default to RGB order
|
||||
}
|
||||
}
|
||||
|
||||
void BusNetwork::show() {
|
||||
@@ -516,8 +562,8 @@ uint8_t BusNetwork::getPins(uint8_t* pinArray) const {
|
||||
void BusNetwork::cleanup() {
|
||||
_type = I_NONE;
|
||||
_valid = false;
|
||||
if (_data != nullptr) free(_data);
|
||||
_data = nullptr;
|
||||
// if (_data != nullptr) free(_data);
|
||||
// _data = nullptr;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
@@ -1181,7 +1227,7 @@ int BusManager::add(BusConfig &bc) {
|
||||
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
|
||||
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
||||
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
||||
busses[numBusses] = new BusNetwork(bc);
|
||||
busses[numBusses] = new BusNetwork(bc, colorOrderMap);
|
||||
} else if (bc.type >= TYPE_HUB75MATRIX && bc.type <= (TYPE_HUB75MATRIX + 10)) {
|
||||
#ifdef WLED_ENABLE_HUB75MATRIX
|
||||
DEBUG_PRINTLN("BusManager::add - Adding BusHub75Matrix");
|
||||
|
||||
@@ -337,7 +337,7 @@ class BusOnOff : public Bus {
|
||||
|
||||
class BusNetwork : public Bus {
|
||||
public:
|
||||
BusNetwork(BusConfig &bc);
|
||||
BusNetwork(BusConfig &bc, const ColorOrderMap &com);
|
||||
|
||||
uint16_t getMaxPixels() const override { return 4096; };
|
||||
bool hasRGB() const { return true; }
|
||||
|
||||
@@ -252,7 +252,8 @@
|
||||
//Network types (master broadcast) (80-95)
|
||||
#define TYPE_NET_DDP_RGB 80 //network DDP RGB bus (master broadcast bus)
|
||||
#define TYPE_NET_E131_RGB 81 //network E131 RGB bus (master broadcast bus, unused)
|
||||
#define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused)
|
||||
#define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus)
|
||||
#define TYPE_NET_ARTNET_RGBW 83 //network ArtNet RGB bus (master broadcast bus)
|
||||
#define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus)
|
||||
|
||||
#define IS_DIGITAL(t) (((t) & 0x10) || ((t)==TYPE_HUB75MATRIX)) //digital are 16-31 and 48-63 // WLEDMM added HUB75
|
||||
|
||||
@@ -774,7 +774,7 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
|
||||
|
||||
// For some reason, this is faster outside of the case block...
|
||||
//
|
||||
static byte *packet_buffer = (byte *) heap_caps_calloc_prefer(530, sizeof(byte), 3, MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM); // MALLOC_CAP_TCM seems to have alignment issues.
|
||||
static byte *packet_buffer = (byte *) heap_caps_calloc_prefer(530, sizeof(byte), 2, MALLOC_CAP_DEFAULT, MALLOC_CAP_SPIRAM); // MALLOC_CAP_TCM seems to have alignment issues.
|
||||
if (packet_buffer[0] != 0x41) memcpy(packet_buffer, ART_NET_HEADER, 12); // copy in the Art-Net header if it isn't there already
|
||||
|
||||
// Volumetric test code
|
||||
@@ -792,6 +792,8 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
|
||||
switch (type) {
|
||||
case 0: // DDP
|
||||
{
|
||||
WiFiUDP ddpUdp;
|
||||
|
||||
// calculate the number of UDP packets we need to send
|
||||
size_t channelCount = length * (isRGBW? 4:3); // 1 channel for every R,G,B value
|
||||
size_t packetCount = ((channelCount-1) / DDP_CHANNELS_PER_PACKET) +1;
|
||||
@@ -857,16 +859,11 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
|
||||
case 1: //E1.31
|
||||
{
|
||||
} break;
|
||||
|
||||
case 2: //ArtNet
|
||||
case 2: //Art-Net
|
||||
{
|
||||
static uint_fast16_t artnetlimiter = millis()+(1000/fps_limit);
|
||||
while (artnetlimiter > micros()) {
|
||||
if (ArtNetSkipFrame) {
|
||||
return 0; // Let WLED keep generating effect frames and we output an Art-Net frame when fps_limit is reached.
|
||||
} else {
|
||||
delayMicroseconds(10); // Make WLED obey fps_limit and just delay here until we're ready to send a frame.
|
||||
}
|
||||
delayMicroseconds(10); // Make WLED obey fps_limit and just delay here until we're ready to send a frame.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -904,8 +901,6 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
|
||||
return 1; // stop when we hit end of LEDs
|
||||
}
|
||||
|
||||
// hardware_output_universe = hardware_outputs_universe_start[hardware_output];
|
||||
|
||||
uint_fast16_t channels_remaining = leds_per_output * (isRGBW?4:3);
|
||||
|
||||
while (channels_remaining > 0) {
|
||||
@@ -1004,6 +999,7 @@ uint8_t IRAM_ATTR realtimeBroadcast(uint8_t type, IPAddress client, uint16_t len
|
||||
return 1; // borked
|
||||
}
|
||||
#endif
|
||||
packet_buffer[9] = ART_NET_HEADER[9]; // reset ArtSync opcode high byte
|
||||
|
||||
#ifdef ARTNET_TIMER
|
||||
packetstotal++;
|
||||
|
||||
Reference in New Issue
Block a user