separate effects

This commit is contained in:
Patrick Moessler 2025-03-22 00:59:47 +01:00
parent e83a3bba36
commit de2b0593ae
5 changed files with 205 additions and 10 deletions

View file

@ -0,0 +1,114 @@
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_time::{Duration, Ticker};
use crate::audio_process::{AudioStats, DspBuffer};
use crate::effects::led_effect::{LedColors, LedData, LedEffect, Rgbv};
use crate::triple_buffer::{Receiver, Sender};
use crate::LED_COUNT;
pub struct LedEffectBassHiBeatStrobe {
bass_color_hue: u32,
bass_color_fill: Rgbv,
hi_beat: u8,
}
impl Default for LedEffectBassHiBeatStrobe {
fn default() -> Self {
Self {
bass_color_hue: 300,
bass_color_fill: Rgbv::black(0),
hi_beat: 0,
}
}
}
impl LedEffect for LedEffectBassHiBeatStrobe {
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_fill = Rgbv::from_hsv(self.bass_color_hue, 100, 100, 1).unwrap();
}
leds.fill(self.bass_color_fill);
// for i in 0..32 {
// leds[i] = self.bass_color_fill.with_o(Rgbv::MAX_O - i as u8);
// leds[LED_COUNT-1-i] = self.bass_color_fill.with_o(Rgbv::MAX_O - i as u8);
// }
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,
);
if stats.floating_max > 10100000
&& (stats.current_powers[1] > 1.35 * stats.avg_powers[1])
&& (stats.current_powers[2] > 1.35 * stats.avg_powers[2])
{
// for led_index in LED_COUNT / 2 - 4..LED_COUNT / 2 + 4 {
// leds[led_index] = Rgbv::white(31);
// }
// let mut tmp = LED_COUNT / 2 - 4..LED_COUNT / 2 + 4;
// while let Some(led_index) = tmp.next() {
// leds[led_index] = Rgbv::white(31);
// }
// for led in leds
// .iter_mut()
// .take(LED_COUNT / 2 + 4)
// .skip(LED_COUNT / 2 - 4)
// {
// *led = Rgbv::white(31);
// }
// for _ in 0..20 {
// let led_index = random_at_most(LED_COUNT as u32 - 1) as usize;
// leds[led_index] = Rgbv::white(31);
// }
self.hi_beat = 6;
}
if self.hi_beat > 0 {
(LED_COUNT / 2 - 8..LED_COUNT / 2 + 8).for_each(|led_index| {
leds[led_index] = if self.hi_beat % 2 == 0 {
Rgbv::black(0)
} else {
Rgbv::white(31)
}
});
self.hi_beat -= 1;
}
self.bass_color_hue = (self.bass_color_hue + 1) % 360;
Duration::from_hz(50)
}
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

@ -0,0 +1,67 @@
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_time::{Duration, Ticker};
use crate::audio_process::{AudioStats, DspBuffer};
use crate::effects::led_effect::{LedColors, LedData, LedEffect, Rgbv};
use crate::triple_buffer::{Receiver, Sender};
pub struct LedEffectBassHueFade {
bass_color_hue: u32,
bass_color_fill: Rgbv,
}
impl Default for LedEffectBassHueFade {
fn default() -> Self {
Self {
bass_color_hue: 300,
bass_color_fill: Rgbv::black(0),
}
}
}
impl LedEffect for LedEffectBassHueFade {
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_fill = Rgbv::from_hsv(self.bass_color_hue, 100, 100, 1).unwrap();
}
leds.fill(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(50)
}
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

@ -8,12 +8,14 @@ use crate::triple_buffer::{Receiver, Sender};
use crate::LED_COUNT; use crate::LED_COUNT;
pub struct LedEffectBassSparks { pub struct LedEffectBassSparks {
bass_color: Rgbv, bass_color_hue: u32,
bass_color_fill: Rgbv,
} }
impl Default for LedEffectBassSparks { impl Default for LedEffectBassSparks {
fn default() -> Self { fn default() -> Self {
Self { Self {
bass_color: Rgbv::black(0), bass_color_hue: 300,
bass_color_fill: Rgbv::black(0),
} }
} }
} }
@ -26,22 +28,31 @@ impl LedEffect for LedEffectBassSparks {
leds: &mut LedColors, leds: &mut LedColors,
) -> Duration { ) -> Duration {
if stats.floating_max > 10100000 && (stats.current_powers[0] > 1.25 * stats.avg_powers[0]) { if stats.floating_max > 10100000 && (stats.current_powers[0] > 1.25 * stats.avg_powers[0]) {
self.bass_color = Rgbv::new(127, 0, 255, 4) self.bass_color_fill = Rgbv::from_hsv(self.bass_color_hue, 100, 100, 1).unwrap();
} }
leds.fill(self.bass_color); leds.fill(self.bass_color_fill);
self.bass_color.decrease(10, 15, 20, 0); 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,
);
if stats.floating_max > 10100000 if stats.floating_max > 10100000
&& (stats.current_powers[1] > 1.35 * stats.avg_powers[1]) && (stats.current_powers[1] > 1.35 * stats.avg_powers[1])
&& (stats.current_powers[2] > 1.35 * stats.avg_powers[2]) && (stats.current_powers[2] > 1.35 * stats.avg_powers[2])
{ {
let alternate_color =
Rgbv::from_hsv((self.bass_color_hue + 180) % 360, 100, 100, 5).unwrap();
for _ in 0..20 { for _ in 0..20 {
let led_index = random_at_most(LED_COUNT as u32 - 1) as usize; let led_index = random_at_most(LED_COUNT as u32 - 1) as usize;
leds[led_index] = Rgbv::white(31); // leds[led_index] = Rgbv::white(31);
leds[led_index] = alternate_color;
} }
} }
self.bass_color_hue = (self.bass_color_hue + 1) % 360;
Duration::from_hz(50) Duration::from_hz(50)
} }

View file

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

View file

@ -19,7 +19,8 @@ use audio_input::mic_input_task;
use audio_process::{process_audio, AudioBuffer, AudioStats, DspBuffer}; use audio_process::{process_audio, AudioBuffer, AudioStats, DspBuffer};
use config::{AUDIO_SAMPLES_PER_BUF, LED_COUNT}; use config::{AUDIO_SAMPLES_PER_BUF, LED_COUNT};
use effects::{ use effects::{
bass_sparks::LedEffectBassSparks, // bass_sparks::LedEffectBassSparks as LedSelectedEffect,
bass_hue_fade::LedEffectBassHueFade as LedSelectedEffect,
led_effect::{LedData, LedEffect}, led_effect::{LedData, LedEffect},
}; };
use led_output::output_leds; use led_output::output_leds;
@ -27,7 +28,7 @@ use triple_buffer::{Receiver, Sender, TripleBuffer};
#[embassy_executor::task] #[embassy_executor::task]
async fn effect_task( async fn effect_task(
mut led_effect: LedEffectBassSparks, mut led_effect: LedSelectedEffect,
input: Receiver<'static, NoopRawMutex, (DspBuffer, AudioStats)>, input: Receiver<'static, NoopRawMutex, (DspBuffer, AudioStats)>,
output: Sender<'static, NoopRawMutex, LedData>, output: Sender<'static, NoopRawMutex, LedData>,
) { ) {
@ -99,7 +100,7 @@ async fn main(spawner: Spawner) {
spawner spawner
.spawn(effect_task( .spawn(effect_task(
LedEffectBassSparks::default(), LedSelectedEffect::default(),
fft_receiver, fft_receiver,
led_sender, led_sender,
)) ))