Skip to content

Commit e593bf7

Browse files
committed
Faster Akemi
1 parent a58a518 commit e593bf7

File tree

1 file changed

+66
-41
lines changed

1 file changed

+66
-41
lines changed

wled00/FX.cpp

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8463,58 +8463,83 @@ uint16_t mode_2DAkemi(void) {
84638463
const uint16_t cols = SEGMENT.virtualWidth();
84648464
const uint16_t rows = SEGMENT.virtualHeight();
84658465

8466-
if (SEGENV.call == 0) {SEGMENT.fill(BLACK);}
8466+
if (SEGENV.call == 0) { SEGMENT.fill(BLACK); }
84678467

8468-
uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF;
8469-
counter = counter >> 8;
8468+
// --- Pre-calculate values before the loops ---
8469+
uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) + 2)) >> 8;
8470+
8471+
// Pre-calculate all color variations ONCE
8472+
const CRGB baseFaceColor = SEGMENT.color_wheel(counter);
8473+
const CRGB baseArmsColor = SEGCOLOR(1) > 0 ? SEGCOLOR(1) : 0xFFE0A0;
8474+
const CRGB eyesMouthColor = SEGCOLOR(2) > 0 ? SEGCOLOR(2) : 0xFFFFFF;
8475+
8476+
// Use faster integer scaling instead of floats
8477+
const uint8_t lightFactorInt = 40; // 0.15 * 255
8478+
const uint8_t normalFactorInt = 102; // 0.4 * 255
8479+
8480+
CRGB lightFaceColor = baseFaceColor; lightFaceColor.nscale8_video(lightFactorInt);
8481+
CRGB normalFaceColor = baseFaceColor; normalFaceColor.nscale8_video(normalFactorInt);
84708482

8471-
const float lightFactor = 0.15f;
8472-
const float normalFactor = 0.4f;
8483+
CRGB lightArmsColor = baseArmsColor; lightArmsColor.nscale8_video(lightFactorInt);
8484+
CRGB normalArmsColor = baseArmsColor; normalArmsColor.nscale8_video(normalFactorInt);
84738485

