Skip to content

Commit 8ce0d85

Browse files
authored
Merge branch 'wled:main' into main
2 parents baa05e8 + d5d7fde commit 8ce0d85

File tree

17 files changed

+466
-541
lines changed

17 files changed

+466
-541
lines changed

.github/workflows/pr-merge.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,14 @@
2525
echo "Job originally triggered by ${{ github.actor }}"
2626
exit 1
2727
- name: Send Discord notification
28+
env:
29+
PR_NUMBER: ${{ github.event.pull_request.number }}
30+
PR_TITLE: ${{ github.event.pull_request.title }}
31+
PR_URL: ${{ github.event.pull_request.html_url }}
32+
ACTOR: ${{ github.actor }}
2833
run: |
29-
curl -H "Content-Type: application/json" -d '{"content": "Pull Request ${{ github.event.pull_request.number }} merged by ${{ github.actor }}"}' ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}
34+
jq -n \
35+
--arg content "Pull Request #${PR_NUMBER} \"${PR_TITLE}\" merged by ${ACTOR}
36+
${PR_URL}" \
37+
'{content: $content}' \
38+
| curl -H "Content-Type: application/json" -d @- ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}

wled00/FX.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7528,9 +7528,9 @@ uint16_t mode_2Ddistortionwaves() {
75287528
byte valueG = gdistort + ((a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 ))<<1);
75297529
byte valueB = bdistort + ((a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 ))<<1);
75307530

7531-
valueR = gamma8(cos8_t(valueR));
7532-
valueG = gamma8(cos8_t(valueG));
7533-
valueB = gamma8(cos8_t(valueB));
7531+
valueR = cos8_t(valueR);
7532+
valueG = cos8_t(valueG);
7533+
valueB = cos8_t(valueB);
75347534

