gled-core 2.31.1

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
pub(crate) mod device_id;
mod device_label;
pub(crate) mod fft;
mod input_scan;
pub(crate) mod sound_data;
pub(crate) use gled_model::sound::trigger as sound_trigger;

pub(crate) use device_label::{audio_device_label, audio_device_labels};
pub(crate) use gled_model::sound::{
    trigger_params as sound_trigger_params, trigger_ref as sound_trigger_ref,
};
pub(crate) use input_scan::scan_audio_inputs;

use crate::audio::{
    fft::{FFTAudioSource, FREQ_BINS},
    sound_data::SoundData,
};
use cpal::DeviceId;
use kanal::Sender;

#[derive(Debug, Default)]
pub(crate) struct AudioPool {
    pub(crate) selected_device: Option<DeviceId>,
    pub(crate) audio_source: Option<FFTAudioSource>,
}

impl AudioPool {
    pub(crate) fn restart_fft(&mut self) {
        self.audio_source = self.selected_device.clone().map(|device_id| {
            tracing::info!("Restarting FFT with device: {:?}", device_id);
            let fft_tx = start_process_fft_data_thread();
            FFTAudioSource::start(device_id, fft_tx)
        });
        let mut data = SoundData::default();
        data.reset();
        data.save();
    }
}

pub(crate) fn start_process_fft_data_thread() -> Sender<[f32; FREQ_BINS]> {
    let (tx, rx) = kanal::bounded(0);

    std::thread::Builder::new()
        .name("gled:audio:trigger".to_string())
        .spawn(move || {
            #[cfg(feature = "profiling")]
            profiling::register_thread!("SoundTriggerThread");
            tracing::info!("Sound trigger thread started");
            let mut sound_data = SoundData::default();

            while let Ok(samples) = rx.recv() {
                sound_data.update();
                sound_data.tick(samples);
                sound_data.save();
            }
        })
        .expect("Could not spawn sound trigger thread");

    tx
}