From a46224254423a99b6a0e501007c055ac3275b99b Mon Sep 17 00:00:00 2001 From: TroyHacks <5659019+troyhacks@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:37:26 -0400 Subject: [PATCH 01/72] Initial 4x downsample PoC for 96Khz sample rate. --- usermods/audioreactive/audio_reactive.h | 2 +- usermods/audioreactive/audio_source.h | 28 +++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index c7fd194ad2..2af22a91b7 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -285,7 +285,7 @@ static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calcula #if !defined(CONFIG_IDF_TARGET_ESP32C3) // audio source parameters and constant -constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms +constexpr SRate_t SAMPLE_RATE = 96000; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms //constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms //constexpr SRate_t SAMPLE_RATE = 20480; // Base sample rate in Hz - 20Khz is experimental. Physical sample time -> 25ms //constexpr SRate_t SAMPLE_RATE = 10240; // Base sample rate in Hz - previous default. Physical sample time -> 50ms diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index 3c257d7814..682ea3943f 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -166,6 +166,7 @@ class AudioSource { bool _i2sMaster; // when false, ESP32 will be in I2S SLAVE mode (for devices that only operate in MASTER mode). Only workds in newer IDF >= 4.4.x float _sampleScale; // pre-scaling factor for I2S samples I2S_datatype newSampleBuffer[I2S_SAMPLES_MAX+4] = { 0 }; // global buffer for i2s_read + I2S_datatype newSampleBuffer4x[(I2S_SAMPLES_MAX*4)+4] = { 0 }; // global buffer for i2s_read }; /* Basic I2S microphone source @@ -174,12 +175,12 @@ class AudioSource { */ class I2SSource : public AudioSource { public: - I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=true) : + I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=false) : AudioSource(sampleRate, blockSize, sampleScale, i2sMaster) { _config = { .mode = i2sMaster ? i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX) : i2s_mode_t(I2S_MODE_SLAVE | I2S_MODE_RX), - .sample_rate = _sampleRate, - .bits_per_sample = I2S_SAMPLE_RESOLUTION, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates + .sample_rate = _sampleRate, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates + .bits_per_sample = I2S_SAMPLE_RESOLUTION, .channel_format = I2S_MIC_CHANNEL, #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S), @@ -357,9 +358,17 @@ class I2SSource : public AudioSource { memset(buffer, 0, sizeof(float) * num_samples); // clear output buffer I2S_datatype *newSamples = newSampleBuffer; // use global input buffer + I2S_datatype *newSamples4x = newSampleBuffer4x; // use oversampling global input buffer + if (num_samples > I2S_SAMPLES_MAX) num_samples = I2S_SAMPLES_MAX; // protect the buffer from overflow - err = i2s_read(I2S_NUM_0, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); + if (_sampleRate == 96000) { + num_samples *= 4; + err = i2s_read(I2S_NUM_0, (void *)newSamples4x, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); + } else { + err = i2s_read(I2S_NUM_0, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); + } + if (err != ESP_OK) { DEBUGSR_PRINTF("Failed to get samples: %d\n", err); return; @@ -371,6 +380,17 @@ class I2SSource : public AudioSource { return; } + if (_sampleRate == 96000) { + int final_samples = num_samples/4; + for (int i = 0; i < final_samples; i++) { + newSamples[i] = 0; + for (int x = 0; x < 4; x++) { + newSamples[i] += newSamples4x[(i*4)+x]/4; + } + } + num_samples = final_samples; + } + // Store samples in sample buffer and update DC offset for (int i = 0; i < num_samples; i++) { From ed897968b928b3ab09879267d5561edb972209ed Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Sun, 3 Mar 2024 15:29:43 -0500 Subject: [PATCH 02/72] Decimation instead of averaging. --- usermods/audioreactive/audio_source.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index ae94fb8659..cf13f953f3 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -382,14 +382,15 @@ class I2SSource : public AudioSource { } if (_sampleRate == 96000) { - int final_samples = num_samples/4; - for (int i = 0; i < final_samples; i++) { - newSamples[i] = 0; - for (int x = 0; x < 4; x++) { - newSamples[i] += newSamples4x[(i*4)+x]/4; - } + for (int i = 0; i < num_samples/4; i++) { + // Code for averaging. Decimation seems fine too. + // newSamples[i] = 0; + // for (int x = 0; x < 4; x++) { + // newSamples[i] += newSamples4x[(i*4)+x]/4; + // } + newSamples[i] = newSamples4x[(i*4)]; // every 4th sample, skip the rest. } - num_samples = final_samples; + num_samples /= 4; // back to 512 samples } // Store samples in sample buffer and update DC offset From 639e911e4b50e142f8c074820b7b51597d0dc717 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:19:58 -0500 Subject: [PATCH 03/72] Decimation wins for better speed with accuracy --- usermods/audioreactive/audio_source.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index cf13f953f3..5acbed4686 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -359,13 +359,13 @@ class I2SSource : public AudioSource { memset(buffer, 0, sizeof(float) * num_samples); // clear output buffer I2S_datatype *newSamples = newSampleBuffer; // use global input buffer - I2S_datatype *newSamples4x = newSampleBuffer4x; // use oversampling global input buffer + I2S_datatype *newSamples_buff = newSampleBuffer4x; // use oversampling global input buffer if (num_samples > I2S_SAMPLES_MAX) num_samples = I2S_SAMPLES_MAX; // protect the buffer from overflow if (_sampleRate == 96000) { num_samples *= 4; - err = i2s_read(I2S_NUM_0, (void *)newSamples4x, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); + err = i2s_read(I2S_NUM_0, (void *)newSamples_buff, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); } else { err = i2s_read(I2S_NUM_0, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); } @@ -382,13 +382,10 @@ class I2SSource : public AudioSource { } if (_sampleRate == 96000) { - for (int i = 0; i < num_samples/4; i++) { - // Code for averaging. Decimation seems fine too. - // newSamples[i] = 0; - // for (int x = 0; x < 4; x++) { - // newSamples[i] += newSamples4x[(i*4)+x]/4; - // } - newSamples[i] = newSamples4x[(i*4)]; // every 4th sample, skip the rest. + int current = 0; + for (int i = 0; i < 2048; i += 4) { + newSamples[current] = newSamples_buff[i]; + current++; } num_samples /= 4; // back to 512 samples } From c5d7e42faac79fd7832e1a07c974b576ef90547c Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:39:19 -0500 Subject: [PATCH 04/72] Quick hack to adjust color balance on some LEDs --- wled00/bus_manager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 14e0888acc..ba56415883 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -74,7 +74,7 @@ uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaul uint8_t swapW = defaultColorOrder >> 4; for (uint8_t i = 0; i < _count; i++) { if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) { - return _mappings[i].colorOrder | (swapW << 4); + return _mappings[i].colorOrder | (swapW << 4); // WLED-MM/TroyHacks: Disabling this disables color order mapping. } } return defaultColorOrder; @@ -172,6 +172,10 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break; } } + if (_colorOrder != co) { + c = RGBW32(dim8_lin(R(c)), dim8_lin(G(c)), dim8_lin(B(c)), 0); // WLED-MM/TroyHacks - remap pixels not in the default color order + co = _colorOrder; // keep the original color order, as this is a hack. :) + } PolyBus::setPixelColor(_busPtr, _iType, pix, c, co); } From 283a7284b491bf3d11f663b25d86bb17f20549b3 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:15:46 -0400 Subject: [PATCH 05/72] ES8311 support added for the ESP32-P4 EV board with mic. --- usermods/audioreactive/audio_reactive.h | 16 +++- usermods/audioreactive/audio_source.h | 100 ++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 1c46e33abf..cbf2152351 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -2022,7 +2022,16 @@ class AudioReactive : public Usermod { if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin; if (i2c_sda >= 0) sdaPin = -1; // -1 = use global if (i2c_scl >= 0) sclPin = -1; - + case 9: + DEBUGSR_PRINTLN(F("AR: ES8311 Source (Mic)")); + audioSource = new ES8311Source(SAMPLE_RATE, BLOCK_SIZE, 1.0f); + //useInputFilter = 0; // to disable low-cut software filtering and restore previous behaviour + delay(100); + // WLEDMM align global pins + if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined) + if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin; + if (i2c_sda >= 0) sdaPin = -1; // -1 = use global + if (i2c_scl >= 0) sclPin = -1; if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); break; @@ -2934,6 +2943,11 @@ class AudioReactive : public Usermod { #else oappend(SET_F("addOption(dd,'AC101 ☾',8);")); #endif + #if SR_DMTYPE==9 + oappend(SET_F("addOption(dd,'ES8311 ☾ (⎌)',9);")); + #else + oappend(SET_F("addOption(dd,'ES8311 ☾',9);")); + #endif #ifdef SR_SQUELCH oappend(SET_F("addInfo(ux+':config:squelch',1,'⎌ ")); oappendi(SR_SQUELCH); oappend("');"); // 0 is field type, 1 is actual field #endif diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index 77111446b8..61f37c4f55 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -640,6 +640,106 @@ class ES8388Source : public I2SSource { }; +/* ES8311 Sound Module + This is an I2S sound processing unit that requires initialization over + I2C before I2S data can be received. +*/ +class ES8311Source : public I2SSource { + private: + // I2C initialization functions for es8311 + void _es8311I2cBegin() { + Wire.setClock(100000); + } + + void _es8311I2cWrite(uint8_t reg, uint8_t val) { + #ifndef ES8311_ADDR + #define ES8311_ADDR 0x18 // default address is... foggy + #endif + Wire.beginTransmission(ES8311_ADDR); + Wire.write((uint8_t)reg); + Wire.write((uint8_t)val); + uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK + if (i2cErr != 0) { + DEBUGSR_PRINTF("AR: ES8311 I2C write failed with error=%d (addr=0x%X, reg 0x%X, val 0x%X).\n", i2cErr, ES8311_ADDR, reg, val); + } + } + + void _es8311InitAdc() { + // + // Currently only tested with the ESP32-P4 EV board with the onboard mic. + // Datasheet with I2C commands: https://dl.xkwy2018.com/downloads/RK3588/01_Official%20Release/04_Product%20Line%20Branch_NVR/02_Key%20Device%20Specifications/ES8311%20DS.pdf + // + _es8311I2cBegin(); + _es8311I2cWrite(0x00, 0b00011111); // RESET, default value + _es8311I2cWrite(0x45, 0b00000000); // GP, default value + _es8311I2cWrite(0x01, 0b00111010); // CLOCK MANAGER was 0b00110000 trying 0b00111010 (MCLK enable?) + + _es8311I2cWrite(0x02, 0b00000000); // 22050hz calculated + _es8311I2cWrite(0x05, 0b00000000); // 22050hz calculated + _es8311I2cWrite(0x03, 0b00010000); // 22050hz calculated + _es8311I2cWrite(0x04, 0b00010000); // 22050hz calculated + _es8311I2cWrite(0x07, 0b00000000); // 22050hz calculated + _es8311I2cWrite(0x08, 0b11111111); // 22050hz calculated + _es8311I2cWrite(0x06, 0b11100011); // 22050hz calculated + + _es8311I2cWrite(0x16, 0b00100000); // ADC was 0b00000011 trying 0b00100100 now + _es8311I2cWrite(0x0B, 0b00000000); // SYSTEM at default + _es8311I2cWrite(0x0C, 0b00100000); // SYSTEM was 0b00001111 trying 0b00100000 + _es8311I2cWrite(0x10, 0b00010011); // SYSTEM was 0b00011111 trying 0b00010011 + _es8311I2cWrite(0x11, 0b01111100); // SYSTEM was 0b01111111 trying 0b01111100 + _es8311I2cWrite(0x00, 0b11000000); // *** RESET (again - seems important?) + _es8311I2cWrite(0x01, 0b00111010); // CLOCK MANAGER was 0b00111111 trying 0b00111010 (again??) + _es8311I2cWrite(0x14, 0b00010000); // *** SYSTEM was 0b00011010 trying 0b00010000 (or 0b01111010) (PGA gain) + _es8311I2cWrite(0x12, 0b00000000); // SYSTEM - DAC, likely don't care + _es8311I2cWrite(0x13, 0b00010000); // SYSTEM - output, likely don't cate + _es8311I2cWrite(0x09, 0b00001000); // SDP IN (likely don't care) was 0b00001100 (16-bit) - changed to 0b00001000 (I2S 32-bit) + _es8311I2cWrite(0x0A, 0b00001000); // *** SDP OUT, was 0b00001100 trying 0b00001000 (I2S 32-bit) + _es8311I2cWrite(0x0E, 0b00000010); // *** SYSTEM was 0b00000010 trying 0b00011010 (seems best so far!) (or 0b00000010) + _es8311I2cWrite(0x0F, 0b01000100); // SYSTEM was 0b01000100 + _es8311I2cWrite(0x15, 0b00000000); // ADC soft ramp (disabled) + _es8311I2cWrite(0x1B, 0b00000101); // ADC soft-mute was 0b00000101 + _es8311I2cWrite(0x1C, 0b01100101); // ADC EQ and offset freeze was 0b01100101 (bad at 0b00101100) + _es8311I2cWrite(0x17, 0b10111111); // ADC volume was 0b11111111 trying ADC volume 0b10111111 = 0db (maxgain) 0x16 + _es8311I2cWrite(0x44, 0b00000000); // 0b10000000 - loopback test. on: 0x88; off: 0x00; mic--" speak + + } + + public: + ES8311Source(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=true) : + I2SSource(sampleRate, blockSize, sampleScale, i2sMaster) { + _config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + }; + + void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { + DEBUGSR_PRINTLN("es8311Source:: initialize();"); + + // if ((i2sckPin < 0) || (mclkPin < 0)) { // WLEDMM not sure if this check is needed here, too + // ERRORSR_PRINTF("\nAR: invalid I2S es8311 pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); + // return; + // } + // BUG: "use global I2C pins" are valid as -1, and -1 is seen as invalid here. + // Workaround: Set I2C pins here, which will also set them globally. + // Bug also exists in ES7243. + if ((i2c_sda < 0) || (i2c_scl < 0)) { // check that global I2C pins are not "undefined" + ERRORSR_PRINTF("\nAR: invalid es8311 global I2C pins: SDA=%d, SCL=%d\n", i2c_sda, i2c_scl); + return; + } + if (!pinManager.joinWire(i2c_sda, i2c_scl)) { // WLEDMM specific: start I2C with globally defined pins + ERRORSR_PRINTF("\nAR: failed to join I2C bus with SDA=%d, SCL=%d\n", i2c_sda, i2c_scl); + return; + } + + // First route mclk, then configure ADC over I2C, then configure I2S + _es8311InitAdc(); + I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin); + } + + void deinitialize() { + I2SSource::deinitialize(); + } + +}; + class WM8978Source : public I2SSource { private: // I2C initialization functions for WM8978 From 3b46af1101212c2106cd04081edb5a8789ae3c38 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Sat, 23 Nov 2024 11:27:32 -0500 Subject: [PATCH 06/72] Make IP clickable via serial monitor --- wled00/wled.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 08f5171d01..17efdceb73 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1352,9 +1352,19 @@ void WLED::handleConnection() initAP(); } } else if (!interfacesInited) { //newly connected - DEBUG_PRINTLN(""); - USER_PRINT(F("Connected! IP address: ")); + USER_PRINTLN(""); + USER_PRINT(F("Connected! IP address: http://")); USER_PRINTLN(Network.localIP()); + //if (Network.isEthernet()) { + // #if ESP32 + // USER_PRINT(ETH.localIP()); + // USER_PRINTLN(" via Ethernet"); + // #endif + //} else { + // USER_PRINT(Network.localIP()); + // USER_PRINTLN(" via WiFi"); + //} + if (improvActive) { if (improvError == 3) sendImprovStateResponse(0x00, true); sendImprovStateResponse(0x04); From 37c7bb11b366e07cd9f63c660789c71512361115 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 18:34:53 +0000 Subject: [PATCH 07/72] Update animartrix for bugfixes for corrupt state for master_speed, speed issues with SM8, Scaledemo1 and Hot_Blob --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 0b8b92ed80..c47ddbd3ad 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1062,7 +1062,7 @@ AR_build_flags = -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT ;; WLE AR_lib_deps = https://github.com/softhack007/arduinoFFT.git#develop @ 1.9.2 ;; used for USERMOD_AUDIOREACTIVE - optimized version, 10% faster on -S2/-C3 animartrix_build_flags = -D USERMOD_ANIMARTRIX ;; WLEDMM usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick -animartrix_lib_deps = https://github.com/netmindz/animartrix.git#18bf17389e57c69f11bc8d04ebe1d215422c7fb7 +animartrix_lib_deps = https://github.com/netmindz/animartrix.git#ccb11dd9a4ec4ff6e7bdf617f6651cced4ed9826 ;; Speed fixes animartrix_lib_ignore = animartrix ;; to remove the animartrix lib dependancy (saves a few bytes) DMXin_build_flags = -D WLED_ENABLE_DMX_INPUT ;; WLEDMM DMX physical input - requires ESP-IDF v4.4.x From 61c2ba98b7dbed99554cf5d138b23fd9eeabc64c Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 24 Nov 2024 17:32:59 +0100 Subject: [PATCH 08/72] HUB75 small speedup gave me 1-3 extra FPS on -S3 with 128x64 --- wled00/bus_manager.cpp | 12 ++++++------ wled00/bus_manager.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index e414bf61ef..5dd51d0afb 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -1056,7 +1056,7 @@ BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWh USER_PRINT(F("heap usage: ")); USER_PRINTLN(int(lastHeap - ESP.getFreeHeap())); } -void __attribute__((hot)) BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c) { +void __attribute__((hot)) IRAM_ATTR BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c) { if (!_valid || pix >= _len) return; // if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT @@ -1097,12 +1097,12 @@ void __attribute__((hot)) BusHub75Matrix::setPixelColor(uint16_t pix, uint32_t c #endif } -uint32_t BusHub75Matrix::getPixelColor(uint16_t pix) const { +uint32_t IRAM_ATTR BusHub75Matrix::getPixelColor(uint16_t pix) const { if (!_valid || pix >= _len || !_ledBuffer) return BLACK; return uint32_t(_ledBuffer[pix].scale8(_bri)) & 0x00FFFFFF; // scale8() is needed to mimic NeoPixelBus, which returns scaled-down colours } -uint32_t __attribute__((hot)) BusHub75Matrix::getPixelColorRestored(uint16_t pix) const { +uint32_t __attribute__((hot)) IRAM_ATTR BusHub75Matrix::getPixelColorRestored(uint16_t pix) const { if (!_valid || pix >= _len || !_ledBuffer) return BLACK; return uint32_t(_ledBuffer[pix]) & 0x00FFFFFF; } @@ -1117,7 +1117,7 @@ void BusHub75Matrix::setBrightness(uint8_t b, bool immediate) { if (display) display->setBrightness(_bri); } -void __attribute__((hot)) BusHub75Matrix::show(void) { +void __attribute__((hot)) IRAM_ATTR BusHub75Matrix::show(void) { if (!_valid) return; MatrixPanel_I2S_DMA* display = BusHub75Matrix::activeDisplay; if (!display) return; @@ -1277,8 +1277,8 @@ void BusManager::removeAll() { lastend = 0; } -void BusManager::show() { - for (uint8_t i = 0; i < numBusses; i++) { +void __attribute__((hot)) BusManager::show() { + for (unsigned i = 0; i < numBusses; i++) { busses[i]->show(); } } diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index cef0286d00..69f3aa2d74 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -191,7 +191,7 @@ class Bus { inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; } inline static uint8_t getGlobalAWMode() { return _gAWM; } - inline uint32_t restore_Color_Lossy(uint32_t c, uint8_t restoreBri) const { // shamelessly grabbed from upstream, who grabbed from NPB, who .. + inline static uint32_t restore_Color_Lossy(uint32_t c, uint8_t restoreBri) { // shamelessly grabbed from upstream, who grabbed from NPB, who .. if (restoreBri < 255) { uint8_t* chan = (uint8_t*) &c; for (uint_fast8_t i=0; i<4; i++) { From ce8fc8930e3d5547592f0103097eda6ed76d8c3e Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 24 Nov 2024 17:45:25 +0100 Subject: [PATCH 09/72] const const const small speedup by declaring some functions "const" --- wled00/FX.cpp | 4 ++-- wled00/FX.h | 6 +++--- wled00/FX_2Dfcn.cpp | 2 +- wled00/FX_fcn.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2b45d37aa3..ce5bdc7302 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4763,7 +4763,7 @@ class AuroraWave { alive = true; } - CRGB getColorForLED(int ledIndex) { + CRGB getColorForLED(int ledIndex) const { if(ledIndex < center - width || ledIndex > center + width) return 0; //Position out of range of this wave CRGB rgb; @@ -4818,7 +4818,7 @@ class AuroraWave { } }; - bool stillAlive() { + bool stillAlive() const { return alive; }; }; diff --git a/wled00/FX.h b/wled00/FX.h index c06934629d..7f53202d5b 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -420,7 +420,7 @@ typedef struct Segment { }; size_t _dataLen; // WLEDMM uint16_t is too small static size_t _usedSegmentData; // WLEDMM uint16_t is too small - void setPixelColorXY_fast(int x, int y,uint32_t c, uint32_t scaled_col, int cols, int rows); // set relative pixel within segment with color - faster, but no error checking!!! + void setPixelColorXY_fast(int x, int y,uint32_t c, uint32_t scaled_col, int cols, int rows) const; // set relative pixel within segment with color - faster, but no error checking!!! bool _isSimpleSegment = false; // simple = no grouping or spacing - mirror, transpose or reverse allowed bool _isSuperSimpleSegment = false; // superSimple = no grouping or spacing, no mirror - only transpose or reverse allowed @@ -606,7 +606,7 @@ typedef struct Segment { // transition functions void startTransition(uint16_t dur); // transition has to start before actual segment values change void handleTransition(void); - uint16_t progress(void); //transition progression between 0-65535 + uint16_t progress(void) const; //transition progression between 0-65535 // WLEDMM method inlined for speed (its called at each setPixelColor) inline uint8_t currentBri(uint8_t briNew, bool useCct = false) { @@ -621,7 +621,7 @@ typedef struct Segment { uint8_t currentMode(uint8_t modeNew); uint32_t currentColor(uint8_t slot, uint32_t colorNew); - CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal); + CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal) const; void setCurrentPalette(void); // 1D strip diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index f6d2bc0b6c..6f7f97b236 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -272,7 +272,7 @@ void Segment::startFrame(void) { // Simplified version of Segment::setPixelColorXY - without error checking. Does not support grouping or spacing // * expects scaled color (final brightness) as additional input parameter, plus segment virtualWidth() and virtualHeight() -void IRAM_ATTR __attribute__((hot)) Segment::setPixelColorXY_fast(int x, int y, uint32_t col, uint32_t scaled_col, int cols, int rows) //WLEDMM +void IRAM_ATTR __attribute__((hot)) Segment::setPixelColorXY_fast(int x, int y, uint32_t col, uint32_t scaled_col, int cols, int rows) const //WLEDMM { unsigned i = UINT_MAX; bool sameColor = false; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index f98f5dcbc9..1c5779464b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -311,7 +311,7 @@ void Segment::setUpLeds() { } } -CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { +CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) const { static unsigned long _lastPaletteChange = millis() - 990000; // perhaps it should be per segment //WLEDMM changed init value to avoid pure orange after startup static CRGBPalette16 randomPalette = CRGBPalette16(DEFAULT_COLOR); static CRGBPalette16 prevRandomPalette = CRGBPalette16(CRGB(BLACK)); @@ -452,7 +452,7 @@ void Segment::startTransition(uint16_t dur) { } // transition progression between 0-65535 -uint16_t IRAM_ATTR_YN Segment::progress() { +uint16_t IRAM_ATTR_YN Segment::progress() const { if (!transitional || !_t) return 0xFFFFU; unsigned long timeNow = millis(); if (timeNow - _t->_start > _t->_dur || _t->_dur == 0) return 0xFFFFU; From eb56a7638d827f456b713a217431a1b779117559 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sun, 24 Nov 2024 17:37:11 +0000 Subject: [PATCH 10/72] Update animartrix version with no dirty state --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index c47ddbd3ad..13b45feb7c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1062,7 +1062,7 @@ AR_build_flags = -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT ;; WLE AR_lib_deps = https://github.com/softhack007/arduinoFFT.git#develop @ 1.9.2 ;; used for USERMOD_AUDIOREACTIVE - optimized version, 10% faster on -S2/-C3 animartrix_build_flags = -D USERMOD_ANIMARTRIX ;; WLEDMM usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick -animartrix_lib_deps = https://github.com/netmindz/animartrix.git#ccb11dd9a4ec4ff6e7bdf617f6651cced4ed9826 ;; Speed fixes +animartrix_lib_deps = https://github.com/netmindz/animartrix.git#657f754783268b648e1d56b3cd31c810379d0c89 ;; Dirty state fix animartrix_lib_ignore = animartrix ;; to remove the animartrix lib dependancy (saves a few bytes) DMXin_build_flags = -D WLED_ENABLE_DMX_INPUT ;; WLEDMM DMX physical input - requires ESP-IDF v4.4.x From 5a2096ab2133e2b0c56fefa5a448ff954abeca4a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 24 Nov 2024 19:09:35 +0100 Subject: [PATCH 11/72] partly inline getPixelColorXY allows the compiler to inline access to ledsrgb[] , while still keeping the "no buffer" case in a separate function so program size does not blow up. --> up to 10% faster --- wled00/FX.h | 18 +++++++++++++++--- wled00/FX_2Dfcn.cpp | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index 7f53202d5b..beba051747 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -721,10 +721,21 @@ typedef struct Segment { uint32_t scaled_col = (_brightness == 255) ? col : color_fade(col, _brightness); // calculate final color setPixelColorXY_fast(x, y, col, scaled_col, int(_2dWidth), int(_2dHeight)); // call "fast" function - } -} + } + } + inline uint32_t getPixelColorXY(int x, int y) const { + // minimal sanity checks + if (!_isValid2D) return 0; // not active + if ((unsigned(x) >= _2dWidth) || (unsigned(y) >= _2dHeight)) return 0 ; // check if (x,y) are out-of-range - due to 2's complement, this also catches negative values + if (ledsrgb) { + int i = x + y*_2dWidth; // avoid error checking done by XY() - be optimistic about ranges of x and y + return RGBW32(ledsrgb[i].r, ledsrgb[i].g, ledsrgb[i].b, 0); + } + else return getPixelColorXY_part2(x, y, int(_2dWidth), int(_2dHeight)); // call "no ledsrgb" function to retrieve pixel from bus driver + } #else void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color + uint32_t __attribute__((pure)) getPixelColorXY(int x, int y) const { return getPixelColorXY_slow(x,y);} #endif inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); } inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } @@ -735,7 +746,8 @@ typedef struct Segment { inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } //#endif - uint32_t __attribute__((pure)) getPixelColorXY(int x, int y) const; + uint32_t __attribute__((pure)) getPixelColorXY_part2(int x, int y, int cols, int rows) const; + uint32_t __attribute__((pure)) getPixelColorXY_slow(int x, int y) const; // 2D support functions void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 6f7f97b236..4d58143bff 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -454,8 +454,18 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa, bool fast #endif } -// returns RGBW values of pixel -uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const { +// WLEDMM this function is only called by getPixelColorXY, in case we don't have the ledsrgb buffer! +uint32_t IRAM_ATTR_YN Segment::getPixelColorXY_part2(int x, int y, int cols, int rows) const { + if (reverse ) x = cols - x - 1; + if (reverse_y) y = rows - y - 1; + if (transpose) std::swap(x,y); // swap X & Y if segment transposed + const uint_fast16_t groupLength_ = groupLength(); // WLEDMM small optimization + x *= groupLength_; // expand to physical pixels + y *= groupLength_; // expand to physical pixels + return strip.getPixelColorXYRestored(start + x, startY + y); +} + +uint32_t IRAM_ATTR_YN Segment::getPixelColorXY_slow(int x, int y) const { // WLEDMM fallback for non-fastpath builds if (x<0 || y<0 || !isActive()) return 0; // not active or out-of range if (ledsrgb) { int i = XY(x,y); From 7ad67b5f64ae28f8eb43a0224bc86a89c04e7b70 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 25 Nov 2024 13:35:16 +0100 Subject: [PATCH 12/72] blurz effect upgrade * avoid black spots * better randomness on esp32 * new mode "FreqMap" (checkbox) - blob location follows major frequency * new mode "GEQ scanner" (checkbox) - blob location based on GEQ band --> looks cool with Pinwheel or Bar or Arc mapping --> will be even better with the new Waterfall mapping mode --- wled00/FX.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index ce5bdc7302..b7b61daf48 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -7589,6 +7589,8 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. um_data_t *um_data = getAudioData(); uint8_t *fftResult = (uint8_t*)um_data->u_data[2]; float volumeSmth = *(float*)um_data->u_data[0]; + float FFT_MajorPeak = *(float*)um_data->u_data[4]; + if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; if (SEGENV.call == 0) { SEGMENT.setUpLeds(); // not sure if necessary @@ -7598,6 +7600,10 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. SEGENV.step = 0; // last pixel color } + #if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improves randonmess + #endif + int fadeoutDelay = (256 - SEGMENT.speed) / 24; if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(max(SEGMENT.speed, (uint8_t)1)); @@ -7606,10 +7612,25 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. } if ((SEGENV.aux1 < SEGLEN) && (volumeSmth > 1.0f)) SEGMENT.setPixelColor(SEGENV.aux1,SEGENV.step); // "repaint" last pixel after blur + unsigned freqBand = SEGENV.aux0 % 16; uint16_t segLoc = random16(SEGLEN); + + if (SEGENV.check1) { // FreqMap mode : blob location by major frequency + int freqLocn; + unsigned maxLen = (SEGENV.check2) ? max(1, SEGLEN-16): SEGLEN; // usable segment length - leave 16 pixels when embedding "GEQ scan" + freqLocn = roundf((log10f((float)FFT_MajorPeak) - 1.78f) * float(maxLen)/(MAX_FREQ_LOG10 - 1.78f)); // log10 frequency range is from 1.78 to 3.71. Let's scale to SEGLEN. // WLEDMM proper rounding + if (freqLocn < 1) freqLocn = 0; // avoid underflow + segLoc = (SEGENV.check2) ? freqLocn + freqBand : freqLocn; + } else if (SEGENV.check2) { // GEQ Scanner mode: blob location is defined by frequency band + random offset + float bandWidth = float(SEGLEN) / 16.0f; + int bandStart = roundf(bandWidth * freqBand); + segLoc = bandStart + random16(max(1, int(bandWidth))); + } + segLoc = max(uint16_t(0), min(uint16_t(SEGLEN-1), segLoc)); // fix overflows + if (SEGLEN < 2) segLoc = 0; // WLEDMM just to be sure - unsigned pixColor = (2*fftResult[SEGENV.aux0%16]*240)/max(1, SEGLEN-1); // WLEDMM avoid uint8 overflow, and preserve pixel parameters for redraw - unsigned pixIntensity = min((unsigned)(2.0f*fftResult[SEGENV.aux0%16]), 255U); + unsigned pixColor = (2*fftResult[freqBand]*240)/max(1, SEGLEN-1); // WLEDMM avoid uint8 overflow, and preserve pixel parameters for redraw + unsigned pixIntensity = min((unsigned)(2.0f*fftResult[freqBand]), 255U); if (volumeSmth > 1.0f) { SEGMENT.setPixelColor(segLoc, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint16_t)pixColor, false, PALETTE_SOLID_WRAP, 0),(uint8_t)pixIntensity)); @@ -7619,12 +7640,12 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. SEGMENT.blur(max(SEGMENT.intensity, (uint8_t)1)); SEGENV.aux0 ++; SEGENV.aux0 %= 16; // make sure it doesn't cross 16 - SEGMENT.setPixelColor(segLoc, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint16_t)pixColor, false, PALETTE_SOLID_WRAP, 0),(uint8_t)pixIntensity)); // repaint center pixel after blur + SEGMENT.addPixelColor(segLoc, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint16_t)pixColor, false, PALETTE_SOLID_WRAP, 0),(uint8_t)pixIntensity/2)); // repaint center pixel after blur } else SEGMENT.blur(max(SEGMENT.intensity, (uint8_t)1)); // silence - just blur it again - return FRAMETIME_FIXED; + return SEGENV.check2 ? FRAMETIME : (3*FRAMETIME_FIXED/4); // faster updates in GEQ Scanner mode } // mode_blurz() -static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz ☾@Fade rate,Blur;!,Color mix;!;01f;sx=48,ix=127,m12=0,si=0"; // Pixels, Beatsin +static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz Plus ☾@Fade rate,Blur,,,,FreqMap ☾,GEQ Scanner ☾,;!,Color mix;!;01f;sx=48,ix=127,m12=7,si=0"; // Pinwheel, Beatsin #endif ///////////////////////// From 7d10bd0cd99982b4e2332d687c9f19f4e8dc566b Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 25 Nov 2024 15:27:53 +0100 Subject: [PATCH 13/72] Allow TV Simulator on single LED segments I've checked the code - nothing preventing the effect to run with SEGLEN=1 --- wled00/FX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index b7b61daf48..26bb99e259 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4720,7 +4720,7 @@ uint16_t mode_tv_simulator(void) { return FRAMETIME; } -static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;"; +static const char _data_FX_MODE_TV_SIMULATOR[] PROGMEM = "TV Simulator@!,!;;!;01"; /* From 12ef7cb2855c6e2d955ff33fc860fd4948b0076d Mon Sep 17 00:00:00 2001 From: Will Miles Date: Wed, 23 Oct 2024 19:47:44 -0400 Subject: [PATCH 14/72] Enable NON32XFER_HANDLER on ESP8266 This is a platform feature that asks forgiveness for PROGMEM misuse: it adds a handler such that incorrectly used PROGMEM will work without crashing, just really, *really* inefficiently. Given that most of our real-world use cases for PROGMEM strings are relatively infrequent text calls, we can err on the side of developer convenience and address performance problems if and when they arise. --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 13b45feb7c..e49c32dabd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -291,6 +291,7 @@ build_flags = ; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'" ; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown -D USERMOD_AUDIOREACTIVE + -D NON32XFER_HANDLER ;; ask forgiveness for PROGMEM misuse lib_deps = #https://github.com/lorol/LITTLEFS.git From 827cf8786045eb2853ff640efd9407925d8db683 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:01:05 +0200 Subject: [PATCH 15/72] Merge pull request #4188 from LuisFadini/0_15_brt_timezone Added BRT timezone --- wled00/data/settings_time.htm | 1 + wled00/ntp.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/wled00/data/settings_time.htm b/wled00/data/settings_time.htm index 52f3385ea2..0c6e68a790 100644 --- a/wled00/data/settings_time.htm +++ b/wled00/data/settings_time.htm @@ -182,6 +182,7 @@