75357535
if(SEGMENT.palette == 0) {
75367536
// use RGB values (original color mode)

wled00/FX_fcn.cpp

Lines changed: 14 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ void Segment::startTransition(uint16_t dur, bool segmentCopy) {
282282
_t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings
283283
_t->_start = millis(); // restart countdown
284284
_t->_dur = dur;
285+
_t->_prevPaletteBlends = 0;
285286
if (_t->_oldSegment) {
286287
_t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition)
287288
for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];
@@ -368,6 +369,7 @@ void Segment::beginDraw(uint16_t prog) {
368369
// minimum blend time is 100ms maximum is 65535ms
369370
#ifndef WLED_SAVE_RAM
370371
unsigned noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
372+
if(noOfBlends > 255) noOfBlends = 255; // safety check
371373
for (unsigned i = 0; i < noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, Segment::_currentPalette, 48);
372374
Segment::_currentPalette = _t->_palT; // copy transitioning/temporary palette
373375
#else
@@ -1192,8 +1194,9 @@ void WS2812FX::finalizeInit() {
11921194
if (busEnd > _length) _length = busEnd;
11931195
// This must be done after all buses have been created, as some kinds (parallel I2S) interact
11941196
bus->begin();
1195-
bus->setBrightness(bri);
1197+
bus->setBrightness(scaledBri(bri));
11961198
}
1199+
BusManager::initializeABL(); // init brightness limiter
11971200
DEBUG_PRINTF_P(PSTR("Heap after buses: %d\n"), ESP.getFreeHeap());
11981201

11991202
Segment::maxWidth = _length;
@@ -1295,7 +1298,7 @@ static uint8_t _add (uint8_t a, uint8_t b) { unsigned t = a + b; return t
12951298
static uint8_t _subtract (uint8_t a, uint8_t b) { return b > a ? (b - a) : 0; }
12961299
static uint8_t _difference(uint8_t a, uint8_t b) { return b > a ? (b - a) : (a - b); }
12971300
static uint8_t _average (uint8_t a, uint8_t b) { return (a + b) >> 1; }
1298-
#ifdef CONFIG_IDF_TARGET_ESP32C3
1301+
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
12991302
static uint8_t _multiply (uint8_t a, uint8_t b) { return ((a * b) + 255) >> 8; } // faster than division on C3 but slightly less accurate
13001303
#else
13011304
static uint8_t _multiply (uint8_t a, uint8_t b) { return (a * b) / 255; } // origianl uses a & b in range [0,1]
@@ -1306,10 +1309,10 @@ static uint8_t _darken (uint8_t a, uint8_t b) { return a < b ? a : b; }
13061309
static uint8_t _screen (uint8_t a, uint8_t b) { return 255 - _multiply(~a,~b); } // 255 - (255-a)*(255-b)/255
13071310
static uint8_t _overlay (uint8_t a, uint8_t b) { return b < 128 ? 2 * _multiply(a,b) : (255 - 2 * _multiply(~a,~b)); }
13081311
static uint8_t _hardlight (uint8_t a, uint8_t b) { return a < 128 ? 2 * _multiply(a,b) : (255 - 2 * _multiply(~a,~b)); }
1309-
#ifdef CONFIG_IDF_TARGET_ESP32C3
1310-
static uint8_t _softlight (uint8_t a, uint8_t b) { return (((b * b * (255 - 2 * a) + 255) >> 8) + 2 * a * b + 255) >> 8; } // Pegtop's formula (1 - 2a)b^2 + 2ab
1312+
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3)
1313+
static uint8_t _softlight (uint8_t a, uint8_t b) { return (((b * b * (255 - 2 * a))) + ((2 * a * b + 256) << 8)) >> 16; } // Pegtop's formula (1 - 2a)b^2
13111314
#else
1312-
static uint8_t _softlight (uint8_t a, uint8_t b) { return (b * b * (255 - 2 * a) / 255 + 2 * a * b) / 255; } // Pegtop's formula (1 - 2a)b^2 + 2ab
1315+
static uint8_t _softlight (uint8_t a, uint8_t b) { return (b * b * (255 - 2 * a) + 255 * 2 * a * b) / (255 * 255); } // Pegtop's formula (1 - 2a)b^2 + 2ab
13131316
#endif
13141317
static uint8_t _dodge (uint8_t a, uint8_t b) { return _divide(~a,b); }
13151318
static uint8_t _burn (uint8_t a, uint8_t b) { return ~_divide(a,~b); }
@@ -1548,66 +1551,6 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
15481551
Segment::setClippingRect(0, 0); // disable clipping for overlays
15491552
}
15501553

1551-
// To disable brightness limiter we either set output max current to 0 or single LED current to 0
1552-
static uint8_t estimateCurrentAndLimitBri(uint8_t brightness, uint32_t *pixels) {
1553-
unsigned milliAmpsMax = BusManager::ablMilliampsMax();
1554-
if (milliAmpsMax > 0) {
1555-
unsigned milliAmpsTotal = 0;
1556-
unsigned avgMilliAmpsPerLED = 0;
1557-
unsigned lengthDigital = 0;
1558-
bool useWackyWS2815PowerModel = false;
1559-
1560-
for (size_t i = 0; i < BusManager::getNumBusses(); i++) {
1561-
const Bus *bus = BusManager::getBus(i);
1562-
if (!(bus && bus->isDigital() && bus->isOk())) continue;
1563-
unsigned maPL = bus->getLEDCurrent();
1564-
if (maPL == 0 || bus->getMaxCurrent() > 0) continue; // skip buses with 0 mA per LED or max current per bus defined (PP-ABL)
1565-
if (maPL == 255) {
1566-
useWackyWS2815PowerModel = true;
1567-
maPL = 12; // WS2815 uses 12mA per channel
1568-
}
1569-
avgMilliAmpsPerLED += maPL * bus->getLength();
1570-
lengthDigital += bus->getLength();
1571-
// sum up the usage of each LED on digital bus
1572-
uint32_t busPowerSum = 0;
1573-
for (unsigned j = 0; j < bus->getLength(); j++) {
1574-
uint32_t c = pixels[j + bus->getStart()];
1575-
byte r = R(c), g = G(c), b = B(c), w = W(c);
1576-
if (useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation
1577-
busPowerSum += (max(max(r,g),b)) * 3;
1578-
} else {
1579-
busPowerSum += (r + g + b + w);
1580-
}
1581-
}
1582-
// RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
1583-
if (bus->hasWhite()) {
1584-
busPowerSum *= 3;
1585-
busPowerSum >>= 2; //same as /= 4
1586-
}
1587-
// powerSum has all the values of channels summed (max would be getLength()*765 as white is excluded) so convert to milliAmps
1588-
milliAmpsTotal += (busPowerSum * maPL * brightness) / (765*255);
1589-
}
1590-
if (lengthDigital > 0) {
1591-
avgMilliAmpsPerLED /= lengthDigital;
1592-
1593-
if (milliAmpsMax > MA_FOR_ESP && avgMilliAmpsPerLED > 0) { //0 mA per LED and too low numbers turn off calculation
1594-
unsigned powerBudget = (milliAmpsMax - MA_FOR_ESP); //80/120mA for ESP power
1595-
if (powerBudget > lengthDigital) { //each LED uses about 1mA in standby, exclude that from power budget
1596-
powerBudget -= lengthDigital;
1597-
} else {
1598-
powerBudget = 0;
1599-
}
1600-
if (milliAmpsTotal > powerBudget) {
1601-
//scale brightness down to stay in current limit
1602-
unsigned scaleB = powerBudget * 255 / milliAmpsTotal;
1603-
brightness = ((brightness * scaleB) >> 8) + 1;
1604-
}
1605-
}
1606-
}
1607-
}
1608-
return brightness;
1609-
}
1610-
16111554
void WS2812FX::show() {
16121555
if (!_pixels) return; // no pixels allocated, nothing to show
16131556

@@ -1635,10 +1578,6 @@ void WS2812FX::show() {
16351578
show_callback callback = _callback;
16361579
if (callback) callback(); // will call setPixelColor or setRealtimePixelColor
16371580

1638-
// determine ABL brightness
1639-
uint8_t newBri = estimateCurrentAndLimitBri(_brightness, _pixels);
1640-
if (newBri != _brightness) BusManager::setBrightness(newBri);
1641-
16421581
// paint actual pixels
16431582
int oldCCT = Bus::getCCT(); // store original CCT value (since it is global)
16441583
// when cctFromRgb is true we implicitly calculate WW and CW from RGB values (cct==-1)
@@ -1649,7 +1588,11 @@ void WS2812FX::show() {
16491588
if (_pixelCCT) { // cctFromRgb already exluded at allocation
16501589
if (i == 0 || _pixelCCT[i-1] != _pixelCCT[i]) BusManager::setSegmentCCT(_pixelCCT[i], correctWB);
16511590
}
1652-
BusManager::setPixelColor(getMappedPixelIndex(i), realtimeMode && arlsDisableGammaCorrection ? _pixels[i] : gamma32(_pixels[i]));
1591+
1592+
uint32_t c = _pixels[i]; // need a copy, do not modify _pixels directly (no byte access allowed on ESP32)
1593+
if(c > 0 && !(realtimeMode && arlsDisableGammaCorrection))
1594+
c = gamma32(c); // apply gamma correction if enabled note: applying gamma after brightness has too much color loss
1595+
BusManager::setPixelColor(getMappedPixelIndex(i), c);
16531596
}
16541597
Bus::setCCT(oldCCT); // restore old CCT for ABL adjustments
16551598

@@ -1661,9 +1604,6 @@ void WS2812FX::show() {
16611604
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
16621605
BusManager::show();
16631606

1664-
// restore brightness for next frame
1665-
if (newBri != _brightness) BusManager::setBrightness(_brightness);
1666-
16671607
if (diff > 0) { // skip calculation if no time has passed
16681608
size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math
16691609
_cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding
@@ -1728,7 +1668,7 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) {
17281668
if (_brightness == 0) { //unfreeze all segments on power off
17291669
for (const Segment &seg : _segments) seg.freeze = false; // freeze is mutable
17301670
}
1731-
BusManager::setBrightness(b);
1671+
BusManager::setBrightness(scaledBri(b));
17321672
if (!direct) {
17331673
unsigned long t = millis();
17341674
if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon

wled00/FXparticleSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ bool initParticleSystem2D(ParticleSystem2D *&PartSys, uint32_t requestedsources,
11181118
allocsuccess = true;
11191119
break; // allocation succeeded
11201120
}
1121-
numparticles /= 2; // cut number of particles in half and try again
1121+
numparticles = ((numparticles / 2) + 3) & ~0x03; // cut number of particles in half and try again, must be 4 byte aligned
11221122
PSPRINTLN(F("PS 2D alloc failed, trying with less particles..."));
11231123
}
11241124
if (!allocsuccess) {
@@ -1815,7 +1815,7 @@ bool initParticleSystem1D(ParticleSystem1D *&PartSys, const uint32_t requestedso
18151815
allocsuccess = true;
18161816
break; // allocation succeeded
18171817
}
1818-
numparticles /= 2; // cut number of particles in half and try again
1818+
numparticles = ((numparticles / 2) + 3) & ~0x03; // cut number of particles in half and try again, must be 4 byte aligned
18191819
PSPRINTLN(F("PS 1D alloc failed, trying with less particles..."));
18201820
}
18211821
if (!allocsuccess) {

0 commit comments

Comments
 (0)