diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 0cfa1b03..49e4e513 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -169,8 +169,8 @@ void FFTcode(void * parameter) { //micDataSm = ((micData * 3) + micData)/4; const int halfSamplesFFT = samplesFFT / 2; // samplesFFT divided by 2 - double maxSample1 = 0.0; // max sample from first half of FFT batch - double maxSample2 = 0.0; // max sample from second half of FFT batch + float maxSample1 = 0.0; // max sample from first half of FFT batch + float maxSample2 = 0.0; // max sample from second half of FFT batch for (int i=0; i < samplesFFT; i++) { // set imaginary parts to 0 @@ -179,9 +179,9 @@ void FFTcode(void * parameter) { if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts { if (i <= halfSamplesFFT) { - if (fabs(vReal[i]) > maxSample1) maxSample1 = fabs(vReal[i]); + if (fabsf((float)vReal[i]) > maxSample1) maxSample1 = fabsf((float)vReal[i]); } else { - if (fabs(vReal[i]) > maxSample2) maxSample2 = fabs(vReal[i]); + if (fabsf((float)vReal[i]) > maxSample2) maxSample2 = fabsf((float)vReal[i]); } } } @@ -234,8 +234,8 @@ void FFTcode(void * parameter) { FFT.MajorPeak(&FFT_MajorPeak, &FFT_Magnitude); // let the effects know which freq was most dominant #ifdef MAJORPEAK_SUPPRESS_NOISE - // dirty hack: limit suppressed channel intensities to FFT_Magnitude - for (int k=0; k < 24; k++) if(xtemp[k] > FFT_Magnitude) xtemp[k] = FFT_Magnitude; + // dirty hack: limit suppressed channel intensities to FFT_Magnitude + for (int k=0; k < 24; k++) if(xtemp[k] > FFT_Magnitude) xtemp[k] = FFT_Magnitude; // restore bins vReal[0] = xtemp[0]; vReal[1] = xtemp[1]; @@ -391,13 +391,13 @@ class AudioReactive : public Usermod { // set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer) + const uint16_t delayMs = 10; // I don't want to sample too often and overload WLED uint8_t maxVol = 10; // Reasonable value for constant volume for 'peak detector', as it won't always trigger uint8_t binNum = 0; // Used to select the bin for FFT based beat detection. uint8_t targetAgc = 60; // This is our setPoint at 20% of max for the adjusted output uint8_t myVals[32]; // Used to store a pile of samples because WLED frame rate and WLED sample rate are not synchronized. Frame rate is too low. bool samplePeak = 0; // Boolean flag for peak. Responding routine must reset this flag bool udpSamplePeak = 0; // Boolean flag for peak. Set at the same tiem as samplePeak, but reset by transmitAudioData - uint16_t delayMs = 10; // I don't want to sample too often and overload WLED int16_t micIn = 0; // Current sample starts with negative values and large values, which is why it's 16 bit signed int16_t sample; // Current sample. Must only be updated ONCE!!! float sampleMax = 0.0f; // Max sample over a few seconds. Needed for AGC controler. @@ -416,6 +416,9 @@ class AudioReactive : public Usermod { bool udpSyncConnected = false; + uint8_t lastMode = 0; // last known effect mode + bool agcEffect = false; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _analogmic[]; @@ -871,18 +874,12 @@ class AudioReactive : public Usermod { * Instead, use a timer check as shown here. */ void loop() { - if (millis() - lastTime > 20) { - lastTime = millis(); - } - if (!(audioSyncEnabled & 0x02)) { // Only run the sampling code IF we're not in Receive mode if (soundAgc > AGC_NUM_PRESETS) soundAgc = 0; // make sure that AGC preset is valid (to avoid array bounds violation) getSample(); // Sample the microphone agcAvg(); // Calculated the PI adjusted value as sampleAvg myVals[millis()%32] = sampleAgc; - static uint8_t lastMode = 0; - static bool agcEffect = false; uint8_t knownMode = strip.getMainSegment().mode; if (lastMode != knownMode) { // only execute if mode changes @@ -944,24 +941,37 @@ class AudioReactive : public Usermod { #endif } - if (audioSyncEnabled & 0x01) { // Only run the transmit code IF we're in Transmit mode - DEBUGSR_PRINTLN("Transmitting UDP Mic Packet"); - EVERY_N_MILLIS(20) { + if (millis() - lastTime > 20) { + lastTime = millis(); + + if (audioSyncEnabled & 0x01) { // Only run the transmit code IF we're in Transmit mode + DEBUGSR_PRINTLN("Transmitting UDP Mic Packet"); transmitAudioData(); } } // Begin UDP Microphone Sync - if (audioSyncEnabled & 0x02) { // Only run the audio listener code if we're in Receive mode + if ((audioSyncEnabled & 0x02) && udpSyncConnected) { // Only run the audio listener code if we're in Receive mode if (millis()-lastTime > delayMs) { - if (udpSyncConnected) { - //Serial.println("Checking for UDP Microphone Packet"); - int packetSize = fftUdp.parsePacket(); - if (packetSize) { - // Serial.println("Received UDP Sync Packet"); - uint8_t fftBuff[packetSize]; - fftUdp.read(fftBuff, packetSize); - audioSyncPacket receivedPacket; + //Serial.println("Checking for UDP Microphone Packet"); + int packetSize = fftUdp.parsePacket(); + if (packetSize) { + // Serial.println("Received UDP Sync Packet"); + uint8_t fftBuff[packetSize]; + fftUdp.read(fftBuff, packetSize); + audioSyncPacket receivedPacket; + memcpy(&receivedPacket, fftBuff, packetSize); + for (int i = 0; i < 32; i++ ){ + myVals[i] = receivedPacket.myVals[i]; + } + sampleAgc = receivedPacket.sampleAgc; + rawSampleAgc = receivedPacket.sampleAgc; + sample = receivedPacket.sample; + sampleAvg = receivedPacket.sampleAvg; + // VERIFY THAT THIS IS A COMPATIBLE PACKET + char packetHeader[6]; + memcpy(&receivedPacket, packetHeader, 6); + if (!(isValidUdpSyncVersion(packetHeader))) { memcpy(&receivedPacket, fftBuff, packetSize); for (int i = 0; i < 32; i++ ){ myVals[i] = receivedPacket.myVals[i]; @@ -970,33 +980,20 @@ class AudioReactive : public Usermod { rawSampleAgc = receivedPacket.sampleAgc; sample = receivedPacket.sample; sampleAvg = receivedPacket.sampleAvg; - // VERIFY THAT THIS IS A COMPATIBLE PACKET - char packetHeader[6]; - memcpy(&receivedPacket, packetHeader, 6); - if (!(isValidUdpSyncVersion(packetHeader))) { - memcpy(&receivedPacket, fftBuff, packetSize); - for (int i = 0; i < 32; i++ ){ - myVals[i] = receivedPacket.myVals[i]; - } - sampleAgc = receivedPacket.sampleAgc; - rawSampleAgc = receivedPacket.sampleAgc; - sample = receivedPacket.sample; - sampleAvg = receivedPacket.sampleAvg; - // Only change samplePeak IF it's currently false. - // If it's true already, then the animation still needs to respond. - if (!samplePeak) { - samplePeak = receivedPacket.samplePeak; - } - //These values are only available on the ESP32 - for (int i = 0; i < 16; i++) { - fftResult[i] = receivedPacket.fftResult[i]; - } - - FFT_Magnitude = receivedPacket.FFT_Magnitude; - FFT_MajorPeak = receivedPacket.FFT_MajorPeak; - //Serial.println("Finished parsing UDP Sync Packet"); + // Only change samplePeak IF it's currently false. + // If it's true already, then the animation still needs to respond. + if (!samplePeak) { + samplePeak = receivedPacket.samplePeak; } + //These values are only available on the ESP32 + for (int i = 0; i < 16; i++) { + fftResult[i] = receivedPacket.fftResult[i]; + } + + FFT_Magnitude = receivedPacket.FFT_Magnitude; + FFT_MajorPeak = receivedPacket.FFT_MajorPeak; + //Serial.println("Finished parsing UDP Sync Packet"); } } } diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index 05352613..4b179ee8 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -581,6 +581,10 @@ class FourLineDisplayUsermod : public Usermod { // remove "* " from dynamic palettes for (byte i=2; i<=printedChars; i++) lineBuffer[i-2] = lineBuffer[i]; //include '\0' printedChars -= 2; + } else if ((lineBuffer[0]==' ' && lineBuffer[1]>127)) { + // remove note symbol from effect names + for (byte i=5; i<=printedChars; i++) lineBuffer[i-5] = lineBuffer[i]; //include '\0' + printedChars -= 5; } if (lineHeight == 2) { // use this code for 8 line display char smallBuffer1[MAX_MODE_LINE_SPACE]; diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2fb5e48b..db0339ef 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -6910,15 +6910,14 @@ uint16_t WS2812FX::mode_blurz(void) { // Blurz. By Andrew Tul fade_out(SEGMENT.speed); uint16_t segLoc = random16(SEGLEN); - setPixelColor(segLoc, color_blend(SEGCOLOR(1), color_from_palette(2*fftResult[SEGENV.aux0 % 16]*240/(SEGLEN-1), false, PALETTE_SOLID_WRAP, 0), 2*fftResult[SEGENV.aux0 % 16])); - SEGENV.aux0++; - SEGENV.aux0 = SEGENV.aux0 % 16; + setPixelColor(segLoc, color_blend(SEGCOLOR(1), color_from_palette(fftResult[SEGENV.aux0], false, PALETTE_SOLID_WRAP, 0), 2*fftResult[SEGENV.aux0])); + ++(SEGENV.aux0) %= 16; // make sure it doesn't cross 16 blur(SEGMENT.intensity); return FRAMETIME; } // mode_blurz() -static const char *_data_FX_MODE_BLURZ PROGMEM = " ♫ Blurz@Fade rate,Blur amount;,Color mix;!"; +static const char *_data_FX_MODE_BLURZ PROGMEM = " ♫ Blurz@Fade rate,Blur amount;!,Color mix;!"; ///////////////////////// @@ -6988,7 +6987,7 @@ uint16_t WS2812FX::mode_freqmap(void) { // Map FFT_MajorPeak t fade_out(SEGMENT.speed); - uint16_t locn = (log10f(FFT_MajorPeak) - 1.78f) * (float)SEGLEN/(3.71f-1.78f); // log10 frequency range is from 1.78 to 3.71. Let's scale to SEGLEN. + uint16_t locn = (log10f((float)FFT_MajorPeak) - 1.78f) * (float)SEGLEN/(3.71f-1.78f); // log10 frequency range is from 1.78 to 3.71. Let's scale to SEGLEN. if (locn >=SEGLEN) locn = SEGLEN-1; uint16_t pixCol = (log10f(FFT_MajorPeak) - 1.78f) * 255.0f/(3.71f-1.78f); // Scale log10 of frequency values to the 255 colour index. diff --git a/wled00/FX.h b/wled00/FX.h index 70d27350..d6ff9160 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -757,6 +757,7 @@ class WS2812FX { blur(uint8_t), fill(uint32_t), fade_out(uint8_t r), + fadeToBlackBy(uint8_t fadeBy), setMode(uint8_t segid, uint8_t m), setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setColor(uint8_t slot, uint32_t c), diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index d382942f..fd505013 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -993,6 +993,13 @@ void WS2812FX::fade_out(uint8_t rate) { } } +// fades all pixels to black using nscale8() +void WS2812FX::fadeToBlackBy(uint8_t fadeBy) { + for (uint16_t i = 0; i < SEGLEN; i++) { + setPixelColor(i, col_to_crgb(getPixelColor(i)).nscale8(255-fadeBy)); + } +} + /* * blurs segment content, source: FastLED colorutils.cpp */