Time setup

+
UTC offset: seconds (max. 18 hours)
Current local time is unknown.
diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index fb5e85b3ae..ddebd9499a 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -48,6 +48,7 @@ Timezone* tz = nullptr; #define TZ_ANCHORAGE 20 #define TZ_MX_CENTRAL 21 #define TZ_PAKISTAN 22 +#define TZ_BRASILIA 23 #define TZ_INIT 255 byte tzCurrent = TZ_INIT; //uninitialized @@ -168,6 +169,11 @@ void updateTimezone() { tcrStandard = tcrDaylight; break; } + case TZ_BRASILIA : { + tcrDaylight = {Last, Sun, Mar, 1, -180}; //Brasília Standard Time = UTC - 3 hours + tcrStandard = tcrDaylight; + break; + } } tzCurrent = currentTimezone; From ae076727104040c5419b6b681f5f6d889643f46b Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:20:07 +0100 Subject: [PATCH 16/72] swirl effect bugfix avoid drawing outside of visible area --- wled00/FX.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 26bb99e259..62edcfe7c1 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -6214,9 +6214,9 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g uint16_t ms = strip.now; - SEGMENT.addPixelColorXY(i, m, ColorFromPalette(SEGPALETTE, ms/29, 255, LINEARBLEND)); - SEGMENT.addPixelColorXY(j, n, ColorFromPalette(SEGPALETTE, ms/41, 255, LINEARBLEND)); - SEGMENT.addPixelColorXY(k, p, ColorFromPalette(SEGPALETTE, ms/73, 255, LINEARBLEND)); + if (i Date: Tue, 26 Nov 2024 15:33:56 +0100 Subject: [PATCH 17/72] allow tri fade effect on 0D (single pixel) --- wled00/FX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 62edcfe7c1..a985386252 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1743,7 +1743,7 @@ uint16_t mode_tricolor_fade(void) { return FRAMETIME; } -static const char _data_FX_MODE_TRICOLOR_FADE[] PROGMEM = "Tri Fade@!;1,2,3;!"; +static const char _data_FX_MODE_TRICOLOR_FADE[] PROGMEM = "Tri Fade@!;1,2,3;!;01"; /* From c44784071ef79d8e431d84a7e876a64add930394 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:07:56 +0100 Subject: [PATCH 18/72] small tails for rolling balls --- wled00/FX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index a985386252..9612070ee3 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -3048,7 +3048,8 @@ static uint16_t rolling_balls(void) { float cfac = float(scale8(8, 255-SEGMENT.speed) +1)*20000.0f; // this uses the Aircoookie conversion factor for scaling time using speed slider bool hasCol2 = SEGCOLOR(2); - if (!SEGMENT.check2) SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); + //if (!SEGMENT.check2) SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); + if (!SEGMENT.check2) SEGMENT.fade_out(253); // WLEDMM adding a bit of trail for (int i = 0; i < numBalls; i++) { float timeSinceLastUpdate = float((strip.now - balls[i].lastBounceUpdate))/cfac; From 402786c14e15799b2d4910f8298c69ab5395cbd0 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:11:07 +0100 Subject: [PATCH 19/72] GEQ FLat mode (1D) --- wled00/FX.cpp | 45 ++++++++++++++++++++++++++++++++++----------- wled00/wled.h | 2 +- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 9612070ee3..37c0b8e8be 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8101,15 +8101,36 @@ static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color, #ifndef WLED_DISABLE_2D ///////////////////////// -// ** 2D GEQ // +// 1D / 2D GEQ // ///////////////////////// -uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + +// GEQ helper: either draws 2D, or flattens pixels to 1D +static void setFlatPixelXY(bool flatMode, int x, int y, uint32_t color, unsigned cols, unsigned rows, unsigned offset) { + if ((unsigned(x) >= cols) || (unsigned(y) >= rows)) return; // skip invisible + + if (!flatMode) SEGMENT.setPixelColorXY(x, y, color); // normal 2D + else { + y = rows - y -1 ; // reverse y + if (y & 0x01) y = (rows + y) / 2; // center bars: odd pixels to the right + else y = (rows - 1 - y) / 2; // even pixels to the left + + int pix = x*rows + y + offset; // flatten -> transpose x y so that bars stay bars + if (unsigned(pix) >= SEGLEN) return; // skip invisible + SEGMENT.setPixelColor(pix, color); + } +} + +uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. Flat Mode added by softhack007 + //if (!strip.isMatrix) return mode_static(); // not a 2D set-up, not a problem + bool flatMode = !SEGMENT.is2D(); const int NUM_BANDS = map2(SEGMENT.custom1, 0, 255, 1, 16); - const uint16_t cols = SEGMENT.virtualWidth(); - const uint16_t rows = SEGMENT.virtualHeight(); - if ((cols <=1) || (rows <=1)) return mode_static(); // not really a 2D set-up + const int vLength = SEGLEN; // for flat mode + const uint16_t cols = flatMode ? min(max(2, NUM_BANDS), (vLength+1)/2) : SEGMENT.virtualWidth(); + const uint16_t rows = flatMode ? vLength / cols : SEGMENT.virtualHeight(); + const unsigned offset = flatMode ? max(0, (vLength - rows*cols +1) / 2) : 0; // flatmode: always center effect + + if ((cols <=1) || (rows <=1)) return mode_static(); // too small if (!SEGENV.allocateData(cols*sizeof(uint16_t))) return mode_static(); //allocation failed uint16_t *previousBarHeight = reinterpret_cast(SEGENV.data); //array of previous bar heights per frequency band @@ -8175,7 +8196,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. if (barHeight > previousBarHeight[x]) previousBarHeight[x] = barHeight; //drive the peak up uint32_t ledColor = BLACK; - if ((! SEGMENT.check1) && (barHeight > 0)) { // use faster drawLine when single-color bars are needed + if ((! SEGMENT.check1) && !flatMode && (barHeight > 0)) { // use faster drawLine when single-color bars are needed ledColor = SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); SEGMENT.drawLine(int(x), max(0,int(rows)-barHeight), int(x), int(rows-1), ledColor, false); // max(0, ...) to prevent negative Y } else { @@ -8184,23 +8205,25 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. colorIndex = map(y, 0, rows-1, 0, 255); ledColor = SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); - SEGMENT.setPixelColorXY(x, rows-1 - y, ledColor); + setFlatPixelXY(flatMode, x, rows-1 - y, ledColor, cols, rows, offset); } } - if ((SEGMENT.intensity < 255) && (previousBarHeight[x] > 0) && (previousBarHeight[x] < rows)) // WLEDMM avoid "overshooting" into other segments - SEGMENT.setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor); + if (!flatMode && (SEGMENT.intensity < 255) && (previousBarHeight[x] > 0) && (previousBarHeight[x] < rows)) // WLEDMM avoid "overshooting" into other segments - disable ripple pixels in 1D mode + setFlatPixelXY(flatMode, x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor, cols, rows, offset); if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect } #ifdef SR_DEBUG + if (!flatMode) { // WLEDMM: abuse top left/right pixels for peak detection debugging SEGMENT.setPixelColorXY(cols-1, 0, (samplePeak > 0) ? GREEN : BLACK); if (samplePeak > 0) SEGMENT.setPixelColorXY(0, 0, GREEN); // WLEDMM end + } #endif return FRAMETIME; } // mode_2DGEQ() -static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ ☾@Fade speed,Ripple decay,# of bands,,,Color bars,Smooth bars ☾;!,,Peaks;!;2f;c1=255,c2=64,pal=11,si=0"; // Beatsin +static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ ☾@Fade speed,Ripple decay,# of bands,,,Color bars,Smooth bars ☾;!,,Peaks;!;12f;c1=255,c2=64,pal=11,si=0"; // Beatsin ///////////////////////// diff --git a/wled00/wled.h b/wled00/wled.h index 85a9fe8444..f2c0ac6eac 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2411150 +#define VERSION 2411270 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ From 8ff0223520edf4cc934a734ce7e9880b61c32fa2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 27 Nov 2024 11:59:13 +0100 Subject: [PATCH 20/72] GEQ flat mode for 2D MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit you still have to use a trick -> the "expand 1D" drop-down is hidden once you select a 2D-capable effect * Create your segment with 2 colums or 2 rows (might also need "transpose" * Select a 1D effect like chunchun * set expand to "Pixels" or "Bar" * now select the GEQ effect --> Flat GEQ runs in the previously set expand mode. --- wled00/FX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 37c0b8e8be..838f763c33 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8122,7 +8122,7 @@ static void setFlatPixelXY(bool flatMode, int x, int y, uint32_t color, unsigned uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. Flat Mode added by softhack007 //if (!strip.isMatrix) return mode_static(); // not a 2D set-up, not a problem - bool flatMode = !SEGMENT.is2D(); + bool flatMode = !SEGMENT.is2D() || (SEGMENT.width() < 3) || (SEGMENT.height() < 3); // also use flat mode when less than 3 colums or rows const int NUM_BANDS = map2(SEGMENT.custom1, 0, 255, 1, 16); const int vLength = SEGLEN; // for flat mode From 59d5ff02c551d82abeccae6b61f68468ad10395a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:18:43 +0100 Subject: [PATCH 21/72] Flat GEQ improvement for shorter stips only center bars if we more than 4 pixels per bar. --- wled00/FX.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 838f763c33..694239d78e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8110,10 +8110,11 @@ static void setFlatPixelXY(bool flatMode, int x, int y, uint32_t color, unsigned if (!flatMode) SEGMENT.setPixelColorXY(x, y, color); // normal 2D else { - y = rows - y -1 ; // reverse y - if (y & 0x01) y = (rows + y) / 2; // center bars: odd pixels to the right - else y = (rows - 1 - y) / 2; // even pixels to the left - + y = rows - y - 1; // reverse y + if (rows > 4) { // center y if we have more than 4 pixels per bar + if (y & 0x01) y = (rows + y) / 2; // center bars: odd pixels to the right + else y = (rows - 1 - y) / 2; // even pixels to the left + } int pix = x*rows + y + offset; // flatten -> transpose x y so that bars stay bars if (unsigned(pix) >= SEGLEN) return; // skip invisible SEGMENT.setPixelColor(pix, color); From f21b2949f1c470459f9d67656f10b0979b6e0af1 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:13:46 +0100 Subject: [PATCH 22/72] fix for effect double restart problem when cross-fade is enabled we only use palette and brightness transitions, so effect restart at the transition end is not required. --- wled00/FX_fcn.cpp | 6 +++--- wled00/wled.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 1c5779464b..0f750b0f03 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -494,12 +494,12 @@ void Segment::setCurrentPalette() { } void Segment::handleTransition() { - if (!transitional) return; + if (!transitional || !_t) return; // Early exit if no transition active unsigned long maxWait = millis() + 20; if (mode == FX_MODE_STATIC && next_time > maxWait) next_time = maxWait; if (progress() == 0xFFFFU) { if (_t) { - if (_t->_modeP != mode) markForReset(); + //if (_t->_modeP != mode) markForReset(); // WLEDMM effect transition disabled as it does not work (flashes due to double effect restart) delete _t; _t = nullptr; } @@ -618,7 +618,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults, bool sliderDefaultsOnly) { sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) {if (oldPalette==-1) oldPalette = palette; setPalette(sOpt);} else {if (oldPalette!=-1) setPalette(oldPalette); oldPalette = -1;} } } - if (!fadeTransition) markForReset(); // WLEDMM quickfix for effect "double startup" bug. -> only works when "Crossfade" is disabled (led settings) + /*if (!fadeTransition)*/ markForReset(); // WLEDMM quickfix for effect "double startup" bug. stateChanged = true; // send UDP/WS broadcast } } diff --git a/wled00/wled.h b/wled00/wled.h index f2c0ac6eac..fe1761a2d2 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2411270 +#define VERSION 2411271 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ @@ -393,7 +393,7 @@ WLED_GLOBAL byte briS _INIT(128); // default brightness WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over WLED_GLOBAL byte nightlightDelayMins _INIT(60); WLED_GLOBAL byte nightlightMode _INIT(NL_MODE_FADE); // See const.h for available modes. Was nightlightFade -WLED_GLOBAL bool fadeTransition _INIT(false); // enable crossfading color transition // WLEDMM disabled - has bugs that will be solved in upstream beta4 +WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition // WLEDMM only do color x-fade -- effect x-fade has bugs that will be solved in upstream beta4 WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms WLED_GLOBAL uint_fast16_t briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) From 1670330b1b00a812d522e8bbbdc8773e97bb12f3 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:51:39 +0100 Subject: [PATCH 23/72] Octopus Radial Wave mode --- wled00/FX.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 694239d78e..e77e72f19b 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8575,6 +8575,7 @@ static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2"; //Octopus (https://editor.soulmatelights.com/gallery/671-octopus) //Stepko and Sutaburosu // adapted for WLED by @blazoncek +// RadialWave mode added by @softhack007, based on https://editor.soulmatelights.com/gallery/1090-radialwave uint16_t mode_2Doctopus() { if (!strip.isMatrix) return mode_static(); // not a 2D set-up @@ -8632,12 +8633,19 @@ uint16_t mode_2Doctopus() { else SEGENV.step += SEGMENT.speed / 32 + 1; // 1-4 range + uint32_t octopusStep = SEGENV.step/2; // 1/2 for Octopus mode + uint32_t radialStep = 7*SEGENV.step/6; // 7/6 = 1.16 for RadialWave mode + for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { byte angle = rMap[XY(x,y)].angle; byte radius = rMap[XY(x,y)].radius; //CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1))); - uint16_t intensity = sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); + uint16_t intensity; + if (SEGMENT.check3) + intensity = sin8(radialStep + sin8(radialStep - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave + else + intensity = sin8(sin8((angle * 4 - radius) / 4 + octopusStep) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity); SEGMENT.setPixelColorXY(x, y, c); @@ -8645,8 +8653,7 @@ uint16_t mode_2Doctopus() { } return FRAMETIME; } -static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs, SuperSync;;!;2;"; - +static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs, SuperSync,,RadialWave ☾;;!;2;"; //Waving Cell //@Stepko (https://editor.soulmatelights.com/gallery/1704-wavingcells) From 9046ec4bde10322911eba36ec81197ce6fbc32e5 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:15:17 +0100 Subject: [PATCH 24/72] Octopus minor optimization replacing "map" with direct computation --- wled00/FX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index e77e72f19b..1b07127cea 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8646,7 +8646,8 @@ uint16_t mode_2Doctopus() { intensity = sin8(radialStep + sin8(radialStep - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave else intensity = sin8(sin8((angle * 4 - radius) / 4 + octopusStep) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus - intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display + //intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display + intensity = (intensity * intensity) / 255; // WLEDMM same as above, but faster and a bit more accurate CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity); SEGMENT.setPixelColorXY(x, y, c); } From 5ea9cb1907bfd8f6c0fc54b4b4658932c774ad9f Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:21:47 +0100 Subject: [PATCH 25/72] Octopus code improvements * removed dead code * merge octopusStep and radialStep --> octoSpeed * improve speed slider resolution by first multiplying, then dividing Thanks @ewoudwijma --- wled00/FX.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 1b07127cea..9656d15efd 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -8628,13 +8628,14 @@ uint16_t mode_2Doctopus() { } } - if (true) // WLEDMM SuperSync - SEGENV.step = strip.now * (SEGMENT.speed / 32 + 1) / 25; // WLEDMM 40fps - else - SEGENV.step += SEGMENT.speed / 32 + 1; // 1-4 range + // WLEDMM SuperSync + SEGENV.step = (strip.now * (SEGMENT.speed+15)) / 33 / 25; // WLEDMM 40fps; speed range 0.4 ... 8 - uint32_t octopusStep = SEGENV.step/2; // 1/2 for Octopus mode - uint32_t radialStep = 7*SEGENV.step/6; // 7/6 = 1.16 for RadialWave mode + // speed of motion and color change + uint32_t colorSpeed = SEGENV.step / 2; + uint32_t octoSpeed; + if (SEGMENT.check3) octoSpeed = 4*SEGENV.step/5; // 4/5 = 0.8 for RadialWave mode + else octoSpeed = SEGENV.step/2; // 1/2 = 0.5 for Octopus mode for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { @@ -8643,12 +8644,12 @@ uint16_t mode_2Doctopus() { //CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1))); uint16_t intensity; if (SEGMENT.check3) - intensity = sin8(radialStep + sin8(radialStep - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave + intensity = sin8(octoSpeed + sin8(octoSpeed - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave else - intensity = sin8(sin8((angle * 4 - radius) / 4 + octopusStep) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus + intensity = sin8(sin8((angle * 4 - radius) / 4 + octoSpeed) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus //intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display intensity = (intensity * intensity) / 255; // WLEDMM same as above, but faster and a bit more accurate - CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity); + CRGB c = ColorFromPalette(SEGPALETTE, colorSpeed - radius, intensity); SEGMENT.setPixelColorXY(x, y, c); } } From e914417c7418e0688ba72d3c7b64e92a3d387473 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Wed, 27 Nov 2024 22:27:56 +0100 Subject: [PATCH 26/72] Merge pull request #4181 from DedeHai/0_15_trig_math Added integer based `sin()/cos()` functions, changed all trig functions to wled_math --- usermods/Analog_Clock/Analog_Clock.h | 4 +- wled00/FX.cpp | 288 ++++++++++++++------------- wled00/fcn_declare.h | 59 ++++-- wled00/util.cpp | 41 +++- wled00/wled_math.cpp | 106 +++++++++- 5 files changed, 319 insertions(+), 179 deletions(-) diff --git a/usermods/Analog_Clock/Analog_Clock.h b/usermods/Analog_Clock/Analog_Clock.h index 596f0acb3b..9d82f7670c 100644 --- a/usermods/Analog_Clock/Analog_Clock.h +++ b/usermods/Analog_Clock/Analog_Clock.h @@ -102,9 +102,9 @@ class AnalogClockUsermod : public Usermod { void secondsEffectSineFade(int16_t secondLed, Toki::Time const& time) { uint32_t ms = time.ms % 1000; - uint8_t b0 = (cos8(ms * 64 / 1000) - 128) * 2; + uint8_t b0 = (cos8_t(ms * 64 / 1000) - 128) * 2; setPixelColor(secondLed, gamma32(scale32(secondColor, b0))); - uint8_t b1 = (sin8(ms * 64 / 1000) - 128) * 2; + uint8_t b1 = (sin8_t(ms * 64 / 1000) - 128) * 2; setPixelColor(inc(secondLed, 1, secondsSegment), gamma32(scale32(secondColor, b1))); } diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 9656d15efd..d89108ed58 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -31,7 +31,7 @@ // effect utility functions static uint8_t sin_gap(uint16_t in) { if (in & 0x100) return 0; - return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0 + return sin8_t(in + 192); // correct phase shift of sine so that it starts and stops at 0 } static uint16_t triwave16(uint16_t in) { @@ -364,7 +364,7 @@ uint16_t mode_breath(void) { counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048 if (counter < 16384) { if (counter > 8192) counter = 8192 - (counter - 8192); - var = sin16(counter) / 103; //close to parabolic in range 0-8192, max val. 23170 + var = sin16_t(counter) / 103; //close to parabolic in range 0-8192, max val. 23170 } uint8_t lum = 30 + var; @@ -546,7 +546,7 @@ uint16_t running_base(bool saw, bool dual=false) { } a = 255 - a; } - uint8_t s = dual ? sin_gap(a) : sin8(a); + uint8_t s = dual ? sin_gap(a) : sin8_t(a); uint32_t ca = color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), s); if (dual) { uint16_t b = (SEGLEN-1-i)*x_scale - counter; @@ -1934,13 +1934,13 @@ uint16_t mode_pride_2015(void) { uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; - uint8_t sat8 = beatsin88( 87, 220, 250); - uint8_t brightdepth = beatsin88( 341, 96, 224); - uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); - uint8_t msmultiplier = beatsin88(147, 23, 60); + uint8_t sat8 = beatsin88_t( 87, 220, 250); + uint8_t brightdepth = beatsin88_t( 341, 96, 224); + uint16_t brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256)); + uint8_t msmultiplier = beatsin88_t(147, 23, 60); uint16_t hue16 = sHue16;//gHue * 256; - uint16_t hueinc16 = beatsin88(113, 1, 3000); + uint16_t hueinc16 = beatsin88_t(113, 1, 3000); if(SEGENV.call == 0) { SEGMENT.setUpLeds(); // WLEDMM use lossless getPixelColor() @@ -1948,15 +1948,14 @@ uint16_t mode_pride_2015(void) { } sPseudotime += duration * msmultiplier; - sHue16 += duration * beatsin88( 400, 5,9); + sHue16 += duration * beatsin88_t( 400, 5,9); uint16_t brightnesstheta16 = sPseudotime; - for (int i = 0 ; i < SEGLEN; i++) { hue16 += hueinc16; uint8_t hue8 = hue16 >> 8; brightnesstheta16 += brightnessthetainc16; - uint16_t b16 = sin16( brightnesstheta16 ) + 32768; + uint16_t b16 = sin16_t( brightnesstheta16 ) + 32768; uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; @@ -2047,7 +2046,7 @@ uint16_t mode_juggle(void) { CRGB fastled_col; byte dothue = 0; for (int i = 0; i < 8; i++) { - uint16_t index = 0 + beatsin88((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); + uint16_t index = 0 + beatsin88_t((16 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); fastled_col = CRGB(SEGMENT.getPixelColor(index)); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(SEGPALETTE, dothue, 255); SEGMENT.setPixelColor(index, fastled_col); @@ -2174,15 +2173,15 @@ uint16_t mode_colorwaves() { uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; - uint8_t brightdepth = beatsin88(341, 96, 224); - uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); - uint8_t msmultiplier = beatsin88(147, 23, 60); + uint8_t brightdepth = beatsin88_t(341, 96, 224); + uint16_t brightnessthetainc16 = beatsin88_t( 203, (25 * 256), (40 * 256)); + uint8_t msmultiplier = beatsin88_t(147, 23, 60); uint16_t hue16 = sHue16;//gHue * 256; - uint16_t hueinc16 = beatsin88(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues + uint16_t hueinc16 = beatsin88_t(113, 60, 300)*SEGMENT.intensity*10/255; // Use the Intensity Slider for the hues sPseudotime += duration * msmultiplier; - sHue16 += duration * beatsin88(400, 5, 9); + sHue16 += duration * beatsin88_t(400, 5, 9); uint16_t brightnesstheta16 = sPseudotime; if(SEGENV.call == 0) { @@ -2201,7 +2200,7 @@ uint16_t mode_colorwaves() { } brightnesstheta16 += brightnessthetainc16; - uint16_t b16 = sin16(brightnesstheta16) + 32768; + uint16_t b16 = sin16_t(brightnesstheta16) + 32768; uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; @@ -2221,7 +2220,7 @@ static const char _data_FX_MODE_COLORWAVES[] PROGMEM = "Colorwaves@!,Hue;!;!"; uint16_t mode_bpm() { //CRGB fastled_col; uint32_t stp = (strip.now / 20) & 0xFF; - uint8_t beat = beatsin8(SEGMENT.speed, 64, 255); + uint8_t beat = beatsin8_t(SEGMENT.speed, 64, 255); for (int i = 0; i < SEGLEN; i++) { //fastled_col = ColorFromPalette(SEGPALETTE, stp + (i * 2), beat - stp + (i * 10)); //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -2242,7 +2241,7 @@ uint16_t mode_fillnoise8() { //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0)); } - SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4 + SEGENV.step += beatsin8_t(SEGMENT.speed, 1, 6); //10,1,4 return FRAMETIME; } @@ -2255,13 +2254,13 @@ uint16_t mode_noise16_1() { SEGENV.step += (1 + SEGMENT.speed/16); for (int i = 0; i < SEGLEN; i++) { - uint16_t shift_x = beatsin8(11); // the x position of the noise field swings @ 17 bpm + uint16_t shift_x = beatsin8_t(11); // the x position of the noise field swings @ 17 bpm uint16_t shift_y = SEGENV.step/42; // the y position becomes slowly incremented uint16_t real_x = (i + shift_x) * scale; // the x position of the noise field swings @ 17 bpm uint16_t real_y = (i + shift_y) * scale; // the y position becomes slowly incremented uint32_t real_z = SEGENV.step; // the z position becomes quickly incremented uint8_t noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down - uint8_t index = sin8(noise * 3); // map LED color based on noise data + uint8_t index = sin8_t(noise * 3); // map LED color based on noise data //fastled_col = ColorFromPalette(SEGPALETTE, index, 255, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -2282,7 +2281,7 @@ uint16_t mode_noise16_2() { uint16_t shift_x = SEGENV.step >> 6; // x as a function of time uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field uint8_t noise = inoise16(real_x, 0, 4223) >> 8; // get the noise data and scale it down - uint8_t index = sin8(noise * 3); // map led color based on noise data + uint8_t index = sin8_t(noise * 3); // map led color based on noise data //fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -2306,7 +2305,7 @@ uint16_t mode_noise16_3() { uint32_t real_y = (i + shift_y) * scale; // based on the precalculated positions uint32_t real_z = SEGENV.step*8; uint8_t noise = inoise16(real_x, real_y, real_z) >> 8; // get the noise data and scale it down - uint8_t index = sin8(noise * 3); // map led color based on noise data + uint8_t index = sin8_t(noise * 3); // map led color based on noise data //fastled_col = ColorFromPalette(SEGPALETTE, index, noise, LINEARBLEND); // With that value, look up the 8 bit colour palette value and assign it to the current LED. //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -2395,14 +2394,14 @@ static const char _data_FX_MODE_COLORTWINKLE[] PROGMEM = "Colortwinkles@Fade spe //Calm effect, like a lake at night uint16_t mode_lake() { uint8_t sp = SEGMENT.speed/10; - int wave1 = beatsin8(sp +2, -64,64); - int wave2 = beatsin8(sp +1, -64,64); - uint8_t wave3 = beatsin8(sp +2, 0,80); + int wave1 = beatsin8_t(sp +2, -64,64); + int wave2 = beatsin8_t(sp +1, -64,64); + uint8_t wave3 = beatsin8_t(sp +2, 0,80); //CRGB fastled_col; for (int i = 0; i < SEGLEN; i++) { - int index = cos8((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; + int index = cos8_t((i*15)+ wave1)/2 + cubicwave8((i*23)+ wave2)/2; uint8_t lum = (index > wave3) ? index - wave3 : 0; //fastled_col = ColorFromPalette(SEGPALETTE, map(index,0,255,0,240), lum, LINEARBLEND); //SEGMENT.setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -2569,7 +2568,7 @@ uint16_t ripple_base() propI /= 2; uint16_t cx = rippleorigin >> 8; uint16_t cy = rippleorigin & 0xFF; - uint8_t mag = scale8(sin8((propF>>2)), amp); + uint8_t mag = scale8(sin8_t((propF>>2)), amp); if (propI > 0) SEGMENT.drawCircle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag), true); } else #endif @@ -2644,7 +2643,7 @@ CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) uint16_t ticks = ms / SEGENV.aux0; uint8_t fastcycle8 = ticks; uint16_t slowcycle16 = (ticks >> 8) + salt; - slowcycle16 += sin8(slowcycle16); + slowcycle16 += sin8_t(slowcycle16); slowcycle16 = (slowcycle16 * 2053) + 1384; uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8); @@ -3115,7 +3114,7 @@ uint16_t sinelon_base(bool dual, bool rainbow=false) { if (SEGLEN == 1) return mode_static(); if (SEGENV.call == 0) { SEGENV.setUpLeds(); SEGMENT.fill(BLACK); } // WLEDMM use lossless getPixelColor() SEGMENT.fade_out(SEGMENT.intensity); - uint16_t pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1); + uint16_t pos = beatsin16_t(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; uint32_t color1 = SEGMENT.color_from_palette(pos, true, false, 0); uint32_t color2 = SEGCOLOR(2); @@ -3941,13 +3940,13 @@ uint16_t mode_plasma(void) { if (SEGENV.call == 0) { SEGENV.aux0 = random8(0,2); // add a bit of randomness } - uint8_t thisPhase = beatsin8(6+SEGENV.aux0,-64,64); - uint8_t thatPhase = beatsin8(7+SEGENV.aux0,-64,64); + uint8_t thisPhase = beatsin8_t(6+SEGENV.aux0,-64,64); + uint8_t thatPhase = beatsin8_t(7+SEGENV.aux0,-64,64); for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows: uint8_t colorIndex = cubicwave8((i*(2+ 3*(SEGMENT.speed >> 5))+thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change. - + cos8((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish. - uint8_t thisBright = qsub8(colorIndex, beatsin8(7,0, (128 - (SEGMENT.intensity>>1)))); + + cos8_t((i*(1+ 2*(SEGMENT.speed >> 5))+thatPhase) & 0xFF)/2; // factor=15 // Hey, you can even change the frequencies if you wish. + uint8_t thisBright = qsub8(colorIndex, beatsin8_t(7,0, (128 - (SEGMENT.intensity>>1)))); //CRGB color = ColorFromPalette(SEGPALETTE, colorIndex, thisBright, LINEARBLEND); //SEGMENT.setPixelColor(i, color.red, color.green, color.blue); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0, thisBright)); @@ -4076,10 +4075,10 @@ CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t uint16_t wavescale_half = (wavescale >> 1) + 20; waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i - uint16_t s16 = sin16(waveangle) + 32768; + uint16_t s16 = sin16_t(waveangle) + 32768; uint16_t cs = scale16(s16, wavescale_half) + wavescale_half; ci += (cs * i); - uint16_t sindex16 = sin16(ci) + 32768; + uint16_t sindex16 = sin16_t(ci) + 32768; uint8_t sindex8 = scale16(sindex16, 240); return ColorFromPalette(p, sindex8, bri, LINEARBLEND); } @@ -4111,34 +4110,34 @@ uint16_t mode_pacifica() uint64_t deltat = (strip.now >> 2) + ((strip.now * SEGMENT.speed) >> 7); strip.now = deltat; - uint16_t speedfactor1 = beatsin16(3, 179, 269); - uint16_t speedfactor2 = beatsin16(4, 179, 269); + uint16_t speedfactor1 = beatsin16_t(3, 179, 269); + uint16_t speedfactor2 = beatsin16_t(4, 179, 269); uint32_t deltams1 = (deltams * speedfactor1) / 256; uint32_t deltams2 = (deltams * speedfactor2) / 256; uint32_t deltams21 = (deltams1 + deltams2) / 2; - sCIStart1 += (deltams1 * beatsin88(1011,10,13)); - sCIStart2 -= (deltams21 * beatsin88(777,8,11)); - sCIStart3 -= (deltams1 * beatsin88(501,5,7)); - sCIStart4 -= (deltams2 * beatsin88(257,4,6)); + sCIStart1 += (deltams1 * beatsin88_t(1011,10,13)); + sCIStart2 -= (deltams21 * beatsin88_t(777,8,11)); + sCIStart3 -= (deltams1 * beatsin88_t(501,5,7)); + sCIStart4 -= (deltams2 * beatsin88_t(257,4,6)); SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2; SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3; // Clear out the LED array to a dim background blue-green //SEGMENT.fill(132618); - uint8_t basethreshold = beatsin8( 9, 55, 65); + uint8_t basethreshold = beatsin8_t( 9, 55, 65); uint8_t wave = beat8( 7 ); for (int i = 0; i < SEGLEN; i++) { CRGB c = CRGB(2, 6, 10); // Render each of four layers, with different scales and speeds, that vary over time - c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0-beat16(301)); - c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401)); - c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8(9, 10,38) , 0-beat16(503)); - c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8(8, 10,28) , beat16(601)); + c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16_t(3, 11 * 256, 14 * 256), beatsin8_t(10, 70, 130), 0-beat16(301)); + c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16_t(4, 6 * 256, 9 * 256), beatsin8_t(17, 40, 80), beat16(401)); + c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8_t(9, 10,38) , 0-beat16(503)); + c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8_t(8, 10,28) , beat16(601)); // Add extra 'white' to areas where the four layers of light have lined up brightly - uint8_t threshold = scale8( sin8( wave), 20) + basethreshold; + uint8_t threshold = scale8( sin8_t( wave), 20) + basethreshold; wave += 7; uint8_t l = c.getAverageLight(); if (l > threshold) { @@ -4262,7 +4261,7 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine for (int i = 0; i < SEGLEN; i++) { uint8_t ranstart = random8(); // The starting value (aka brightness) for each pixel. Must be consistent each time through the loop for this to work. - uint8_t pixBri = sin8(ranstart + 16 * strip.now/(256-SEGMENT.speed)); + uint8_t pixBri = sin8_t(ranstart + 16 * strip.now/(256-SEGMENT.speed)); if (random8() > SEGMENT.intensity) pixBri = 0; SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri)); } @@ -4305,7 +4304,7 @@ uint16_t mode_noisepal(void) { // Slow noise SEGMENT.setPixelColor(i, color.red, color.green, color.blue); } - SEGENV.aux0 += beatsin8(10,1,4); // Moving along the distance. Vary it a bit with a sine wave. + SEGENV.aux0 += beatsin8_t(10,1,4); // Moving along the distance. Vary it a bit with a sine wave. return FRAMETIME; } @@ -4388,7 +4387,7 @@ uint16_t mode_chunchun(void) for (int i = 0; i < numBirds; i++) { counter -= span; - uint16_t megumin = sin16(counter) + 0x8000; + uint16_t megumin = sin16_t(counter) + 0x8000; uint16_t bird = uint32_t(megumin * SEGLEN) >> 16; uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping bird = constrain(bird, 0, SEGLEN-1); @@ -4558,7 +4557,7 @@ uint16_t mode_washing_machine(void) { SEGENV.step += (speed * 2048) / (512 - SEGMENT.speed); for (int i = 0; i < SEGLEN; i++) { - uint8_t col = sin8(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7)); + uint8_t col = sin8_t(((SEGMENT.intensity / 25 + 1) * 255 * i / SEGLEN) + (SEGENV.step >> 7)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); } @@ -4911,12 +4910,12 @@ static const char _data_FX_MODE_PERLINMOVE[] PROGMEM = "Perlin Move@!,# of pixel ///////////////////////// // Waveins // ///////////////////////// -// Uses beatsin8() + phase shifting. By: Andrew Tuline +// Uses beatsin8_t() + phase shifting. By: Andrew Tuline uint16_t mode_wavesins(void) { for (int i = 0; i < SEGLEN; i++) { - uint8_t bri = sin8(strip.now/4 + i * SEGMENT.intensity); - uint8_t index = beatsin8(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3)); + uint8_t bri = sin8_t(strip.now/4 + i * SEGMENT.intensity); + uint8_t index = beatsin8_t(SEGMENT.speed, SEGMENT.custom1, SEGMENT.custom1+SEGMENT.custom2, 0, i * (SEGMENT.custom3<<3)); // custom3 is reduced resolution slider //SEGMENT.setPixelColor(i, ColorFromPalette(SEGPALETTE, index, bri, LINEARBLEND)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(index, false, PALETTE_SOLID_WRAP, 0, bri)); } @@ -4938,9 +4937,9 @@ uint16_t mode_FlowStripe(void) { for (int i = 0; i < SEGLEN; i++) { int c = (abs(i - hl) / hl) * 127; - c = sin8(c); - c = sin8(c / 2 + t); - byte b = sin8(c + t/8); + c = sin8_t(c); + c = sin8_t(c / 2 + t); + byte b = sin8_t(c + t/8); SEGMENT.setPixelColor(i, CHSV(b + hue, 255, 255)); } @@ -4974,14 +4973,14 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma unsigned long t = strip.now; // timebase // outer stars for (unsigned i = 0; i < 8; i++) { - x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio); - y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio); + x = beatsin8_t(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio); + y = beatsin8_t(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio); SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255)); } // inner stars for (size_t i = 0; i < 4; i++) { - x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio); - y = beatsin8(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio); + x = beatsin8_t(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + (t * i)/ratio); + y = beatsin8_t(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + (t * i)/ratio); SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255)); } // central white dot @@ -5017,10 +5016,10 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so SEGENV.aux0++; // hue SEGMENT.fadeToBlackBy(40); for (size_t i = 0; i < numLines; i++) { - byte x1 = beatsin8(2 + SEGMENT.speed/16, 0, (cols - 1)); - byte x2 = beatsin8(1 + SEGMENT.speed/16, 0, (rows - 1)); - byte y1 = beatsin8(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24); - byte y2 = beatsin8(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64); + byte x1 = beatsin8_t(2 + SEGMENT.speed/16, 0, (cols - 1)); + byte x2 = beatsin8_t(1 + SEGMENT.speed/16, 0, (rows - 1)); + byte y1 = beatsin8_t(5 + SEGMENT.speed/16, 0, (cols - 1), 0, i * 24); + byte y2 = beatsin8_t(3 + SEGMENT.speed/16, 0, (rows - 1), 0, i * 48 + 64); CRGB color = ColorFromPalette(SEGPALETTE, i * 255 / numLines + (SEGENV.aux0&0xFF), 255, LINEARBLEND); byte xsteps = abs8(x1 - y1) + 1; @@ -5068,14 +5067,14 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa int lastY1 = -1; int lastY2 = -1; for (int i = 0; i < cols; i++) { - int posY1 = beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4 ); - int posY2 = beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128); + int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 ); + int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128); if ((i==0) || ((abs(lastY1 - posY1) < 2) && (abs(lastY2 - posY2) < 2))) { // use original code when no holes - SEGMENT.setPixelColorXY(i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND)); - SEGMENT.setPixelColorXY(i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND)); + SEGMENT.setPixelColorXY(i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND)); + SEGMENT.setPixelColorXY(i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND)); } else { // draw line to prevent holes - SEGMENT.drawLine(i-1, lastY1, i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND)); - SEGMENT.drawLine(i-1, lastY2, i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND)); + SEGMENT.drawLine(i-1, lastY1, i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND)); + SEGMENT.drawLine(i-1, lastY2, i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND)); } lastY1 = posY1; lastY2 = posY2; @@ -5108,8 +5107,8 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma SEGMENT.fadeToBlackBy(135); for (int i = 0; i < rows; i++) { - uint16_t x = beatsin8(speeds, 0, cols - 1, 0, i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, i * freq + 128); - uint16_t x1 = beatsin8(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq); + uint16_t x = beatsin8_t(speeds, 0, cols - 1, 0, i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, i * freq + 128); + uint16_t x1 = beatsin8_t(speeds, 0, cols - 1, 0, 128 + i * freq) + beatsin8_t(speeds - 7, 0, cols - 1, 0, 128 + 64 + i * freq); uint8_t hue = (i * 128 / rows) + ms; // skip every 4th row every now and then (fade it more) if ((i + ms / 8) & 3) { @@ -5241,9 +5240,9 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so SEGMENT.fadeToBlackBy(16); for (size_t i = 8; i > 0; i--) { - SEGMENT.addPixelColorXY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), - beatsin8(SEGMENT.intensity/8 - i, 0, rows - 1), - ColorFromPalette(SEGPALETTE, beatsin8(12, 0, 255), 255, LINEARBLEND)); + SEGMENT.addPixelColorXY(beatsin8_t(SEGMENT.speed/8 + i, 0, cols - 1), + beatsin8_t(SEGMENT.intensity/8 - i, 0, rows - 1), + ColorFromPalette(SEGPALETTE, beatsin8_t(12, 0, 255), 255, LINEARBLEND)); } SEGMENT.blur(SEGMENT.custom1>>3); @@ -5661,7 +5660,7 @@ uint16_t mode_2DHiphotic() { // By: ldirko https://edit for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { - SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8(cos8(x * SEGMENT.speed/16 + a / 3) + sin8(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); + SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(sin8_t(cos8_t(x * SEGMENT.speed/16 + a / 3) + sin8_t(y * SEGMENT.intensity/16 + a / 4) + a), false, PALETTE_SOLID_WRAP, 0)); } } @@ -5740,8 +5739,10 @@ uint16_t mode_2DJulia(void) { // An animated Julia set reAl = -0.94299f; // PixelBlaze example imAg = 0.3162f; - reAl += sinf((float)strip.now/305.f)/20.f; - imAg += sinf((float)strip.now/405.f)/20.f; + //reAl += sinf((float)strip.now/305.f)/20.f; + //imAg += sinf((float)strip.now/405.f)/20.f; + reAl += (float)sin16_t(strip.now * 34) / 655340.f; + imAg += (float)sin16_t(strip.now * 26) / 655340.f; dx = (xmax - xmin) / (cols); // Scale the delta x and y values to our matrix size. dy = (ymax - ymin) / (rows); @@ -5820,8 +5821,8 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline int maxLoops = max(192, 4*(cols+rows)); maxLoops = ((maxLoops / 128) +1) * 128; // make sure whe have half or full turns => multiples of 128 for (int i=0; i < maxLoops; i ++) { - float xlocn = float(sin8(phase/2 + (i* SEGMENT.speed)/64)) / 255.0f; // WLEDMM align speed with original effect - float ylocn = float(cos8(phase/2 + i*2)) / 255.0f; + float xlocn = float(sin8_t(phase/2 + (i* SEGMENT.speed)/64)) / 255.0f; // WLEDMM align speed with original effect + float ylocn = float(cos8_t(phase/2 + i*2)) / 255.0f; //SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing unsigned palIndex = (256*ylocn) + phase/2 + (i* SEGMENT.speed)/64; //SEGMENT.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(palIndex, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing - color follows rotation @@ -5832,8 +5833,8 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline } else for (int i=0; i < 256; i ++) { //WLEDMM: stick to the original calculations of xlocn and ylocn - uint_fast8_t xlocn = sin8(phase/2 + (i*SEGMENT.speed)/64); - uint_fast8_t ylocn = cos8(phase/2 + i*2); + uint_fast8_t xlocn = sin8_t(phase/2 + (i*SEGMENT.speed)/64); + uint_fast8_t ylocn = cos8_t(phase/2 + i*2); xlocn = (cols < 2) ? 1 : (map(2*xlocn, 0,511, 0,2*(cols-1)) +1) /2; // softhack007: "*2 +1" for proper rounding ylocn = (rows < 2) ? 1 : (map(2*ylocn, 0,511, 0,2*(rows-1)) +1) /2; // "rows > 2" is needed to avoid div/0 in map() SEGMENT.setPixelColorXY((uint8_t)xlocn, (uint8_t)ylocn, SEGMENT.color_from_palette(strip.now/100+i, false, PALETTE_SOLID_WRAP, 0)); @@ -5939,8 +5940,8 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have uint8_t y3 = map(inoise8(strip.now * speed, 25355, 22685), 0, 255, 0, rows-1); // and one Lissajou function - uint8_t x1 = beatsin8(23 * speed, 0, cols-1); - uint8_t y1 = beatsin8(28 * speed, 0, rows-1); + uint8_t x1 = beatsin8_t(23 * speed, 0, cols-1); + uint8_t y1 = beatsin8_t(28 * speed, 0, rows-1); for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { @@ -6142,7 +6143,7 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi uint32_t a = strip.now / (18 - SEGMENT.speed / 16); uint16_t x = (a / 14) % cols; - uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0); + uint16_t y = map((sin8_t(a * 5) + sin8_t(a * 4) + sin8_t(a * 2)), 0, 765, rows-1, 0); SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, map(y, 0, rows-1, 0, 255), 255, LINEARBLEND)); SEGMENT.blur(1 + (SEGMENT.intensity>>4)); @@ -6169,10 +6170,10 @@ uint16_t mode_2DSindots(void) { // By: ldirko http SEGMENT.fadeToBlackBy(SEGMENT.custom1>>3); byte t1 = strip.now / (257 - SEGMENT.speed); // 20; - byte t2 = sin8(t1) / 4 * 2; + byte t2 = sin8_t(t1) / 4 * 2; for (int i = 0; i < 13; i++) { - byte x = sin8(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15! - byte y = sin8(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15! + byte x = sin8_t(t1 + i * SEGMENT.intensity/8)*(cols-1)/255; // max index now 255x15/255=15! + byte y = sin8_t(t2 + i * SEGMENT.intensity/8)*(rows-1)/255; // max index now 255x15/255=15! SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, i * 255 / 13, 255, LINEARBLEND)); } SEGMENT.blur(SEGMENT.custom2>>3); @@ -6206,12 +6207,12 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g SEGMENT.blur(blurAmount); // Use two out-of-sync sine waves - uint8_t i = beatsin8(19, kBorderWidth, cols-kBorderWidth); - uint8_t j = beatsin8(22, kBorderWidth, cols-kBorderWidth); - uint8_t k = beatsin8(17, kBorderWidth, cols-kBorderWidth); - uint8_t m = beatsin8(18, kBorderWidth, rows-kBorderWidth); - uint8_t n = beatsin8(15, kBorderWidth, rows-kBorderWidth); - uint8_t p = beatsin8(20, kBorderWidth, rows-kBorderWidth); + uint8_t i = beatsin8_t(19, kBorderWidth, cols-kBorderWidth); + uint8_t j = beatsin8_t(22, kBorderWidth, cols-kBorderWidth); + uint8_t k = beatsin8_t(17, kBorderWidth, cols-kBorderWidth); + uint8_t m = beatsin8_t(18, kBorderWidth, rows-kBorderWidth); + uint8_t n = beatsin8_t(15, kBorderWidth, rows-kBorderWidth); + uint8_t p = beatsin8_t(20, kBorderWidth, rows-kBorderWidth); uint16_t ms = strip.now; @@ -6293,19 +6294,19 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so uint8_t hue, bri; size_t intensity; - int offsetX = beatsin16(3, -360, 360); - int offsetY = beatsin16(2, -360, 360); + int offsetX = beatsin16_t(3, -360, 360); + int offsetY = beatsin16_t(2, -360, 360); int sharpness = SEGMENT.custom3 / 8; // 0-3 for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { - hue = x * beatsin16(10, 1, 10) + offsetY; - intensity = bri = sin8(x * SEGMENT.speed/2 + offsetX); + hue = x * beatsin16_t(10, 1, 10) + offsetY; + intensity = bri = sin8_t(x * SEGMENT.speed/2 + offsetX); for (int i=0; i>= 8*sharpness; SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND)); hue = y * 3 + offsetX; - intensity = bri = sin8(y * SEGMENT.intensity/2 + offsetY); + intensity = bri = sin8_t(y * SEGMENT.intensity/2 + offsetY); for (int i=0; i>= 8*sharpness; SEGMENT.addPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, hue, intensity, LINEARBLEND)); @@ -6345,9 +6346,9 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht SEGMENT.move(SEGENV.aux0, 1); for (size_t i = 0; i < 8; i++) { - byte x = beatsin8(12 + i, 2, cols - 3); - byte y = beatsin8(15 + i, 2, rows - 3); - CRGB color = ColorFromPalette(SEGPALETTE, beatsin8(12 + i, 0, 255), 255); + byte x = beatsin8_t(12 + i, 2, cols - 3); + byte y = beatsin8_t(15 + i, 2, rows - 3); + CRGB color = ColorFromPalette(SEGPALETTE, beatsin8_t(12 + i, 0, 255), 255); SEGMENT.addPixelColorXY(x, y, color); if (cols > 24 || rows > 24) { SEGMENT.addPixelColorXY(x+1, y, color); @@ -6772,8 +6773,8 @@ uint16_t mode_2Ddriftrose(void) { SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3)); for (size_t i = 1; i < 37; i++) { float angle = float(DEG_TO_RAD) * i * 10; - uint32_t x = int((CX + (sinf(angle) * (beatsin8(i, 0, L2)-L))) * 255.f); - uint32_t y = int((CY + (cosf(angle) * (beatsin8(i, 0, L2)-L))) * 255.f); + uint32_t x = int((CX + (sinf(angle) * (beatsin8_t(i, 0, L2)-L))) * 255.f); + uint32_t y = int((CY + (cosf(angle) * (beatsin8_t(i, 0, L2)-L))) * 255.f); if ((x < wu_cols) && (y < wu_rows)) SEGMENT.wu_pixel(x, y, CHSV(i * 10, 255, 255)); } SEGMENT.blur((SEGMENT.intensity>>4)+1); @@ -6944,10 +6945,10 @@ uint16_t mode_2DSwirl(void) { SEGMENT.blur(SEGMENT.custom1); - unsigned i = beatsin8( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); - unsigned j = beatsin8( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); - unsigned ni = (cols - 1) - i; - unsigned nj = (cols - 1) - j; + int i = beatsin8_t( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); + int j = beatsin8_t( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); + int ni = (cols - 1) - i; + int nj = (cols - 1) - j; uint16_t ms = strip.now; um_data_t *um_data = getAudioData(); @@ -7214,7 +7215,7 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. for (size_t i=0; ithisphase += beatsin8(6,-4,4); // You can change direction and speed individually. - plasmoip->thatphase += beatsin8(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline. + plasmoip->thisphase += beatsin8_t(6,-4,4); // You can change direction and speed individually. + plasmoip->thatphase += beatsin8_t(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline. for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set a brightness based on a wave as follows. // updated, similar to "plasma" effect - softhack007 uint8_t thisbright = cubicwave8(((i*(1 + (3*SEGMENT.speed/32)))+plasmoip->thisphase) & 0xFF)/2; - thisbright += cos8(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases. + thisbright += cos8_t(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases. uint8_t colorIndex=thisbright; if (volumeSmth * SEGMENT.intensity / 64 < thisbright) {thisbright = 0;} @@ -8035,7 +8036,7 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac frTemp -=132; // This should give us a base musical note of C3 frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255; - uint16_t i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1); + uint16_t i = map(beatsin8_t(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1); // i will be always constrained between 0 and 0 if SEGLEN equals 1 i = constrain(i, 0, SEGLEN-1); SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint8_t)frTemp, false, PALETTE_SOLID_WRAP, 0), volTemp)); @@ -8405,12 +8406,12 @@ uint16_t mode_2Ddistortionwaves() { uint16_t a2 = a/2; uint16_t a3 = a/3; - uint16_t cx = beatsin8(10-speed,0,cols-1)*scale; - uint16_t cy = beatsin8(12-speed,0,rows-1)*scale; - uint16_t cx1 = beatsin8(13-speed,0,cols-1)*scale; - uint16_t cy1 = beatsin8(15-speed,0,rows-1)*scale; - uint16_t cx2 = beatsin8(17-speed,0,cols-1)*scale; - uint16_t cy2 = beatsin8(14-speed,0,rows-1)*scale; + uint16_t cx = beatsin8_t(10-speed,0,cols-1)*scale; + uint16_t cy = beatsin8_t(12-speed,0,rows-1)*scale; + uint16_t cx1 = beatsin8_t(13-speed,0,cols-1)*scale; + uint16_t cy1 = beatsin8_t(15-speed,0,rows-1)*scale; + uint16_t cx2 = beatsin8_t(17-speed,0,cols-1)*scale; + uint16_t cy2 = beatsin8_t(14-speed,0,rows-1)*scale; uint16_t xoffs = 0; for (int x = 0; x < cols; x++) { @@ -8420,17 +8421,17 @@ uint16_t mode_2Ddistortionwaves() { for (int y = 0; y < rows; y++) { yoffs += scale; - byte rdistort = cos8((cos8(((x<<3)+a )&255)+cos8(((y<<3)-a2)&255)+a3 )&255)>>1; - byte gdistort = cos8((cos8(((x<<3)-a2)&255)+cos8(((y<<3)+a3)&255)+a+32 )&255)>>1; - byte bdistort = cos8((cos8(((x<<3)+a3)&255)+cos8(((y<<3)-a) &255)+a2+64)&255)>>1; + byte rdistort = cos8_t((cos8_t(((x<<3)+a )&255)+cos8_t(((y<<3)-a2)&255)+a3 )&255)>>1; + byte gdistort = cos8_t((cos8_t(((x<<3)-a2)&255)+cos8_t(((y<<3)+a3)&255)+a+32 )&255)>>1; + byte bdistort = cos8_t((cos8_t(((x<<3)+a3)&255)+cos8_t(((y<<3)-a) &255)+a2+64)&255)>>1; byte valueR = rdistort+ w* (a- ( ((xoffs - cx) * (xoffs - cx) + (yoffs - cy) * (yoffs - cy))>>7 )); byte valueG = gdistort+ w* (a2-( ((xoffs - cx1) * (xoffs - cx1) + (yoffs - cy1) * (yoffs - cy1))>>7 )); byte valueB = bdistort+ w* (a3-( ((xoffs - cx2) * (xoffs - cx2) + (yoffs - cy2) * (yoffs - cy2))>>7 )); - valueR = gamma8(cos8(valueR)); - valueG = gamma8(cos8(valueG)); - valueB = gamma8(cos8(valueB)); + valueR = gamma8(cos8_t(valueR)); + valueG = gamma8(cos8_t(valueG)); + valueB = gamma8(cos8_t(valueB)); SEGMENT.setPixelColorXY(x, y, RGBW32(valueR, valueG, valueB, 0)); } @@ -8622,8 +8623,11 @@ uint16_t mode_2Doctopus() { const uint16_t C_Y = rows / 2 + (SEGMENT.custom2 - 128)*rows/255; for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { - rMap[XY(x, y)].angle = int(40.7436f * atan2f((y - C_Y), (x - C_X))); // avoid 128*atan2()/PI - rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu + int dx = (x - C_X); + int dy = (y - C_Y); + rMap[XY(x, y)].angle = int(40.7436f * atan2f(dy, dx)); // avoid 128*atan2()/PI + //rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu + rMap[XY(x, y)].radius = sqrtf(dx * dx + dy * dy) * mapp; //thanks Sutaburosu } } } @@ -8641,12 +8645,12 @@ uint16_t mode_2Doctopus() { for (int y = yStart; y < yEnd; y++) { byte angle = rMap[XY(x,y)].angle; byte radius = rMap[XY(x,y)].radius; - //CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1))); + //CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8_t(sin8_t((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1))); uint16_t intensity; if (SEGMENT.check3) - intensity = sin8(octoSpeed + sin8(octoSpeed - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave + intensity = sin8_t(octoSpeed + sin8_t(octoSpeed - radius) + angle * (SEGMENT.custom3/4+1)); // RadialWave else - intensity = sin8(sin8((angle * 4 - radius) / 4 + octoSpeed) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus + intensity = sin8_t(sin8_t((angle * 4 - radius) / 4 + octoSpeed) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1)); // Octopus //intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display intensity = (intensity * intensity) / 255; // WLEDMM same as above, but faster and a bit more accurate CRGB c = ColorFromPalette(SEGPALETTE, colorSpeed - radius, intensity); @@ -8671,7 +8675,7 @@ uint16_t mode_2Dwavingcell() { uint8_t aY = SEGMENT.custom2/16 + 1; uint8_t aZ = SEGMENT.custom3 + 1; for (int x = 0; x < cols; x++) for (int y = 0; y T atan_t(T x); - float cos_t(float phi) __attribute__((const)); - float sin_t(float x) __attribute__((const)); - float tan_t(float x) __attribute__((const)); - float acos_t(float x); - float asin_t(float x); - float atan_t(float x) __attribute__((const)); - float floor_t(float x) __attribute__((const)); - float fmod_t(float num, float denom) __attribute__((const)); -#else - #include // WLEDMM use "float" variants - #define sin_t sinf - #define cos_t cosf - #define tan_t tanf - #define asin_t asinf - #define acos_t acosf - #define atan_t atanf - #define fmod_t fmodf - #define floor_t floorf -#endif +//float cos_t(float phi); // use float math +//float sin_t(float phi); +//float tan_t(float x); +int16_t sin16_t(uint16_t theta); +int16_t cos16_t(uint16_t theta); +uint8_t sin8_t(uint8_t theta); +uint8_t cos8_t(uint8_t theta); + +float sin_approx(float theta); // uses integer math (converted to float), accuracy +/-0.0015 (compared to sinf()) +float cos_approx(float theta); +float tan_approx(float x); +//float atan2_t(float y, float x); +//float acos_t(float x); +//float asin_t(float x); +//template T atan_t(T x); +//float floor_t(float x); +//float fmod_t(float num, float denom); +#define sin_t sin_approx +#define cos_t cos_approx +#define tan_t tan_approx + +#include // standard math functions. use a lot of flash +#define atan2_t atan2f +#define asin_t asinf +#define acos_t acosf +#define atan_t atanf +#define fmod_t fmodf +#define floor_t floorf +/* +#define sin_t sinf +#define cos_t cosf +#define tan_t tanf +*/ //wled_serial.cpp void handleSerial(); diff --git a/wled00/util.cpp b/wled00/util.cpp index 87e14c2c99..3b380ce8cb 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -423,6 +423,39 @@ uint16_t crc16(const unsigned char* data_p, size_t length) { return crc; } +// fastled beatsin: 1:1 replacements to remove the use of fastled sin16() +// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details. +uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset) +{ + uint16_t beat = beat88( beats_per_minute_88, timebase); + uint16_t beatsin (sin16_t( beat + phase_offset) + 32768); + uint16_t rangewidth = highest - lowest; + uint16_t scaledbeat = scale16( beatsin, rangewidth); + uint16_t result = lowest + scaledbeat; + return result; +} + +// Generates a 16-bit sine wave at a given BPM that oscillates within a given range. see fastled for details. +uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset) +{ + uint16_t beat = beat16( beats_per_minute, timebase); + uint16_t beatsin = (sin16_t( beat + phase_offset) + 32768); + uint16_t rangewidth = highest - lowest; + uint16_t scaledbeat = scale16( beatsin, rangewidth); + uint16_t result = lowest + scaledbeat; + return result; +} + +// Generates an 8-bit sine wave at a given BPM that oscillates within a given range. see fastled for details. +uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest, uint8_t highest, uint32_t timebase, uint8_t phase_offset) +{ + uint8_t beat = beat8( beats_per_minute, timebase); + uint8_t beatsin = sin8_t( beat + phase_offset); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8( beatsin, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} /////////////////////////////////////////////////////////////////////////////// // Begin simulateSound (to enable audio enhanced effects to display something) @@ -487,8 +520,8 @@ um_data_t* simulateSound(uint8_t simulationId) default: case UMS_BeatSin: for (int i = 0; i<16; i++) - fftResult[i] = beatsin8(120 / (i+1), 0, 255); - // fftResult[i] = (beatsin8(120, 0, 255) + (256/16 * i)) % 256; + fftResult[i] = beatsin8_t(120 / (i+1), 0, 255); + // fftResult[i] = (beatsin8_t(120, 0, 255) + (256/16 * i)) % 256; volumeSmth = fftResult[8]; break; case UMS_WeWillRockYou: @@ -525,12 +558,12 @@ um_data_t* simulateSound(uint8_t simulationId) break; case UMS_10_13: for (int i = 0; i<16; i++) - fftResult[i] = inoise8(beatsin8(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3); + fftResult[i] = inoise8(beatsin8_t(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3); volumeSmth = fftResult[8]; break; case UMS_14_3: for (int i = 0; i<16; i++) - fftResult[i] = inoise8(beatsin8(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3); + fftResult[i] = inoise8(beatsin8_t(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3); volumeSmth = fftResult[8]; break; } diff --git a/wled00/wled_math.cpp b/wled00/wled_math.cpp index a4c9fc123c..bd5423389a 100644 --- a/wled00/wled_math.cpp +++ b/wled00/wled_math.cpp @@ -10,16 +10,25 @@ //#define WLED_DEBUG_MATH +// Note: cos_t, sin_t and tan_t are very accurate but slow +// the math.h functions use several kB of flash and are to be avoided if possible +// sin16_t / cos16_t are faster and much more accurate than the fastled variants +// sin_approx and cos_approx are float wrappers for sin16_t/cos16_t and have an accuracy better than +/-0.0015 compared to sinf() +// sin8_t / cos8_t are fastled replacements and use sin16_t / cos16_t. Slightly slower than fastled version but very accurate + + +// Taylor series approximations, replaced with Bhaskara I's approximation +/* #define modd(x, y) ((x) - (int)((x) / (y)) * (y)) float cos_t(float phi) { - float x = modd(phi, TWO_PI); + float x = modd(phi, M_TWOPI); if (x < 0) x = -1 * x; int8_t sign = 1; - if (x > PI) + if (x > M_PI) { - x -= PI; + x -= M_PI; sign = -1; } float xx = x * x; @@ -31,8 +40,8 @@ float cos_t(float phi) return res; } -float sin_t(float x) { - float res = cos_t(HALF_PI - x); +float sin_t(float phi) { + float res = cos_t(M_PI_2 - phi); #ifdef WLED_DEBUG_MATH Serial.printf("sin: %f,%f,%f,(%f)\n",x,res,sin(x),res-sin(x)); #endif @@ -48,6 +57,81 @@ float tan_t(float x) { #endif return res; } +*/ + +// 16-bit, integer based Bhaskara I's sine approximation: 16*x*(pi - x) / (5*pi^2 - 4*x*(pi - x)) +// input is 16bit unsigned (0-65535), output is 16bit signed (-32767 to +32767) +// optimized integer implementation by @dedehai +int16_t sin16_t(uint16_t theta) { + int scale = 1; + if (theta > 0x7FFF) { + theta = 0xFFFF - theta; + scale = -1; // second half of the sine function is negative (pi - 2*pi) + } + uint32_t precal = theta * (0x7FFF - theta); + uint64_t numerator = (uint64_t)precal * (4 * 0x7FFF); // 64bit required + int32_t denominator = 1342095361 - precal; // 1342095361 is 5 * 0x7FFF^2 / 4 + int16_t result = numerator / denominator; + return result * scale; +} + +int16_t cos16_t(uint16_t theta) { + return sin16_t(theta + 0x4000); //cos(x) = sin(x+pi/2) +} + +uint8_t sin8_t(uint8_t theta) { + int32_t sin16 = sin16_t((uint16_t)theta * 257); // 255 * 257 = 0xFFFF + sin16 += 0x7FFF + 128; //shift result to range 0-0xFFFF, +128 for rounding + return min(sin16, int32_t(0xFFFF)) >> 8; // min performs saturation, and prevents overflow +} + +uint8_t cos8_t(uint8_t theta) { + return sin8_t(theta + 64); //cos(x) = sin(x+pi/2) +} + +float sin_approx(float theta) { + uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3) + int32_t result = sin16_t(scaled_theta); + float sin = float(result) / 0x7FFF; + return sin; +} + +float cos_approx(float theta) { + uint16_t scaled_theta = (int)(theta * (float)(0xFFFF / M_TWOPI)); // note: do not cast negative float to uint! cast to int first (undefined on C3) + int32_t result = sin16_t(scaled_theta + 0x4000); + float cos = float(result) / 0x7FFF; + return cos; +} + +float tan_approx(float x) { + float c = cos_approx(x); + if (c==0.0f) return 0; + float res = sin_approx(x) / c; + return res; +} + +#if 0 // WLEDMM we prefer libm functions that are accurate and fast. +#define ATAN2_CONST_A 0.1963f +#define ATAN2_CONST_B 0.9817f + +// atan2_t approximation, with the idea from https://gist.github.com/volkansalma/2972237?permalink_comment_id=3872525#gistcomment-3872525 +float atan2_t(float y, float x) { + float abs_y = fabs(y); + float abs_x = fabs(x); + float r = (abs_x - abs_y) / (abs_y + abs_x + 1e-10f); // avoid division by zero by adding a small nubmer + float angle; + if(x < 0) { + r = -r; + angle = M_PI_2 + M_PI_4; + } + else + angle = M_PI_2 - M_PI_4; + + float add = (ATAN2_CONST_A * (r * r) - ATAN2_CONST_B) * r; + angle += add; + angle = y < 0 ? -angle : angle; + return angle; +} //https://stackoverflow.com/questions/3380628 // Absolute error <= 6.7e-5 @@ -60,10 +144,10 @@ float acos_t(float x) { ret = ret * xabs; ret = ret - 0.2121144f; ret = ret * xabs; - ret = ret + HALF_PI; + ret = ret + M_PI_2; ret = ret * sqrt(1.0f-xabs); ret = ret - 2 * negate * ret; - float res = negate * PI + ret; + float res = negate * M_PI + ret; #ifdef WLED_DEBUG_MATH Serial.printf("acos: %f,%f,%f,(%f)\n",x,res,acos(x),res-acos(x)); #endif @@ -71,7 +155,7 @@ float acos_t(float x) { } float asin_t(float x) { - float res = HALF_PI - acos_t(x); + float res = M_PI_2 - acos_t(x); #ifdef WLED_DEBUG_MATH Serial.printf("asin: %f,%f,%f,(%f)\n",x,res,asin(x),res-asin(x)); #endif @@ -87,7 +171,7 @@ float atan_t(float x) { //For A/B/C, see https://stackoverflow.com/a/42542593 static const double A { 0.0776509570923569 }; static const double B { -0.287434475393028 }; - static const double C { ((HALF_PI/2) - A - B) }; + static const double C { ((M_PI_4) - A - B) }; // polynominal factors for approximation between 1 and 5 static const float C0 { 0.089494f }; static const float C1 { 0.974207f }; @@ -102,7 +186,7 @@ float atan_t(float x) { x = std::abs(x); float res; if (x > 5.0f) { // atan(x) converges to pi/2 - (1/x) for large values - res = HALF_PI - (1.0f/x); + res = M_PI_2 - (1.0f/x); } else if (x > 1.0f) { //1 < x < 5 float xx = x * x; res = (C4*xx*xx)+(C3*xx*x)+(C2*xx)+(C1*x)+C0; @@ -137,3 +221,5 @@ float fmod_t(float num, float denom) { #endif return res; } + +#endif // WLEDMM \ No newline at end of file From 6c87799ce5cf66bd33ebc03861f55233e8bc2e04 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:48:27 +0100 Subject: [PATCH 27/72] post merge --- wled00/FX.cpp | 8 ++++---- wled00/wled.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index d89108ed58..9186866fb9 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -6945,10 +6945,10 @@ uint16_t mode_2DSwirl(void) { SEGMENT.blur(SEGMENT.custom1); - int i = beatsin8_t( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); - int j = beatsin8_t( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); - int ni = (cols - 1) - i; - int nj = (cols - 1) - j; + unsigned i = beatsin8_t( 27*SEGMENT.speed/255, borderWidth, cols - borderWidth); + unsigned j = beatsin8_t( 41*SEGMENT.speed/255, borderWidth, rows - borderWidth); + unsigned ni = (cols - 1) - i; + unsigned nj = (cols - 1) - j; uint16_t ms = strip.now; um_data_t *um_data = getAudioData(); diff --git a/wled00/wled.h b/wled00/wled.h index fe1761a2d2..2811036532 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2411271 +#define VERSION 2411290 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ From b2364bf4a5b3310720f26300470ec8dc74d1acb8 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:56:35 +0100 Subject: [PATCH 28/72] chunchun effect bugfixes (for strips >256 pixels) * avoid 16bit overflows * improve time resolution * limit to 32 birds (=max for 256 pixels) * fix fade_out --- wled00/FX.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 9186866fb9..238ce0ac33 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4377,20 +4377,20 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver */ uint16_t mode_chunchun(void) { - if (SEGLEN == 1) return mode_static(); + if (SEGLEN <= 1) return mode_static(); if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor() - SEGMENT.fade_out(254); // add a bit of trail - uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4)); - uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment - uint16_t span = (SEGMENT.intensity << 8) / numBirds; + SEGMENT.fade_out(253); // add a bit of trail // WLEDMM fade rate above 253 has no effect + uint32_t counter = ((strip.now * (96 + SEGMENT.speed)) >> 4); // WLEDMM same result, better resolution + uint16_t numBirds = min(32, 2 + (SEGLEN >> 3)); // 2 + 1/8 of a segment - WLEDMM max 32 + uint32_t span = (SEGMENT.intensity << 8) / numBirds; - for (int i = 0; i < numBirds; i++) + for (unsigned i = 0; i < numBirds; i++) { counter -= span; uint16_t megumin = sin16_t(counter) + 0x8000; uint16_t bird = uint32_t(megumin * SEGLEN) >> 16; uint32_t c = SEGMENT.color_from_palette((i * 255)/ numBirds, false, false, 0); // no palette wrapping - bird = constrain(bird, 0, SEGLEN-1); + bird = min(bird, uint16_t(SEGLEN-1)); // WLEDMM unsigned is always >= 0 SEGMENT.setPixelColor(bird, c); } return FRAMETIME; From b0b6ec37fd795e1288dd6924cd0f548e744db63a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 29 Nov 2024 15:05:47 +0100 Subject: [PATCH 29/72] support for benchmarking FastLed vs. WLED triginometry --- wled00/FX.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 238ce0ac33..01314346a1 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -25,6 +25,16 @@ #define indexToVStrip(index, stripNr) ((index) | (int((stripNr)+1)<<16)) +#if 0 // for benchmarking - change to "#if 1" to use less accurate, but 30% faster FastLed sin8 and cos8 functions +#define sin8_t sin8 +#define cos8_t cos8 +#define sin16_t sin16 +#define cos16_t cos16 +#define beatsin8_t beatsin8 +#define beatsin88_t beatsin88 +#define beatsin16_t beatsin16 +#endif + // WLEDMM replace abs8 by abs, as abs8 does not work for numbers >127 #define abs8(x) abs(x) From 9ff235e1538cd1fbd984a3fe5112e9356fe10bd1 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:29:28 +0100 Subject: [PATCH 30/72] Show "NO PSRAM" on info page ... to help diagnose problems that come from wrong PSRAM settings --- wled00/data/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/data/index.js b/wled00/data/index.js index 86e6465bdd..7dced6a4a3 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -717,7 +717,7 @@ ${i.psram?inforow("PSRAM ☾",((i.tpram-i.psram)/1024).toFixed(0)+"/"+(i.tpram/1 ${i.psusedram?inforow("Max used PSRAM ☾",((i.tpram-i.psusedram)/1024).toFixed(0)+" kB",", "+((i.tpram-i.psusedram)*100.0/i.tpram).toFixed(1)+"%"):""} ${i.freestack?inforow("Free stack ☾",(i.freestack/1000).toFixed(3)," kB"):""}
-${i.tpram?inforow("PSRAM " + (i.psrmode?"("+i.psrmode+" mode) ":"") + " ☾",(i.tpram/1024/1024).toFixed(0)," MB"):""} +${i.tpram?inforow("PSRAM " + (i.psrmode?"("+i.psrmode+" mode) ":"") + " ☾",(i.tpram/1024/1024).toFixed(0)," MB"):inforow("NO PSRAM found.", "")} ${i.e32flash?inforow("Flash mode "+i.e32flashmode+i.e32flashtext + " ☾",i.e32flash+" MB, "+i.e32flashspeed," Mhz"):""} ${i.e32model?inforow(i.e32model + " ☾",i.e32cores +" core(s),"," "+i.e32speed+" Mhz"):""} ${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} From a0e03766ef7cc12c42d3116ed3ad98a008f20fe0 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:02:44 +0100 Subject: [PATCH 31/72] blends effect bugfix quick fix for "missing pixel 256" problem --- wled00/FX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 01314346a1..f44db9da23 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4596,7 +4596,7 @@ uint16_t mode_blends(void) { uint16_t offset = 0; for (int i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, pixels[offset++]); - if (offset > pixelLen) offset = 0; + if (offset >= pixelLen) offset = 0; } return FRAMETIME; From 994a9e7212189c6b8cb37224ddd708434325e114 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:15:21 -0500 Subject: [PATCH 32/72] Fix Color Order GUI for Art-Net --- wled00/data/settings_leds.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 62af94b7b7..375cfa39d5 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -222,7 +222,7 @@ } gId("rf"+n).onclick = (t == 31) ? (()=>{return false}) : (()=>{}); // prevent change for TM1814 gRGBW |= isRGBW = ((t > 17 && t < 22) || (t > 28 && t < 32) || (t > 40 && t < 46 && t != 43) || t == 88); // RGBW checkbox, TYPE_xxxx values from const.h - gId("co"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)||(t >= 100 && t < 110)) ? "none":"inline"; // hide color order for PWM + gId("co"+n).style.display = ((t >= 83 && t < 96) || (t >= 40 && t < 48)||(t >= 100 && t < 110)) ? "none":"inline"; // hide color order for PWM gId("dig"+n+"w").style.display = (t > 28 && t < 32) ? "inline":"none"; // show swap channels dropdown gId("dig"+n+"O").style.display = (t == 82 || t == 83) ? "inline":"none"; // show Art-Net output number gId("dig"+n+"L").style.display = (t == 82 || t == 83) ? "inline":"none"; // show Art-Net LEDs per output From f2f621befcc493cad6e7058a3e6d8d8ee9b9f7df Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:48:11 +0100 Subject: [PATCH 33/72] minor FX improvements Fire2012: better randomness Julia: avoid darkening when using "blur" --- wled00/FX.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f44db9da23..c3a5c59564 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2128,12 +2128,16 @@ uint16_t mode_fire_2012() { const uint8_t ignition = max(3,SEGLEN/10); // ignition area: 10% of segment length or minimum 3 pixels + #if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improves randonmess + #endif + // Step 1. Cool down every cell a little for (int i = 0; i < SEGLEN; i++) { uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4); uint8_t minTemp = (ixcen = 0.; julias->ycen = 0.; julias->xymag = 1.0; From 0dbde5a257999e85925d08aa46fc3c01e2cbb809 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:06:47 +0100 Subject: [PATCH 34/72] audioreactive multi-comet (backported from WELD-SR 0.13.4) --- wled00/FX.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ wled00/FX.h | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index c3a5c59564..0f7c7526db 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1794,6 +1794,61 @@ uint16_t mode_multi_comet(void) { } static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = "Multi Comet"; +// audioreactive multi-comet by @softhack007 +uint16_t mode_multi_comet_ar(void) { + constexpr unsigned MAX_COMETS = 16; // was 8 + uint32_t cycleTime = max(1, int((255 - SEGMENT.speed)/4)); + uint32_t it = strip.now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; // too early + + if (!SEGENV.allocateData(sizeof(uint16_t) * MAX_COMETS)) return mode_static(); //allocation failed + uint16_t* comets = reinterpret_cast(SEGENV.data); + if (SEGENV.call == 0) { // do some initializations + SEGMENT.setUpLeds(); SEGMENT.fill(BLACK); + for(uint8_t i=0; i < MAX_COMETS; i++) comets[i] = SEGLEN; // WLEDMM make sure comments are started individually + SEGENV.aux0 = 0; + } + SEGMENT.fade_out(254 - SEGMENT.intensity/2); + + um_data_t *um_data; + if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) um_data = simulateSound(SEGMENT.soundSim); + float volumeSmth = *(float*) um_data->u_data[0]; + int16_t volumeRaw = *(int16_t*) um_data->u_data[1]; + uint8_t samplePeak = *(uint8_t*) um_data->u_data[3]; + + uint16_t armed = SEGENV.aux0; // allows to delay comet launch + + #if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improve randomness (esp32) + #endif + bool shotOne = false; // avoids starting several coments at the same time (invisible due to overlap) + for(unsigned i=0; i < MAX_COMETS; i++) { + if(comets[i] < SEGLEN) { + // draw comet + uint16_t index = comets[i]; + if (SEGCOLOR(2) != 0) + SEGMENT.setPixelColor(index, i % 2 ? SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(2)); + else + SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + comets[i]++; // move + } else { + // randomly launch a new comet + if (random16(min(uint16_t(256), SEGLEN)) < 3) armed++; // new comet loaded and ready + if (armed > 2) armed = 2; // max three armed at once (avoid overlap) + // delay comet "launch" during silence, and wait until next beat + if ( (armed > 0) && (shotOne == false) + && (volumeSmth > 1.0f) && ((samplePeak > 0) || (volumeRaw > 104)) ) { // delayed lauch - wait until peak, don't launch in silence + comets[i] = 0; // start a new comet! + armed--; // un-arm one + shotOne = true; + } + } + } + SEGENV.aux0 = armed; + SEGENV.step = it; + return FRAMETIME; +} +static const char _data_FX_MODE_MULTI_COMET_AR[] PROGMEM = "Multi Comet audio ☾@Speed,Tail Length;!,!;!;1v;sx=160,ix=32,m12=7,si=1"; // Pinwheel, WeWillRockU /* * Running random pixels ("Stream 2") @@ -9017,6 +9072,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_LIGHTNING, &mode_lightning, _data_FX_MODE_LIGHTNING); addEffect(FX_MODE_ICU, &mode_icu, _data_FX_MODE_ICU); addEffect(FX_MODE_MULTI_COMET, &mode_multi_comet, _data_FX_MODE_MULTI_COMET); + addEffect(FX_MODE_MULTI_COMET_AR, &mode_multi_comet_ar, _data_FX_MODE_MULTI_COMET_AR); addEffect(FX_MODE_DUAL_LARSON_SCANNER, &mode_dual_larson_scanner, _data_FX_MODE_DUAL_LARSON_SCANNER); addEffect(FX_MODE_RANDOM_CHASE, &mode_random_chase, _data_FX_MODE_RANDOM_CHASE); addEffect(FX_MODE_OSCILLATE, &mode_oscillate, _data_FX_MODE_OSCILLATE); diff --git a/wled00/FX.h b/wled00/FX.h index beba051747..670c321a74 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -330,7 +330,7 @@ bool strip_uses_global_leds(void) __attribute__((pure)); // WLEDMM implemented // Experimental Audioresponsive modes from WLED-SR // #define FX_MODE_3DSphereMove 189 // experimental WLED-SR "cube" mode #define FX_MODE_POPCORN_AR 190 // WLED-SR audioreactive popcorn -// #define FX_MODE_MULTI_COMET_AR 191 // WLED-SR audioreactive multi-comet +#define FX_MODE_MULTI_COMET_AR 191 // WLED-SR audioreactive multi-comet #define FX_MODE_STARBURST_AR 192 // WLED-SR audioreactive fireworks starburst // #define FX_MODE_PALETTE_AR 193 // WLED-SR audioreactive palette #define FX_MODE_FIREWORKS_AR 194 // WLED-SR audioreactive fireworks From 9922d2aa8d01373a64b96a8685a0be14d264c4f2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:44:46 +0100 Subject: [PATCH 35/72] bugfix: don't render segments that are "off" --- wled00/FX_fcn.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 0f750b0f03..a450dca76e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1913,6 +1913,7 @@ void WS2812FX::service() { seg.resetIfRequired(); if (!seg.isActive()) continue; + if (!seg.on && !seg.transitional) continue; // WLEDMM skip disabled segments, unless a crossfade is ongoing // last condition ensures all solid segments are updated at the same time if(nowUp >= seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) // WLEDMM ">=" instead of ">" From 23d41e66c94e5f111e6dec44e3ed731171c964d2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:04:21 +0100 Subject: [PATCH 36/72] bugfix #2 for switched-off segments segments that are "off" were still rendered during transitions. --- wled00/FX.h | 2 ++ wled00/FX_fcn.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/wled00/FX.h b/wled00/FX.h index 670c321a74..c35c54fb87 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -380,6 +380,7 @@ typedef struct Segment { }; uint8_t grouping, spacing; uint8_t opacity; + uint8_t lastBri; // WLEDMM optimization for black-to-black "transitions" bool needsBlank; // WLEDMM indicates that Segment needs to be blanked (due to change of mirror / reverse / transpose / spacing) uint32_t colors[NUM_COLORS]; uint8_t cct; //0==1900K, 255==10091K @@ -490,6 +491,7 @@ typedef struct Segment { grouping(1), spacing(0), opacity(255), + lastBri(255), needsBlank(false), colors{DEFAULT_COLOR,BLACK,BLACK}, cct(127), diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index a450dca76e..b2d7162f19 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1935,6 +1935,7 @@ void WS2812FX::service() { now = millis() + timebase; #endif seg.startFrame(); // WLEDMM + if (!_triggered && (seg.currentBri(seg.opacity) == 0) && (seg.lastBri == 0)) continue; // WLEDMM skip totally black segments // effect blending (execute previous effect) // actual code may be a bit more involved as effects have runtime data including allocated memory //if (seg.transitional && seg._modeP) (*_mode[seg._modeP])(progress()); @@ -1944,6 +1945,7 @@ void WS2812FX::service() { if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++; if (seg.transitional && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition + seg.lastBri = seg.currentBri(seg.on ? seg.opacity:0); // WLEDMM remember for next time seg.handleTransition(); } From 86ed5a82e3d03df1e2a40af3110cb6935428c880 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:31:52 +0100 Subject: [PATCH 37/72] DNA effect: additional parameter "phases" (thanks @ewoudwijma ) controls the number of phases shown by the effect breaking - the old code was using a fixed width per wave, while the new one always fits the same number waves into the panel width. --- wled00/FX.cpp | 12 +++++++++--- wled00/wled.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 0f7c7526db..f255fa5ada 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5124,6 +5124,7 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); + uint8_t phases = SEGMENT.custom1; if (SEGENV.call == 0) { SEGMENT.setUpLeds(); @@ -5136,8 +5137,13 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa int lastY1 = -1; int lastY2 = -1; for (int i = 0; i < cols; i++) { - int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 ); - int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128); + // int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 ); + ///int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128); + unsigned phase = cols * i / 8; // 256 is a complete phase; half a phase is dna is 128 + phase = i * 4 * phases / cols; // cols ==0 cannot happen due to the for loop + int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, phase ); + int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, phase+128); + if ((i==0) || ((abs(lastY1 - posY1) < 2) && (abs(lastY2 - posY2) < 2))) { // use original code when no holes SEGMENT.setPixelColorXY(i, posY1, ColorFromPalette(SEGPALETTE, i*5+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10), LINEARBLEND)); SEGMENT.setPixelColorXY(i, posY2, ColorFromPalette(SEGPALETTE, i*5+128+strip.now/17, beatsin8_t(5, 55, 255, 0, i*10+128), LINEARBLEND)); @@ -5152,7 +5158,7 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa return FRAMETIME; } // mode_2Ddna() -static const char _data_FX_MODE_2DDNA[] PROGMEM = "DNA@Scroll speed,Blur;;!;2"; +static const char _data_FX_MODE_2DDNA[] PROGMEM = "DNA@Scroll speed,Blur,Phases;;!;2"; ///////////////////////// diff --git a/wled00/wled.h b/wled00/wled.h index 2811036532..7af6b43c3b 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2411290 +#define VERSION 2412030 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ From 9ea2303ecbfc8a0bd5ebe3c8ada6b6c903756846 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:00:26 +0100 Subject: [PATCH 38/72] DNA effect optimization (phases) * non-breaking - reproduces the old behavior at phases = 127 * minor math optimizations * phase boost for large values (good for small panels) --- wled00/FX.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f255fa5ada..53d99886ee 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5119,12 +5119,13 @@ static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Spee ///////////////////// // 2D DNA // ///////////////////// -uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. +uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. Phases added by @ewoudwijma if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - uint8_t phases = SEGMENT.custom1; + unsigned phases = SEGMENT.custom1; + if (phases > 179) phases = 179 + 2.5f * (phases - 179); // boost for values > 179 if (SEGENV.call == 0) { SEGMENT.setUpLeds(); @@ -5137,10 +5138,9 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa int lastY1 = -1; int lastY2 = -1; for (int i = 0; i < cols; i++) { - // int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4 ); - ///int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, i*4+128); - unsigned phase = cols * i / 8; // 256 is a complete phase; half a phase is dna is 128 - phase = i * 4 * phases / cols; // cols ==0 cannot happen due to the for loop + // 256 is a complete phase; half a phase of dna is 128 + // unsigned phase = i * 4 * phases / cols; // original formula; cols ==0 cannot happen due to the for loop + unsigned phase = i * 4 * phases / 128; // WLEDMM this reproduces the previous behaviour at phases=127 int posY1 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, phase ); int posY2 = beatsin8_t(SEGMENT.speed/8, 0, rows-1, 0, phase+128); From f4ac04b9f981659fc539e522d49b03e80b4554c4 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:48:35 +0100 Subject: [PATCH 39/72] Update platformio.ini - fix for duplicate WLED_RELEASE_NAMEs esp32S3_4MB_S and esp32s3_8MB_M were used by two different buildenvs. --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index e49c32dabd..b1ce10e269 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2164,7 +2164,7 @@ board_build.partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; 1.8MB firmware, ;; board_build.partitions = tools/WLED_ESP32_4MB_512KB_FS.csv ;; 1.7MB firmware, 500KB filesystem (esptool erase_flash needed when changing from "standard WLED" partitions) build_flags = ${common.build_flags} ${esp32s3.build_flags} -Wno-misleading-indentation -Wno-format-truncation ${common_mm.build_flags_S} - -D WLED_RELEASE_NAME=esp32S3_4MB_S + -D WLED_RELEASE_NAME=esp32S3_4MB_PSRAM_S -DBOARD_HAS_PSRAM ;; -D WLED_USE_PSRAM -D WLED_USE_PSRAM_JSON -DALL_JSON_TO_PSRAM ; WLEDMM --> force all JSON stuff into PSRAM; gives more free heap -DCONFIG_MBEDTLS_DYNAMIC_BUFFER=1 ;; optional - allows some buffers to use PSRAM @@ -2202,7 +2202,7 @@ board = lolin_s3_mini ;; -S3 mini: 4MB flash 2MB PSRAM board_build.partitions = ${esp32.default_partitions} build_flags = ${common.build_flags} ${esp32s3.build_flags} -Wno-misleading-indentation -Wno-format-truncation ${common_mm.build_flags_S} ${common_mm.build_flags_M} - -D WLED_RELEASE_NAME=esp32S3_4MB_M + -D WLED_RELEASE_NAME=esp32S3_4MB_PSRAM_M -DBOARD_HAS_PSRAM ;; -D WLED_USE_PSRAM -D WLED_USE_PSRAM_JSON -DALL_JSON_TO_PSRAM ; WLEDMM --> force all JSON stuff into PSRAM; gives more free heap -DCONFIG_MBEDTLS_DYNAMIC_BUFFER=1 ;; optional - allows some buffers to use PSRAM From 6763ca1f682b4478351258d8512abafe430ebf09 Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:53:01 -0500 Subject: [PATCH 40/72] Cosmetic 2D Setup change: Start at Panel 1 instead of 0 --- wled00/data/settings_2D.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/data/settings_2D.htm b/wled00/data/settings_2D.htm index c57bf3d9ec..85f9dddb6f 100644 --- a/wled00/data/settings_2D.htm +++ b/wled00/data/settings_2D.htm @@ -98,7 +98,7 @@ var pw = parseInt(d.Sf.PW.value); var ph = parseInt(d.Sf.PH.value); //WLEDMM: change name to id - let b = `