8486+
// Cache audio data
84748487
um_data_t *um_data = getAudioData();
84758488
uint8_t fftResult[NUM_GEQ_CHANNELS] = {0};
8476-
if (um_data->u_data != nullptr) memcpy(fftResult, um_data->u_data[2], sizeof(fftResult)); // WLEDMM buffer curent values
8477-
float base = fftResult[0]/255.0f;
8478-
8479-
//draw and color Akemi
8480-
for (int y=0; y < rows; y++) for (int x=0; x < cols; x++) {
8481-
CRGB color;
8482-
CRGB soundColor = ORANGE;
8483-
CRGB faceColor = SEGMENT.color_wheel(counter);
8484-
CRGB armsAndLegsColor = SEGCOLOR(1) > 0 ? SEGCOLOR(1) : 0xFFE0A0; //default warmish white 0xABA8FF; //0xFF52e5;//
8485-
uint8_t ak = pgm_read_byte_near(akemi + ((y * 32)/rows) * 32 + (x * 32)/cols); // akemi[(y * 32)/rows][(x * 32)/cols]
8486-
switch (ak) {
8487-
case 3: armsAndLegsColor.r *= lightFactor; armsAndLegsColor.g *= lightFactor; armsAndLegsColor.b *= lightFactor; color = armsAndLegsColor; break; //light arms and legs 0x9B9B9B
8488-
case 2: armsAndLegsColor.r *= normalFactor; armsAndLegsColor.g *= normalFactor; armsAndLegsColor.b *= normalFactor; color = armsAndLegsColor; break; //normal arms and legs 0x888888
8489-
case 1: color = armsAndLegsColor; break; //dark arms and legs 0x686868
8490-
case 6: faceColor.r *= lightFactor; faceColor.g *= lightFactor; faceColor.b *= lightFactor; color=faceColor; break; //light face 0x31AAFF
8491-
case 5: faceColor.r *= normalFactor; faceColor.g *= normalFactor; faceColor.b *= normalFactor; color=faceColor; break; //normal face 0x0094FF
8492-
case 4: color = faceColor; break; //dark face 0x007DC6
8493-
case 7: color = SEGCOLOR(2) > 0 ? SEGCOLOR(2) : 0xFFFFFF; break; //eyes and mouth default white
8494-
case 8: if (base > 0.4) {soundColor.r *= base; soundColor.g *= base; soundColor.b *= base; color=soundColor;} else color = armsAndLegsColor; break;
8495-
default: color = BLACK; break;
8496-
}
8497-
8498-
if (SEGMENT.intensity > 128 && um_data && fftResult[0] > 128) { //dance if base is high
8499-
SEGMENT.setPixelColorXY(x, 0, BLACK);
8500-
SEGMENT.setPixelColorXY(x, y+1, color);
8501-
} else
8502-
SEGMENT.setPixelColorXY(x, y, color);
8489+
if (um_data && um_data->u_data) {
8490+
memcpy(fftResult, um_data->u_data[2], sizeof(fftResult));
8491+
}
8492+
const uint8_t fftBase = fftResult[0];
8493+
const bool isDancing = (SEGMENT.intensity > 128 && fftBase > 128);
8494+
8495+
// --- Main drawing loop ---
8496+
for (int y = 0; y < rows; y++) {
8497+
// Pre-calculate the row offset for the akemi bitmap to avoid division in the x-loop
8498+
uint16_t y_offset = ((y * 32) / rows) * 32;
8499+
8500+
for (int x = 0; x < cols; x++) {
8501+
CRGB color = BLACK; // Default to BLACK
8502+
uint8_t ak = pgm_read_byte_near(akemi + y_offset + (x * 32) / cols);
8503+
8504+
switch (ak) {
8505+
case 1: color = baseArmsColor; break;
8506+
case 2: color = normalArmsColor; break;
8507+
case 3: color = lightArmsColor; break;
8508+
case 4: color = baseFaceColor; break;
8509+
case 5: color = normalFaceColor; break;
8510+
case 6: color = lightFaceColor; break;
8511+
case 7: color = eyesMouthColor; break;
8512+
case 8:
8513+
if (fftBase > 102) { // 0.4 * 255
8514+
color = CRGB(ORANGE).nscale8_video(fftBase);
8515+
} else {
8516+
color = baseArmsColor;
8517+
}
8518+
break;
8519+
}
8520+
8521+
if (isDancing) {
8522+
SEGMENT.setPixelColorXY(x, y + 1, color);
8523+
if (y==0) SEGMENT.setPixelColorXY(x, 0, BLACK); // Clear top row only once
8524+
} else {
8525+
SEGMENT.setPixelColorXY(x, y, color);
8526+
}
8527+
}
85038528
}
85048529

8505-
//add geq left and right
8530+
// --- GEQ drawing loop (largely unchanged, but with cached um_data) ---
85068531
if (um_data) {
8507-
int xMax = cols/8;
8508-
for (int x=0; x < xMax; x++) {
8509-
size_t band = map2(x, 0, max(xMax,4), 0, 15); // map 0..cols/8 to 16 GEQ bands
8532+
int xMax = cols / 8;
8533+
for (int x = 0; x < xMax; x++) {
8534+
size_t band = map2(x, 0, max(xMax, 4), 0, 15);
85108535
uint32_t color = SEGMENT.color_from_palette((band * 35), false, PALETTE_SOLID_WRAP, 0);
85118536
band = constrain(band, 0, 15);
8512-
uint16_t barHeight = map(fftResult[band], 0, 255, 0, 17*rows/32);
8537+
uint16_t barHeight = map(fftResult[band], 0, 255, 0, 17 * rows / 32);
8538+
barHeight = constrain(barHeight, 0, (rows / 2) + 1);
85138539

8514-
barHeight = constrain(barHeight, 0, (rows/2)+1); // map() may overshoot
8515-
for (int y=0; y < barHeight; y++) {
8516-
SEGMENT.setPixelColorXY(x, rows/2-y, color);
8517-
SEGMENT.setPixelColorXY(cols-1-x, rows/2-y, color);
8540+
for (int y = 0; y < barHeight; y++) {
8541+
SEGMENT.setPixelColorXY(x, rows / 2 - y, color);
8542+
SEGMENT.setPixelColorXY(cols - 1 - x, rows / 2 - y, color);
85188543
}
85198544
}
85208545
}

0 commit comments

Comments
 (0)