diff --git a/platformio.ini b/platformio.ini index a9ab79f302..507c391caf 100644 --- a/platformio.ini +++ b/platformio.ini @@ -933,6 +933,10 @@ lib_deps_S = 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#f070fefc42febe2de3a2ab5d6d39e78bbc539702 +audiolux_lib_deps = + https://github.com/netmindz/Audiolux.git#5de778a1011d5458d644e7590a28674b77240b8e ;; WLED-build-errors + https://github.com/netmindz/Arduino-logging-library.git#9d739e98159677fb8a4d1e03087c29ce7b2efd60 + build_flags_M = -D USERMOD_ARTIFX ; WLEDMM usermod - temporarily moved into "_M", due to problems in "_S" when compiling with -O2 -D WLED_MAX_USERMODS=25 ; default only 4-6, also for _XL configs takes 25 pointers in memory @@ -944,6 +948,7 @@ build_flags_M = -D USERMOD_ROTARY_ENCODER_UI -D USERMOD_AUTO_SAVE ${common_mm.animartrix_build_flags} + -D USERMOD_AUDIOLUX ;WLEDMM: only setting WLED_DEBUG_HOST is enough, ip and port can be defined in sync settings as well -D WLED_DEBUG_HOST='"192.168.x.x"' ;; to send debug messages over network to host 192.168.x.y - FQDN is also possible -D WLED_DEBUG_PORT=1768 ;; port for network debugging. default = 7868 @@ -953,12 +958,14 @@ lib_deps_M = OneWire@~2.3.5 ; used for USERMOD_FOUR_LINE_DISPLAY and USERMOD_DALLASTEMPERATURE olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY ${common_mm.animartrix_lib_deps} + ${common_mm.audiolux_lib_deps} lib_deps_V4_M = ;https://github.com/blazoncek/OneWire.git ; includes bugfixes for inconsistent readings paulstoffregen/OneWire@ ^2.3.7 ; used for USERMOD_DALLASTEMPERATURE -> need newer release with bugfixes for -S3; still requires TEMPERATURE_PIN < 46 olikraus/U8g2@ ^2.34.5 ; used for USERMOD_FOUR_LINE_DISPLAY -> need newer version with bugfixes for arduino-esp32 v2.0.4 (Wire inititialization) ${common_mm.animartrix_lib_deps} + ${common_mm.audiolux_lib_deps} build_flags_XL = -D USERMOD_WEATHER ; WLEDMM usermod @@ -1023,6 +1030,7 @@ lib_deps = ${esp32_4MB_S_base.lib_deps} ${common_mm.lib_deps_M} [esp32_4MB_XL_base] extends = esp32_4MB_M_base build_flags = ${esp32_4MB_M_base.build_flags} ${common_mm.build_flags_XL} +build_unflags = -D USERMOD_AUDIOLUX ; Tips us over the edge lib_deps = ${esp32_4MB_M_base.lib_deps} ${common_mm.lib_deps_XL} ; board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv diff --git a/usermods/usermod_v2_audiolux/usermod_v2_audiolux.h b/usermods/usermod_v2_audiolux/usermod_v2_audiolux.h new file mode 100644 index 0000000000..4a490ee00f --- /dev/null +++ b/usermods/usermod_v2_audiolux/usermod_v2_audiolux.h @@ -0,0 +1,198 @@ +#pragma once + +#include "wled.h" + +#include "pixl.h" +#include "Logging.h" + +#define LOGLEVEL LOG_LEVEL_INFOS + +using namespace pixl; + +//======================================================================================================================== + +class WLEDAudioInput : public Input { + public: + WLEDAudioInput(){} + void update() { + if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { + // add support for no audio + um_data = simulateSound(SEGMENT.soundSim); + } + } + float getInput(int index = 0) { + if (index == 0) { + float volume = *(float*)um_data->u_data[0]; + float value = (float) map((volume * 4), 0, 1020, 0, 1000) / 1000.0f; + if(value > 0) Serial.println(value); + return value; + } else if (index == 1) { + uint8_t *fftResult = (uint8_t*) um_data->u_data[2]; + return 0.0; // TODO map 0-255 to expected range - https://github.com/netmindz/Audiolux/blob/81056ab8f59cb4a801b541ba57a62786b4b93a73/msgeq7.cpp#L39 + } else { + return 0.0; + } + } + private: + um_data_t *um_data; +}; + +class AudioLux { + + int NUM_LEDS; + LEDStrip ledstrip = LEDStrip(NUM_LEDS); + LEDs leds = LEDs(&ledstrip, 0, 0, false); + Input* input; + Visualization* viz; + Animation* anim; + Looper* looper = Looper::instance(); + + public: + + AudioLux() {} + + void initEffect() { + + NUM_LEDS = SEGMENT.virtualWidth() * SEGMENT.virtualHeight(); + + ledstrip = LEDStrip(NUM_LEDS); + leds = LEDs(&ledstrip, 0, NUM_LEDS, false); + + // Add all the components to the looper so they update every frame + + looper->clearAll(); + delete viz; + delete anim; + delete input; + looper->setUpdatesPerSecond(40); + } + + void setVizTwinkleVisualization() { + initEffect(); + + input = new NullInput(); + looper->addInput(input); + + viz = new TwinkleVisualization(input, NUM_LEDS); + looper->addVisualization(viz); + } + + void setVizHueVisualization() { + initEffect(); + + input = new RandomInput(); + looper->addInput(input); + + viz = new HueVisualization(input, NUM_LEDS); + anim = new PassThroughAnimation(viz, leds); + looper->addVisualization(viz); + looper->addAnimation(anim); + } + + void setFireVisualization() { + initEffect(); + + input = new RandomInput(); + looper->addInput(input); + + viz = new FireVisualization(input, NUM_LEDS); + looper->addVisualization(viz); + } + + void setAudioFireVisualization() { + initEffect(); + + input = new WLEDAudioInput(); + looper->addInput(input); + + viz = new FireVisualization(input, NUM_LEDS); + looper->addVisualization(viz); + } + + void loop() { + Looper::instance()->loop(); + for(int i = 0; i < NUM_LEDS; i++) { + SEGMENT.setPixelColor(i, ledstrip.leds[i]); // TODO: UGLY copy for now + } + } +}; + +//======================================================================================================================== + +AudioLux audioLux; + +static const char _data_FX_mode_TwinkleVisualization[] PROGMEM = "AudioLux - Twinkle"; +static const char _data_FX_mode_HueVisualization[] PROGMEM = "AudioLux - Hue"; +static const char _data_FX_mode_FireVisualization[] PROGMEM = "AudioLux - Fire"; +static const char _data_FX_mode_AudioFireVisualization[] PROGMEM = "AudioLux - AudioFire"; + + +uint16_t mode_TwinkleVisualization() { + if (SEGENV.call == 0) { + audioLux.setVizTwinkleVisualization(); + } + audioLux.loop(); + return FRAMETIME; +} + +uint16_t mode_HueVisualization() { + if (SEGENV.call == 0) { + audioLux.setVizHueVisualization(); + } + audioLux.loop(); + return FRAMETIME; +} + +uint16_t mode_FireVisualization() { + if (SEGENV.call == 0) { + audioLux.setFireVisualization(); + } + audioLux.loop(); + return FRAMETIME; +} + +uint16_t mode_AudioFireVisualization() { + if (SEGENV.call == 0) { + audioLux.setAudioFireVisualization(); + } + audioLux.loop(); + return FRAMETIME; +} + + +class AudioLuxUsermod : public Usermod { + + public: + + AudioLuxUsermod(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM + + void setup() { + + if(!enabled) return; + + strip.addEffect(255, &mode_TwinkleVisualization, _data_FX_mode_TwinkleVisualization); + strip.addEffect(255, &mode_HueVisualization, _data_FX_mode_HueVisualization); + strip.addEffect(255, &mode_FireVisualization, _data_FX_mode_FireVisualization); + strip.addEffect(255, &mode_AudioFireVisualization, _data_FX_mode_AudioFireVisualization); + + initDone = true; + } + + void loop() { + if (!enabled || strip.isUpdating()) return; + + // do your magic here + if (millis() - lastTime > 1000) { + //USER_PRINTLN("I'm alive!"); + lastTime = millis(); + } + + + } + + uint16_t getId() + { + return USERMOD_ID_AUDIOLUX; + } + +}; \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index f78f19c62e..ee7da6560e 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -139,6 +139,7 @@ #define USERMOD_ID_WEATHER 91 //Usermod "usermod_v2_weather.h" #define USERMOD_ID_GAMES 92 //Usermod "usermod_v2_games.h" #define USERMOD_ID_ANIMARTRIX 93 //Usermod "usermod_v2_animartrix.h" +#define USERMOD_ID_AUDIOLUX 94 //Usermod "usermod_v2_audiolux.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 1ccf1d0301..728fa37619 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -212,6 +212,9 @@ #ifdef USERMOD_ANIMARTRIX #include "../usermods/usermod_v2_animartrix/usermod_v2_animartrix.h" #endif +#ifdef USERMOD_AUDIOLUX +#include "../usermods/usermod_v2_audiolux/usermod_v2_audiolux.h" +#endif void registerUsermods() { @@ -405,4 +408,8 @@ void registerUsermods() #ifdef USERMOD_ANIMARTRIX usermods.add(new AnimartrixUsermod("Animartrix", false)); #endif +#ifdef USERMOD_AUDIOLUX + usermods.add(new AudioLuxUsermod("AudioLux", true)); +#endif + }