Panel ${i}
+ let b = `

Panel ${i+1}
1st LED: @@ -334,7 +334,7 @@ ctx.font = '40px Arial'; ctx.fillStyle = "orange"; - ctx.fillText(p, topLeftX + pw/2*ppL - 10, topLeftY + ph/2*ppL + 10); + ctx.fillText(p+1, topLeftX + pw/2*ppL - 10, topLeftY + ph/2*ppL + 10); } gId("MD").innerHTML = "Matrix Dimensions (W*H=LC): " + maxWidth + " x " + maxHeight + " = " + maxWidth * maxHeight; } From 102d098e28dc762c426630a28420930f0de2d59d Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:05:37 +0100 Subject: [PATCH 42/72] bugfix #3 for ghostly appearing switched-off segments --- wled00/FX_fcn.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index b2d7162f19..a62ee39b80 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -551,7 +551,7 @@ bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black } - if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change + if (fadeTransition && on) startTransition(strip.getTransition()); // start transition prior to change // WLEDMM only on real change colors[slot] = c; stateChanged = true; // send UDP/WS broadcast return true; @@ -564,7 +564,7 @@ void Segment::setCCT(uint16_t k) { k = (k - 1900) >> 5; } if (cct == k) return; - if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change + if (fadeTransition && on) startTransition(strip.getTransition()); // start transition prior to change cct = k; stateChanged = true; // send UDP/WS broadcast } @@ -628,7 +628,7 @@ void Segment::setPalette(uint8_t pal) { if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes if (pal != palette) { - if (strip.paletteFade) startTransition(strip.getTransition()); + if (strip.paletteFade && on) startTransition(strip.getTransition()); palette = pal; stateChanged = true; // send UDP/WS broadcast } From 972257a7ee8cf800b9ec3d445039727b30003eb4 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:18:39 +0100 Subject: [PATCH 43/72] minor code cleanup * removed dead code * prevent promotion to double * made constants constexpr * made some methods const * fixed a few typo's --- wled00/FX.cpp | 105 +++++++++++++++++++------------------------- wled00/FX.h | 1 - wled00/FX_2Dfcn.cpp | 5 +-- wled00/FX_fcn.cpp | 11 ----- 4 files changed, 46 insertions(+), 76 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 53d99886ee..4e6d702368 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -75,7 +75,7 @@ static int8_t tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) { return 0; } -// float version of map() // WLEDMM moved here so its available for all effects +// float version of map() // WLEDMM moved here so it is available for all effects static float mapf(float x, float in_min, float in_max, float out_min, float out_max){ if (in_max == in_min) return (out_min); // WLEDMM avoid div/0 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; @@ -795,7 +795,7 @@ static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!; * Android loading circle */ uint16_t mode_android(void) { - + if (SEGLEN <= 1) return mode_static(); // WLEDMM to prevent division by zero for (int i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } @@ -1043,7 +1043,7 @@ static const char _data_FX_MODE_TRAFFIC_LIGHT[] PROGMEM = "Traffic Light@!,US st */ #define FLASH_COUNT 4 uint16_t mode_chase_flash(void) { - if (SEGLEN == 1) return mode_static(); + if (SEGLEN <= 1) return mode_static(); uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for (int i = 0; i < SEGLEN; i++) { @@ -2091,7 +2091,7 @@ uint16_t mode_partyjerk() { CRGB rgb(CHSV(SEGENV.aux1, 255, activeColor)); SEGMENT.setPixelColor((uint16_t)i, rgb.r, rgb.g, rgb.b); - }; + } return FRAMETIME; } // mode_partyjerk() @@ -3012,7 +3012,7 @@ uint16_t mode_bouncing_balls(void) { if (SEGLEN == 1) return mode_static(); //allocate segment data const uint16_t strips = SEGMENT.nrOfVStrips(); // adapt for 2D - const size_t maxNumBalls = 16; + constexpr size_t maxNumBalls = 16; uint16_t dataSize = sizeof(ball) * maxNumBalls; if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed @@ -3165,7 +3165,7 @@ static uint16_t rolling_balls(void) { if (thisHeight < 0.0f) thisHeight = 0.0f; if (thisHeight > 1.0f) thisHeight = 1.0f; - uint16_t pos = round(thisHeight * (SEGLEN - 1)); + uint16_t pos = roundf(thisHeight * (SEGLEN - 1)); SEGMENT.setPixelColor(pos, color); balls[i].lastBounceUpdate = strip.now; balls[i].height = thisHeight; @@ -3808,7 +3808,7 @@ uint16_t mode_drip(void) if (SEGLEN == 1) return mode_static(); //allocate segment data uint16_t strips = SEGMENT.nrOfVStrips(); - const int maxNumDrops = 4; + constexpr int maxNumDrops = 4; uint16_t dataSize = sizeof(sparkdrop) * maxNumDrops; if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed SparkDrop* drops = reinterpret_cast(SEGENV.data); @@ -4034,8 +4034,8 @@ uint16_t mode_percent(void) { uint8_t percent = SEGMENT.intensity; percent = constrain(percent, 0, 200); - uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0 - : SEGLEN * (200 - percent) / 100.0; + uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0f + : SEGLEN * (200 - percent) / 100.0f; uint8_t size = (1 + ((SEGMENT.speed * SEGLEN) >> 11)); if (SEGMENT.speed == 255) size = 255; @@ -4137,7 +4137,7 @@ static const char _data_FX_MODE_HEARTBEAT[] PROGMEM = "Heartbeat@!,!;!,!;!;01;m1 // Modified for WLED, based on https://github.com/FastLED/FastLED/blob/master/examples/Pacifica/Pacifica.ino // // Add one layer of waves into the led array -CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) +CRGB pacifica_one_layer(uint16_t i, const CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) { uint16_t ci = cistart; uint16_t waveangle = ioff; @@ -4294,7 +4294,7 @@ uint16_t phased_base(uint8_t moder) { // We're making sine wave uint8_t modVal = 5;//SEGMENT.fft1/8+1; // You can change the modulus. AKA FFT1 (was 5). uint8_t index = strip.now/64; // Set color rotation speed - *phase += SEGMENT.speed/32.0; // You can change the speed of the wave. AKA SPEED (was .4) + *phase += SEGMENT.speed/32.0f; // You can change the speed of the wave. AKA SPEED (was .4) for (int i = 0; i < SEGLEN; i++) { if (moder == 1) modVal = (inoise8(i*10 + i*10) /16); // Let's randomize our mod length with some Perlin noise. @@ -4518,7 +4518,7 @@ uint16_t mode_dancing_shadows(void) if (!initialize) { // advance the position of the spotlight int16_t delta = (float)(time - spotlights[i].lastUpdateTime) * - (spotlights[i].speed * ((1.0 + SEGMENT.speed)/100.0)); + (spotlights[i].speed * ((1.0f + SEGMENT.speed)/100.0f)); if (abs(delta) >= 1) { spotlights[i].position += delta; @@ -4533,15 +4533,15 @@ uint16_t mode_dancing_shadows(void) spotlights[i].colorIdx = random8(); spotlights[i].width = random8(1, 10); - spotlights[i].speed = 1.0/random8(4, 50); + spotlights[i].speed = 1.0f/random8(4, 50); if (initialize) { spotlights[i].position = random16(SEGLEN); - spotlights[i].speed *= random8(2) ? 1.0 : -1.0; + spotlights[i].speed *= random8(2) > 0 ? 1.0 : -1.0; } else { if (random8(2)) { spotlights[i].position = SEGLEN + spotlights[i].width; - spotlights[i].speed *= -1.0; + spotlights[i].speed *= -1.0f; }else { spotlights[i].position = -spotlights[i].width; } @@ -5038,7 +5038,7 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma } SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails - const unsigned long ratio = 128; // rotation speed + constexpr unsigned long ratio = 128; // rotation speed unsigned long t = strip.now; // timebase // outer stars for (unsigned i = 0; i < 8; i++) { @@ -5342,7 +5342,7 @@ class GameOfLifeGrid { const int8_t offsetY[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; public: GameOfLifeGrid(Cell* data, int c, int r) : cells(data), cols(c), rows(r), maxIndex(r * c) {} - void getNeighborIndexes(unsigned neighbors[9], unsigned cIndex, unsigned x, unsigned y, bool wrap) { + void getNeighborIndexes(unsigned neighbors[9], unsigned cIndex, unsigned x, unsigned y, bool wrap) const { unsigned neighborCount = 0; bool edgeCell = x == 0 || x == cols-1 || y == 0 || y == rows-1; for (unsigned i = 0; i < 8; ++i) { @@ -5363,7 +5363,7 @@ class GameOfLifeGrid { } neighbors[0] = neighborCount; } - void setCell(unsigned cIndex, unsigned x, unsigned y, bool alive, bool wrap) { + void setCell(unsigned cIndex, unsigned x, unsigned y, bool alive, bool wrap) const { Cell* cell = &cells[cIndex]; if (alive == cell->alive) return; // No change cell->alive = alive; @@ -5372,7 +5372,7 @@ class GameOfLifeGrid { int val = alive ? 1 : -1; for (unsigned i = 1; i <= neighbors[0]; ++i) cells[neighbors[i]].neighbors += val; } - void recalculateEdgeNeighbors(bool wrap) { + void recalculateEdgeNeighbors(bool wrap) const { unsigned cIndex = 0; for (unsigned y = 0; y < rows; ++y) for (unsigned x = 0; x < cols; ++x, ++cIndex) { Cell* cell = &cells[cIndex]; @@ -5811,7 +5811,7 @@ uint16_t mode_2DJulia(void) { // An animated Julia set maxIterations = SEGMENT.intensity/2; - // Resize section on the fly for some animaton. + // Resize section on the fly for some animation. reAl = -0.94299f; // PixelBlaze example imAg = 0.3162f; @@ -5820,8 +5820,8 @@ uint16_t mode_2DJulia(void) { // An animated Julia set reAl += (float)sin16_t(strip.now * 34) / 655340.f; imAg += (float)sin16_t(strip.now * 26) / 655340.f; - dx = (xmax - xmin) / (cols); // Scale the delta x and y values to our matrix size. - dy = (ymax - ymin) / (rows); + dx = (xmax - xmin) / cols; // Scale the delta x and y values to our matrix size. + dy = (ymax - ymin) / rows; // Start y float y = ymin; @@ -5867,8 +5867,8 @@ uint16_t mode_2DJulia(void) { // An animated Julia set if(SEGMENT.check2) SEGMENT.blur(64, true); // strong blurr if(SEGMENT.check3) { // draw crosshair - int screenX = lround((0.5f / maxCenter) * (julias->xcen + maxCenter) * float(cols)); - int screenY = lround((0.5f / maxCenter) * (julias->ycen + maxCenter) * float(rows)); + int screenX = lroundf((0.5f / maxCenter) * (julias->xcen + maxCenter) * float(cols)); + int screenY = lroundf((0.5f / maxCenter) * (julias->ycen + maxCenter) * float(rows)); int hair = min(min(cols-1, rows-1)/2, 3); SEGMENT.drawLine(screenX, screenY-hair, screenX, screenY+hair, GREEN, true); SEGMENT.drawLine(screenX-hair, screenY, screenX+hair, screenY, GREEN, true); @@ -6039,7 +6039,7 @@ uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have byte color = dist ? 1000 / dist : 255; // map color between thresholds - if (color > 0 and color < 60) { + if (color > 0 && color < 60) { SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(map(color * 9, 9, 531, 0, 255), false, PALETTE_SOLID_WRAP, 0)); } else { SEGMENT.setPixelColorXY(x, y, SEGMENT.color_from_palette(0, false, PALETTE_SOLID_WRAP, 0)); @@ -6458,8 +6458,6 @@ uint16_t mode_2Dcrazybees(void) { int8_t signX, signY; int16_t deltaX, deltaY, error; void aimed(uint_fast16_t w, uint_fast16_t h) { - if (!true) //WLEDMM SuperSync - random16_set_seed(strip.now); aimX = random8(0, min(UINT8_MAX, int(w))); aimY = random8(0, min(UINT8_MAX, int(h))); hue = random8(); @@ -6475,8 +6473,7 @@ uint16_t mode_2Dcrazybees(void) { bee_t *bee = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - if (true) //WLEDMM SuperSync - random16_set_seed(strip.now); + random16_set_seed(strip.now); //WLEDMM SuperSync SEGMENT.setUpLeds(); SEGMENT.fill(BLACK); for (size_t i = 0; i < n; i++) { @@ -7017,7 +7014,7 @@ uint16_t mode_2DSwirl(void) { SEGMENT.fill(BLACK); } - const uint8_t borderWidth = 2; + constexpr uint8_t borderWidth = 2; SEGMENT.blur(SEGMENT.custom1); @@ -7106,7 +7103,7 @@ typedef struct Gravity { /////////////////////// uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. - const uint16_t dataSize = sizeof(gravity); + constexpr uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Gravity* gravcen = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { @@ -7123,7 +7120,7 @@ uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivity" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0, 0, 32, 0, (float)SEGLEN/2.0); // map to pixels available in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0, 32, 0, (float)SEGLEN/2.0f); // map to pixels available in current segment uint16_t tempsamp = constrain(mySampleAvg, 0, SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -7171,10 +7168,10 @@ uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew //SEGMENT.fade_out(240); // twice? really? SEGMENT.fade_out(253); // 50% - float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0; + float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivity" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0, 0.0f, 32.0f, 0.0f, (float)SEGLEN/2.0); // map to pixels availeable in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0.0f, 32.0f, 0.0f, (float)SEGLEN/2.0f); // map to pixels availeable in current segment int tempsamp = constrain(mySampleAvg, 0, SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -7226,7 +7223,7 @@ uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. float realVolume = volumeSmth; if (SEGENV.check3 && SEGENV.check2) SEGENV.check2 = false; // only one option if (SEGENV.check2) volumeSmth = soundPressure; - if (SEGENV.check3) volumeSmth = 255.0 - agcSensitivity; + if (SEGENV.check3) volumeSmth = 255.0f - agcSensitivity; SEGMENT.fade_out(253); float sensGain = (float)(SEGMENT.intensity+2) / 257.0f; // min gain = 1/128 @@ -7287,7 +7284,7 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor() SEGMENT.fade_out(224); // 6.25% - uint16_t my_sampleAgc = fmax(fmin(volumeSmth, 255.0), 0); + uint16_t my_sampleAgc = max(min(volumeSmth, 255.0f), 0.0f); for (size_t i=0; iSEGLEN/2) maxLen = SEGLEN/2; @@ -7429,7 +7426,7 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline. uint8_t fadeRate = map2(SEGMENT.speed,0,255,200,254); SEGMENT.fade_out(fadeRate); - float tmpSound2 = volumeRaw * 2.0 * (float)SEGMENT.intensity / 255.0; + float tmpSound2 = volumeRaw * 2.0f * (float)SEGMENT.intensity / 255.0f; int maxLen = mapf(tmpSound2, 0, 255, 0, SEGLEN); // map to pixels availeable in current segment // Still a bit too sensitive. if (maxLen <0) maxLen = 0; if (maxLen >SEGLEN) maxLen = SEGLEN; @@ -7974,14 +7971,14 @@ uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschun int lowerLimit = 80 + 3 * SEGMENT.custom1; // min 80hz-850hz i = lowerLimit!=upperLimit ? mapf(FFT_MajorPeak, lowerLimit, upperLimit, 0, 255) : FFT_MajorPeak; // may under/overflow - so we enforce uint8_t } else { - // Musical Scale (logarythmic scaling) + // Musical Scale (logarithmic scaling) float upperLimit = logf(80 + 42 * SEGMENT.custom2); // max 80hz-10Khz float lowerLimit = logf(80 + 3 * SEGMENT.custom1); // min 80hz-850hz float peakMapped = fabsf(lowerLimit - upperLimit)>0.05f ? mapf(logf(FFT_MajorPeak), lowerLimit, upperLimit, 0, 255) : FFT_MajorPeak; // may under/overflow if (peakMapped > 255) intensity = constrain((320-peakMapped), 0, intensity*100) / 100.0f; // too high: fade away i = constrain(peakMapped, 0, 255); // fix over / underflow } - uint16_t b = 255.0 * intensity; + uint16_t b = 255.0f * intensity; if (b > 255) b=255; color = CHSV(i, 176+(uint8_t)b/4, (uint8_t)b); // implicit conversion to RGB supplied by FastLED } @@ -8023,7 +8020,7 @@ uint16_t mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivity" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0,32, 0, (float)SEGLEN/2.0); // map to pixels availeable in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0,32, 0, (float)SEGLEN/2.0f); // map to pixels available in current segment int tempsamp = constrain(mySampleAvg,0,SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -8542,21 +8539,12 @@ uint16_t mode_2Dsoap() { // init if (SEGENV.call == 0) { - if (true) {//WLEDMM SuperSync - random16_set_seed(535); - USER_PRINTF("SuperSync\n"); - } + random16_set_seed(535); //WLEDMM SuperSync SEGENV.setUpLeds(); SEGMENT.fill(BLACK); *noise32_x = random16(); *noise32_y = random16(); *noise32_z = random16(); - } else { - if (!true) { //WLEDMM SuperSync - *noise32_x += mov; - *noise32_y += mov; - *noise32_z += mov; - } } //WLEDMM: changing noise calculation for SuperSync to make it deterministic using strip.now @@ -8564,11 +8552,10 @@ uint16_t mode_2Dsoap() { uint32_t noise32_y_MM = *noise32_y; uint32_t noise32_z_MM = *noise32_z; - if (true) { //WLEDMM SuperSync - noise32_x_MM = *noise32_x + mov * strip.now / 100; //10 fps (original 20-40 fps, depending on realized fps) - noise32_y_MM = *noise32_y + mov * strip.now / 100; - noise32_z_MM = *noise32_z + mov * strip.now / 100; - } + //WLEDMM SuperSync + noise32_x_MM = *noise32_x + mov * strip.now / 100; //10 fps (original 20-40 fps, depending on realized fps) + noise32_y_MM = *noise32_y + mov * strip.now / 100; + noise32_z_MM = *noise32_z + mov * strip.now / 100; for (int i = 0; i < cols; i++) { int32_t ioffset = scale32_x * (i - cols / 2); @@ -8689,8 +8676,6 @@ uint16_t mode_2Doctopus() { // re-init if SEGMENT dimensions or offset changed if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows || SEGMENT.custom1 != *offsX || SEGMENT.custom2 != *offsY) { - if (!true) //WLEDMM SuperSync - SEGENV.step = 0; // t SEGENV.aux0 = cols; SEGENV.aux1 = rows; *offsX = SEGMENT.custom1; @@ -8968,7 +8953,7 @@ uint16_t mode_2DPaintbrush() { byte y1 = beatsin8_t(max(16,int(SEGMENT.speed))/16*3 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1); byte y2 = beatsin8_t(max(16,int(SEGMENT.speed))/16*4 + fftResult[0]/16, 0, (rows-1), fftResult[bin], SEGENV.aux1); - int length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); + int length = sqrtf((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); length = map8(fftResult[bin],0,length); if (length > max(1,int(SEGMENT.custom3))) { diff --git a/wled00/FX.h b/wled00/FX.h index c35c54fb87..5e8ae60acd 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -429,7 +429,6 @@ typedef struct Segment { // WLEDMM cache some values that won't change while drawing a frame bool _isValid2D = false; uint8_t _brightness = 255; // final pixel brightness - including transitions and segment opacity - bool _firstFill = true; // dirty HACK support uint16_t _2dWidth = 0; // virtualWidth uint16_t _2dHeight = 0; // virtualHeight uint16_t _virtuallength = 0; // virtualLength diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 4d58143bff..2c7d0fc851 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -259,9 +259,6 @@ void Segment::startFrame(void) { _2dHeight = calc_virtualHeight(); _2dWidth = _isValid2D ? calc_virtualWidth() : calc_virtualLength(); _virtuallength = calc_virtualLength(); - #if 0 && defined(WLED_ENABLE_HUB75MATRIX) - _firstFill = true; // dirty HACK - #endif #endif } // WLEDMM end @@ -402,7 +399,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa, bool fast if (Segment::maxHeight==1) return; // not a matrix set-up if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized -#if 0 // depricated +#if 0 // deprecated const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index a62ee39b80..462bb7e7af 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1399,17 +1399,6 @@ void Segment::refreshLightCapabilities() { */ void __attribute__((hot)) Segment::fill(uint32_t c) { if (!isActive()) return; // not active - - #if 0 && defined(WLED_ENABLE_HUB75MATRIX) && defined(WLEDMM_FASTPATH) - // DIRTY HACK - this ignores the first fill(black) in each frame, knowing that HUB75 has already blanked out the display. - if (_firstFill) { - _firstFill = false; - if (c == BLACK) { - if (ledsrgb && ledsrgbSize > 0) memset(ledsrgb, 0, ledsrgbSize); - return; - } - } - #endif const uint_fast16_t cols = is2D() ? virtualWidth() : virtualLength(); // WLEDMM use fast int types const uint_fast16_t rows = virtualHeight(); // will be 1 for 1D From a5e9df66684c5dc5bc132dd1d90efd63a5bfe87c Mon Sep 17 00:00:00 2001 From: Troy <5659019+troyhacks@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:14:03 -0500 Subject: [PATCH 44/72] Revert "Merge pull request #204 from troyhacks/Strip_Level_Color_Adjust" This reverts commit db55872732889daf449b1b66317f7c783f2ee0d6, reversing changes made to 972257a7ee8cf800b9ec3d445039727b30003eb4. --- usermods/audioreactive/audio_reactive.h | 2 +- usermods/audioreactive/audio_source.h | 18 +++--------------- wled00/bus_manager.cpp | 6 +----- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 1e5f968196..5e343a2b30 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -348,7 +348,7 @@ static float lastFftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // backup #if !defined(CONFIG_IDF_TARGET_ESP32C3) // audio source parameters and constant -constexpr SRate_t SAMPLE_RATE = 96000; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms +constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms //constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms //constexpr SRate_t SAMPLE_RATE = 20480; // Base sample rate in Hz - 20Khz is experimental. Physical sample time -> 25ms //constexpr SRate_t SAMPLE_RATE = 10240; // Base sample rate in Hz - previous default. Physical sample time -> 50ms diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index 2313001b99..e8bba8efc5 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -186,7 +186,6 @@ class AudioSource { bool _i2sMaster; // when false, ESP32 will be in I2S SLAVE mode (for devices that only operate in MASTER mode). Only works in newer IDF >= 4.4.x float _sampleScale; // pre-scaling factor for I2S samples I2S_datatype newSampleBuffer[I2S_SAMPLES_MAX+4] = { 0 }; // global buffer for i2s_read - I2S_datatype newSampleBuffer4x[(I2S_SAMPLES_MAX*4)+4] = { 0 }; // global buffer for i2s_read }; /* Basic I2S microphone source @@ -195,12 +194,12 @@ class AudioSource { */ class I2SSource : public AudioSource { public: - I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=false) : + I2SSource(SRate_t sampleRate, int blockSize, float sampleScale = 1.0f, bool i2sMaster=true) : AudioSource(sampleRate, blockSize, sampleScale, i2sMaster) { _config = { .mode = i2sMaster ? i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX) : i2s_mode_t(I2S_MODE_SLAVE | I2S_MODE_RX), - .sample_rate = _sampleRate, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates - .bits_per_sample = I2S_SAMPLE_RESOLUTION, + .sample_rate = _sampleRate, + .bits_per_sample = I2S_SAMPLE_RESOLUTION, // slave mode: may help to set this to 96000, as the other side (master) controls sample rates .channel_format = I2S_MIC_CHANNEL, #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S), @@ -395,8 +394,6 @@ class I2SSource : public AudioSource { memset(buffer, 0, sizeof(float) * num_samples); // clear output buffer I2S_datatype *newSamples = newSampleBuffer; // use global input buffer - I2S_datatype *newSamples_buff = newSampleBuffer4x; // use oversampling global input buffer - if (num_samples > I2S_SAMPLES_MAX) num_samples = I2S_SAMPLES_MAX; // protect the buffer from overflow err = i2s_read(AR_I2S_PORT, (void *)newSamples, num_samples * sizeof(I2S_datatype), &bytes_read, portMAX_DELAY); @@ -411,15 +408,6 @@ class I2SSource : public AudioSource { return; } - if (_sampleRate == 96000) { - int current = 0; - for (int i = 0; i < 2048; i += 4) { - newSamples[current] = newSamples_buff[i]; - current++; - } - num_samples /= 4; // back to 512 samples - } - // Store samples in sample buffer and update DC offset for (int i = 0; i < num_samples; i++) { diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index ff12b85eb1..5dd51d0afb 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -102,7 +102,7 @@ uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaul uint8_t swapW = defaultColorOrder >> 4; for (uint8_t i = 0; i < _count; i++) { if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) { - return _mappings[i].colorOrder | (swapW << 4); // WLED-MM/TroyHacks: Disabling this disables color order mapping. + return _mappings[i].colorOrder | (swapW << 4); } } return defaultColorOrder; @@ -202,10 +202,6 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break; } } - if (_colorOrder != co) { - c = RGBW32(dim8_lin(R(c)), dim8_lin(G(c)), dim8_lin(B(c)), 0); // WLED-MM/TroyHacks - remap pixels not in the default color order - co = _colorOrder; // keep the original color order, as this is a hack. :) - } PolyBus::setPixelColor(_busPtr, _iType, pix, c, co); } From 2cc08486fdd32d7793335c4456e055ec49cf5fa1 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:09:05 +0100 Subject: [PATCH 45/72] change version numbering scheme * use 14.5.0-dev instead of "0.14.5.0-b32.41.dev" * new release name "Small Step" * semantic versioning compatibility checked, see https://jubianchi.github.io/semver-check/#/version/14.5.0-dev --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- wled00/data/index.js | 16 +++++++++------- wled00/improv.cpp | 5 +++-- wled00/wled.h | 5 ++--- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 34b5904de5..937dfa9c50 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -48,7 +48,7 @@ body: attributes: label: What version/release of MM WLED? description: You can find this in by going to Config -> Security & Updates -> Scroll to Bottom. Copy and paste the entire line after "Server message" - placeholder: "e.g. build 2401290, WLEDMM_0.14.1-b32.40_esp32_4MB_M.bin" + placeholder: "e.g. build 2401290, WLEDMM_14.5.0-beta_esp32_4MB_M.bin" validations: required: true - type: dropdown diff --git a/package-lock.json b/package-lock.json index 59697131a3..d6cd2b9c05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wled", - "version": "0.14.1-b32.41.dev", + "version": "14.5.0-dev", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wled", - "version": "0.14.1-b32.41.dev", + "version": "14.5.0-dev", "license": "EUPL-1.2", "dependencies": { "clean-css": "^4.2.3", diff --git a/package.json b/package.json index b6763b3347..4e82f27c5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.14.1-b32.41.dev", + "version": "14.5.0-dev", "description": "Tools for WLED project", "main": "tools/cdata.js", "directories": { diff --git a/wled00/data/index.js b/wled00/data/index.js index 7dced6a4a3..fb183d820d 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -684,18 +684,20 @@ function populateInfo(i) urows += inforow(k,val); } } - var vcn = "Kuuhaku"; - if (i.ver.startsWith("0.14.")) vcn = "Hoshi"; + var vcn = "Small Step"; // WLED-MM 14.5.0, release Dec 2024 +// if (i.ver.startsWith("0.14.")) vcn = "Hoshi"; // if (i.ver.includes("-bl")) vcn = "Supāku"; if (i.cn) vcn = i.cn; //WLEDMM: add total heap and total PSRAM, and build number, add bin name - if (i.ver.includes("0.14.0")) vcn = "Lupo"; // check for MM versioning scheme - if (i.ver.includes("0.14.0-b15")) vcn = "Sitting Ducks"; // late easter egg - if (i.ver.includes("0.14.0-b2")) vcn = "This is the way"; // recently watched The Mandalorian? I have spoken ;-) - if (i.ver.includes("0.14.0-b15.22")) vcn = "Lupo"; - if (i.ver.includes("0.14.1-b3")) vcn = "Fried Chicken"; // final line of "One Vision" by Queen + //if (i.ver.includes("0.14.0")) vcn = "Lupo"; // check for MM versioning scheme + //if (i.ver.includes("0.14.0-b15")) vcn = "Sitting Ducks"; // late easter egg + //if (i.ver.includes("0.14.0-b2")) vcn = "This is the way"; // recently watched The Mandalorian? I have spoken ;-) + //if (i.ver.includes("0.14.0-b15.22")) vcn = "Lupo"; + //if (i.ver.includes("0.14.1-b")) vcn = "Fried Chicken"; // final line of "One Vision" by Queen if (i.ver.includes("0.14.3-b")) vcn = "Fried Chicken"; + if (i.ver.includes("14.5.")) vcn = "Small Step"; + cn += `v${i.ver}  "${vcn}"

