add runner effect

This commit is contained in:
Patrick Moessler 2025-03-24 03:29:20 +01:00
parent ebfdeabe2c
commit 812a389ea2
4 changed files with 107 additions and 2 deletions

View file

@ -0,0 +1,86 @@
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_time::{Duration, Ticker};
use crate::audio_process::{AudioStats, DspBuffer};
use crate::config::LED_COUNT;
use crate::effects::led_effect::{LedColors, LedData, LedEffect, Rgbv};
use crate::triple_buffer::{Receiver, Sender};
pub struct LedEffectBassHueRunner {
bass_color_hue: u32,
bass_color_fill: Rgbv,
bass_color_invert: bool,
}
impl Default for LedEffectBassHueRunner {
fn default() -> Self {
Self {
bass_color_hue: 300,
bass_color_fill: Rgbv::black(0),
bass_color_invert: false,
}
}
}
impl LedEffect for LedEffectBassHueRunner {
fn render(
&mut self,
_: bool,
_: &DspBuffer,
stats: &AudioStats,
leds: &mut LedColors,
) -> Duration {
if stats.floating_max > 10100000 && (stats.current_powers[0] > 1.25 * stats.avg_powers[0]) {
self.bass_color_invert = !self.bass_color_invert;
self.bass_color_fill = Rgbv::from_hsv(
if self.bass_color_invert {
(self.bass_color_hue + 180) % 360
} else {
self.bass_color_hue
},
100,
100,
1,
)
.unwrap();
}
for i in 0..LED_COUNT / 2 - 1 {
leds[LED_COUNT / 2 + i] = leds[LED_COUNT / 2 + i + 1];
leds[LED_COUNT / 2 - 1 - i] = leds[LED_COUNT / 2 - 1 - i - 1];
}
leds[0] = self.bass_color_fill;
leds[LED_COUNT - 1] = self.bass_color_fill;
self.bass_color_fill.decrease(
std::cmp::max(self.bass_color_fill.r / 4, 1),
std::cmp::max(self.bass_color_fill.g / 4, 1),
std::cmp::max(self.bass_color_fill.b / 4, 1),
0,
);
self.bass_color_hue = (self.bass_color_hue + 1) % 360;
Duration::from_hz(100)
}
async fn process_led_effect(
&mut self,
mut input: Receiver<'static, NoopRawMutex, (DspBuffer, AudioStats)>,
mut output: Sender<'static, NoopRawMutex, LedData>,
) {
let mut set_interval = Duration::from_hz(100);
let mut ticker = Ticker::every(set_interval);
loop {
let ((fft, stats), was_new) = input.receive_cached().await;
let leds = output.send().await;
let interval = self.render(was_new, fft, stats, &mut leds.leds);
output.send_done();
if set_interval != interval {
set_interval = interval;
ticker = Ticker::every(set_interval);
}
ticker.next().await;
}
}
}

View file

@ -101,6 +101,23 @@ impl Rgbv {
*self
}
#[inline(always)]
pub fn divide(&mut self, r: u8, g: u8, b: u8, o: u8) -> Self {
self.r /= r;
self.g /= g;
self.b /= b;
self.set_o(self.o() / o);
*self
}
#[inline(always)]
pub fn divide_rgb(&mut self, r: u8, g: u8, b: u8) -> Self {
self.r /= r;
self.g /= g;
self.b /= b;
*self
}
/// Converts hue, saturation, value to RGB
/// // copied from rmt_neopixel example
pub fn from_hsv(h: u32, s: u32, v: u32, o: u8) -> Result<Self> {

View file

@ -1,4 +1,5 @@
pub mod led_effect;
pub mod bass_sparks;
pub mod bass_hi_beat_strobe;
pub mod bass_hue_fade;
pub mod bass_hue_fade;
pub mod bass_hue_runner;

View file

@ -20,7 +20,8 @@ use audio_process::{process_audio, AudioBuffer, AudioStats, DspBuffer};
use config::{AUDIO_SAMPLES_PER_BUF, LED_COUNT};
use effects::{
// bass_sparks::LedEffectBassSparks as LedSelectedEffect,
bass_hue_fade::LedEffectBassHueFade as LedSelectedEffect,
// bass_hue_fade::LedEffectBassHueFade as LedSelectedEffect,
bass_hue_runner::LedEffectBassHueRunner as LedSelectedEffect,
led_effect::{LedData, LedEffect},
};
use led_output::output_leds;