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
}