@@ -1794,6 +1794,61 @@ uint16_t mode_multi_comet(void) {
17941794}
17951795static const char _data_FX_MODE_MULTI_COMET[] PROGMEM = " Multi Comet" ;
17961796
1797+ // audioreactive multi-comet by @softhack007
1798+ uint16_t mode_multi_comet_ar (void ) {
1799+ constexpr unsigned MAX_COMETS = 16 ; // was 8
1800+ uint32_t cycleTime = max (1 , int ((255 - SEGMENT.speed )/4 ));
1801+ uint32_t it = strip.now / cycleTime;
1802+ if (SEGENV.step == it) return FRAMETIME; // too early
1803+
1804+ if (!SEGENV.allocateData (sizeof (uint16_t ) * MAX_COMETS)) return mode_static (); // allocation failed
1805+ uint16_t * comets = reinterpret_cast <uint16_t *>(SEGENV.data );
1806+ if (SEGENV.call == 0 ) { // do some initializations
1807+ SEGMENT.setUpLeds (); SEGMENT.fill (BLACK);
1808+ for (uint8_t i=0 ; i < MAX_COMETS; i++) comets[i] = SEGLEN; // WLEDMM make sure comments are started individually
1809+ SEGENV.aux0 = 0 ;
1810+ }
1811+ SEGMENT.fade_out (254 - SEGMENT.intensity /2 );
1812+
1813+ um_data_t *um_data;
1814+ if (!usermods.getUMData (&um_data, USERMOD_ID_AUDIOREACTIVE)) um_data = simulateSound (SEGMENT.soundSim );
1815+ float volumeSmth = *(float *) um_data->u_data [0 ];
1816+ int16_t volumeRaw = *(int16_t *) um_data->u_data [1 ];
1817+ uint8_t samplePeak = *(uint8_t *) um_data->u_data [3 ];
1818+
1819+ uint16_t armed = SEGENV.aux0 ; // allows to delay comet launch
1820+
1821+ #if defined(ARDUINO_ARCH_ESP32)
1822+ random16_add_entropy (esp_random () & 0xFFFF ); // improve randomness (esp32)
1823+ #endif
1824+ bool shotOne = false ; // avoids starting several coments at the same time (invisible due to overlap)
1825+ for (unsigned i=0 ; i < MAX_COMETS; i++) {
1826+ if (comets[i] < SEGLEN) {
1827+ // draw comet
1828+ uint16_t index = comets[i];
1829+ if (SEGCOLOR (2 ) != 0 )
1830+ SEGMENT.setPixelColor (index, i % 2 ? SEGMENT.color_from_palette (index, true , PALETTE_SOLID_WRAP, 0 ) : SEGCOLOR (2 ));
1831+ else
1832+ SEGMENT.setPixelColor (index, SEGMENT.color_from_palette (index, true , PALETTE_SOLID_WRAP, 0 ));
1833+ comets[i]++; // move
1834+ } else {
1835+ // randomly launch a new comet
1836+ if (random16 (min (uint16_t (256 ), SEGLEN)) < 3 ) armed++; // new comet loaded and ready
1837+ if (armed > 2 ) armed = 2 ; // max three armed at once (avoid overlap)
1838+ // delay comet "launch" during silence, and wait until next beat
1839+ if ( (armed > 0 ) && (shotOne == false )
1840+ && (volumeSmth > 1 .0f ) && ((samplePeak > 0 ) || (volumeRaw > 104 )) ) { // delayed lauch - wait until peak, don't launch in silence
1841+ comets[i] = 0 ; // start a new comet!
1842+ armed--; // un-arm one
1843+ shotOne = true ;
1844+ }
1845+ }
1846+ }
1847+ SEGENV.aux0 = armed;
1848+ SEGENV.step = it;
1849+ return FRAMETIME;
1850+ }
1851+ 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
17971852
17981853/*
17991854 * Running random pixels ("Stream 2")
@@ -9017,6 +9072,7 @@ void WS2812FX::setupEffectData() {
90179072 addEffect (FX_MODE_LIGHTNING, &mode_lightning, _data_FX_MODE_LIGHTNING);
90189073 addEffect (FX_MODE_ICU, &mode_icu, _data_FX_MODE_ICU);
90199074 addEffect (FX_MODE_MULTI_COMET, &mode_multi_comet, _data_FX_MODE_MULTI_COMET);
9075+ addEffect (FX_MODE_MULTI_COMET_AR, &mode_multi_comet_ar, _data_FX_MODE_MULTI_COMET_AR);
90209076 addEffect (FX_MODE_DUAL_LARSON_SCANNER, &mode_dual_larson_scanner, _data_FX_MODE_DUAL_LARSON_SCANNER);
90219077 addEffect (FX_MODE_RANDOM_CHASE, &mode_random_chase, _data_FX_MODE_RANDOM_CHASE);
90229078 addEffect (FX_MODE_OSCILLATE, &mode_oscillate, _data_FX_MODE_OSCILLATE);
0 commit comments