(WLEDMM ${i.rel}.bin)

build ${i.vid}

${urows} ${urows===""?'':''} diff --git a/wled00/improv.cpp b/wled00/improv.cpp index afcbbbb2e5..cbe292c729 100644 --- a/wled00/improv.cpp +++ b/wled00/improv.cpp @@ -210,8 +210,9 @@ void sendImprovInfoResponse() { //Use serverDescription if it has been changed from the default "WLED", else mDNS name bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0); - char vString[32]; - snprintf_P(vString, sizeof(vString)-1, PSTR("0.14.1-b32.41/%i"),VERSION); + char vString[32] = { '\0' }; + //snprintf_P(vString, sizeof(vString)-1, PSTR("0.14.1-b34.42/%i"),VERSION); // upstream baseline + snprintf_P(vString, sizeof(vString)-1, PSTR("14.5.0-dev/%i"),VERSION); // WLEDMM version const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription}; sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str); diff --git a/wled00/wled.h b/wled00/wled.h index 7af6b43c3b..f146c35bca 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -3,12 +3,11 @@ /* Main sketch, global variable declarations @title WLED project sketch - @version 0.14.1-b1x - @author Christian Schwinne + @version 14.5.0-dev */ // version code in format yymmddb (b = daily build) -#define VERSION 2412030 +#define VERSION 2412110 // WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED. #define _MoonModules_WLED_ From 40bfe619b9155d893e77366f60d29e81155e4560 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:52:02 +0100 Subject: [PATCH 46/72] bugfix: avoid double blanking segments if both seg.reset and seg.needsBlank were set, this caused a second (unwanted) blanking in frame 1. --- wled00/FX_fcn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 462bb7e7af..78a17b3358 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -277,7 +277,7 @@ void Segment::resetIfRequired() { next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; reset = false; // setOption(SEG_OPTION_RESET, false); startFrame(); // WLEDMM update cached propoerties - if (isActive() && !freeze) fill(BLACK); // WLEDMM start clean + if (isActive() && !freeze) { fill(BLACK); needsBlank = false; } // WLEDMM start clean DEBUG_PRINTLN("Segment reset"); } else if (needsBlank) { startFrame(); // WLEDMM update cached propoerties From 3ef8d93bbe5afd50956ad5a3aeb5fca62f963baa Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:50:39 +0100 Subject: [PATCH 47/72] another attempt to reduces flickering * BusManager::show(): explicitly wait until the bus driver is idle (done by NPB show, too, but in a different way) * BusManager::removeAll(): use delay() instead of yield() - yield() does _not_ free the processor on esp32! --- wled00/bus_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 5dd51d0afb..2c87c498e8 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -1268,7 +1268,11 @@ int BusManager::add(BusConfig &bc) { void BusManager::removeAll() { DEBUG_PRINTLN(F("Removing all.")); //prevents crashes due to deleting busses while in use. +#if !defined(ARDUINO_ARCH_ESP32) while (!canAllShow()) yield(); +#else + while (!canAllShow()) delay(2); // WLEDMM on esp32, yield() doesn't work as you think it would +#endif for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; numBusses = 0; // WLEDMM clear cached Bus info @@ -1279,6 +1283,10 @@ void BusManager::removeAll() { void __attribute__((hot)) BusManager::show() { for (unsigned i = 0; i < numBusses; i++) { +#if 1 && defined(ARDUINO_ARCH_ESP32) + unsigned long t0 = millis(); + while ((busses[i]->canShow() == false) && (millis() - t0 < 80)) delay(1); // WLEDMM experimental: wait until bus driver is ready (max 80ms) - costs us 1-2 fps but reduces flickering +#endif busses[i]->show(); } } From 6e14dac0498e621c8ca96b9970db36514c7b2d23 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:25:46 +0100 Subject: [PATCH 48/72] ripple and rain effect fixes (for large fixtures) * made timing calculations work with large led counts * improve randomness by injecting esp_random() * ripple 2D: avoid ugly artifacts, by limiting circles to on-screen coordibnates --- wled00/FX.cpp | 23 +++++++++++++++++++---- wled00/FX.h | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 4e6d702368..04a77701f2 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1289,6 +1289,9 @@ static uint16_t mode_fireworks_core(bool useaudio) { if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur + #if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improve randomness (esp32) + #endif if (addPixels) // WLEDMM for (int i=0; i> 2), MAX_RIPPLES); // 56 max for 16 segment ESP8266 uint16_t dataSize = sizeof(ripple) * maxRipples; + const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const int16_t maxDim = max(2, (cols + rows) / 4); // WLEDMM + #if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improve randomness (esp32) + #endif + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor() @@ -2638,7 +2648,9 @@ uint16_t ripple_base() uint16_t cx = rippleorigin >> 8; uint16_t cy = rippleorigin & 0xFF; uint8_t mag = scale8(sin8_t((propF>>2)), amp); - if (propI > 0) SEGMENT.drawCircle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag), true); + propI = min(propI, maxDim); // WLEDMM make sure that circles are visible + if ((propI > 0) && (unsigned(cx + propI) < cols) && (unsigned(cy) < rows)) // WLEDMM + SEGMENT.drawCircle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag), true); } else #endif { @@ -3687,6 +3699,9 @@ uint16_t mode_exploding_fireworks(void) float gravity = -0.0004f - (SEGMENT.speed/800000.0f); // m/s/s gravity *= rows; +#if defined(ARDUINO_ARCH_ESP32) + random16_add_entropy(esp_random() & 0xFFFF); // improves randonmess +#endif if (SEGENV.aux0 < 2) { //FLARE if (SEGENV.aux0 == 0) { //init flare @@ -3708,7 +3723,7 @@ uint16_t mode_exploding_fireworks(void) flare->pos += flare->vel; flare->posX += flare->velX; flare->pos = constrain(flare->pos, 0, rows-1); - flare->posX = constrain(flare->posX, 0, cols-strip.isMatrix); + flare->posX = constrain(flare->posX, 0, cols-int(strip.isMatrix)); flare->vel += gravity; flare->col -= 2; } else { @@ -3738,10 +3753,10 @@ uint16_t mode_exploding_fireworks(void) sparks[i].colIndex = random8(); sparks[i].vel *= flare->pos/rows; // proportional to height sparks[i].velX *= strip.isMatrix ? flare->posX/cols : 0; // proportional to width - sparks[i].vel *= -gravity *50; + sparks[i].vel *= -gravity *50.0f; } //sparks[1].col = 345; // this will be our known spark - *dying_gravity = gravity/2; + *dying_gravity = gravity/2.0f; SEGENV.aux0 = 3; } diff --git a/wled00/FX.h b/wled00/FX.h index 5e8ae60acd..e09246953a 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -94,7 +94,7 @@ bool strip_uses_global_leds(void) __attribute__((pure)); // WLEDMM implemented #define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */ #define SEGPALETTE Segment::getCurrentPalette() #define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */ -#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN) +#define SPEED_FORMULA_L (4U + (50U*(255U - SEGMENT.speed))/min(SEGLEN, uint16_t(512))) // WLEDMM limiting the formula to 512 virtual pixels // some common colors #define RED (uint32_t)0xFF0000 From 636dd2afa8fa4e5229d68993cf1dfc19b3f9bd57 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:35:32 +0100 Subject: [PATCH 49/72] Fix CI builds by explicitly requiring ubuntu-22.04 --- .github/workflows/wled-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/wled-ci.yml b/.github/workflows/wled-ci.yml index d311af4ac0..8a44db719d 100644 --- a/.github/workflows/wled-ci.yml +++ b/.github/workflows/wled-ci.yml @@ -6,7 +6,7 @@ jobs: get_default_envs: name: Gather Environments - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Cache pip @@ -31,7 +31,7 @@ jobs: build: name: Builds - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: get_default_envs strategy: fail-fast: false @@ -74,7 +74,7 @@ jobs: path: build_output/release/*.bin release: name: Create Release - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: [get_default_envs, build] if: startsWith(github.ref, 'refs/tags/') steps: From 37d0086aadb761d3de7cd71de86721e2292760dd Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:38:25 +0100 Subject: [PATCH 50/72] tiny change to test CI builds --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 83c488e4b4..a44a82b3ae 100644 --- a/readme.md +++ b/readme.md @@ -14,7 +14,7 @@ image -MoonModules/WLED is a fork from [Aircoookie/WLED](https://github.com/Aircoookie/WLED) which contains latest merge of v0.14 of WLED with [additional features](https://mm.kno.wled.ge/moonmodules/what-is-moonmodules/). +MoonModules/WLED is a fork of [Aircoookie/WLED](https://github.com/Aircoookie/WLED) which contains latest merge of v0.14 of WLED with [additional features](https://mm.kno.wled.ge/moonmodules/what-is-moonmodules/). This fork is created by members of the [Atuline/WLED](https://github.com/atuline/WLED) team to make development against v0.14 possible while still preserving [Atuline/WLED v0.13.x](https://github.com/atuline/WLED/tree/dev) as a stable and supported version. The Atuline/WLED fork is also called WLED SR (Sound Reactive). From a37e20560dfd120db5d2d8b7645197f1eb6c5f79 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:16:39 +0100 Subject: [PATCH 51/72] minor HTML and CSS fixes * duplicate use of ID "heart" * "& " --> "& " * missed changes in simple UI --- wled00/data/index.css | 6 ++++++ wled00/data/index.htm | 2 +- wled00/data/index.js | 1 + wled00/data/settings.htm | 4 ++-- wled00/data/settings_leds.htm | 2 +- wled00/data/settings_wifi.htm | 4 ++-- wled00/data/simple.css | 6 ++++++ wled00/data/simple.htm | 1 + wled00/data/simple.js | 7 ++++--- 9 files changed, 24 insertions(+), 9 deletions(-) diff --git a/wled00/data/index.css b/wled00/data/index.css index 617f971bd0..deb0cc64e7 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -665,6 +665,12 @@ button { color: #f00; } +#heartMM { + transition: color 0.9s; + font-size: 16px; + color: #0f0; +} + img { max-width: 100%; max-height: 100%; diff --git a/wled00/data/index.htm b/wled00/data/index.htm index e0c9ca547c..57fca4cf8e 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -389,7 +389,7 @@
WLED made with ❤︎ by Aircoookie and the WLED community
- WLED MM made with ❤︎ by Softhack007 & Ewowi and the WLED 2D & Audio Dev community + WLED MM made with ❤︎ by Softhack007 & Ewowi and the WLED 2D & Audio Dev community
- + diff --git a/wled00/data/simple.css b/wled00/data/simple.css index 87eecee736..b7b9a30d12 100644 --- a/wled00/data/simple.css +++ b/wled00/data/simple.css @@ -361,6 +361,12 @@ button:hover { color: #f00; } +#heartMM { + transition: color 0.9s; + font-size: 16px; + color: #0f0; +} + img { max-width: 100%; max-height: 100%; diff --git a/wled00/data/simple.htm b/wled00/data/simple.htm index 955bd65d81..599ee1102c 100644 --- a/wled00/data/simple.htm +++ b/wled00/data/simple.htm @@ -246,6 +246,7 @@ Made with ❤︎ by Aircoookie and the WLED community + WLED MM made with ❤︎ by Softhack007 & Ewowi and the WLED 2D & Audio Dev community

${urows} ${inforow("Build",i.vid)} @@ -1281,7 +1282,7 @@ function setBalance(b) var hc = 0; setInterval(()=>{if (!isInfo) return; hc+=18; if (hc>300) hc=0; if (hc>200)hc=306; if (hc==144) hc+=36; if (hc==108) hc+=18; -gId('heart').style.color = `hsl(${hc}, 100%, 50%)`;}, 910); +gId('heart').style.color = `hsl(${hc}, 100%, 50%)`; gId('heartMM').style.color = `hsl(${hc}, 100%, 50%)`;}, 910); function openGH() { window.open("https://github.com/Aircoookie/WLED/wiki"); } From 151e7a8a69520de7c8ad49fc59c53ceb09917c31 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:21:33 +0100 Subject: [PATCH 52/72] WiFi -> Wi-Fi The official spelling is 'Wi-Fi' --- wled00/data/settings.htm | 2 +- wled00/data/settings_sec.htm | 2 +- wled00/data/settings_wifi.htm | 10 +++++----- wled00/data/welcome.htm | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/wled00/data/settings.htm b/wled00/data/settings.htm index 9e22466495..48d4149d87 100644 --- a/wled00/data/settings.htm +++ b/wled00/data/settings.htm @@ -94,7 +94,7 @@ - +
Loading...
diff --git a/wled00/data/settings_sec.htm b/wled00/data/settings_sec.htm index 8ae229f7b2..b6fe559064 100644 --- a/wled00/data/settings_sec.htm +++ b/wled00/data/settings_sec.htm @@ -95,7 +95,7 @@

Security & Update setup

The password should be changed when OTA is enabled.
Disable OTA when not in use, otherwise an attacker can reflash device software!
Settings on this page are only changable if OTA lock is disabled!
- Deny access to WiFi settings if locked:

+ Deny access to Wi-Fi settings if locked:

Factory reset:
All settings and presets will be erased.

⚠ Unencrypted transmission. An attacker on the same network can intercept form data!
diff --git a/wled00/data/settings_wifi.htm b/wled00/data/settings_wifi.htm index 98f1494eaf..43ebbcdc21 100644 --- a/wled00/data/settings_wifi.htm +++ b/wled00/data/settings_wifi.htm @@ -3,7 +3,7 @@ - WiFi Settings + Wi-Fi Settings