From 812a389ea22e45e9f70aecd9896a10b76a2a791a Mon Sep 17 00:00:00 2001 From: Patrick Moessler <pub@asaril.de> Date: Mon, 24 Mar 2025 03:29:20 +0100 Subject: [PATCH] add runner effect --- src/effects/bass_hue_runner.rs | 86 ++++++++++++++++++++++++++++++++++ src/effects/led_effect.rs | 17 +++++++ src/effects/mod.rs | 3 +- src/main.rs | 3 +- 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/effects/bass_hue_runner.rs diff --git a/src/effects/bass_hue_runner.rs b/src/effects/bass_hue_runner.rs new file mode 100644 index 0000000..3b81e28 --- /dev/null +++ b/src/effects/bass_hue_runner.rs @@ -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; + } + } +} diff --git a/src/effects/led_effect.rs b/src/effects/led_effect.rs index 8674aca..033c4a2 100644 --- a/src/effects/led_effect.rs +++ b/src/effects/led_effect.rs @@ -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> { diff --git a/src/effects/mod.rs b/src/effects/mod.rs index 6511360..d15669c 100644 --- a/src/effects/mod.rs +++ b/src/effects/mod.rs @@ -1,4 +1,5 @@ pub mod led_effect; pub mod bass_sparks; pub mod bass_hi_beat_strobe; -pub mod bass_hue_fade; \ No newline at end of file +pub mod bass_hue_fade; +pub mod bass_hue_runner; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4e778f1..fd83eab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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;