generated from lks/eframe_template_android
Add dummy device for testing
This commit is contained in:
parent
edcf10f73c
commit
a8340a3fb9
@ -7,7 +7,7 @@ use realfft::num_complex::Complex32;
|
||||
|
||||
pub enum PlotData {
|
||||
U8(Vec<u8>),
|
||||
//F32(Vec<f32>),
|
||||
F32(Vec<f32>),
|
||||
Bode32(Vec<Complex32>),
|
||||
}
|
||||
#[derive(Clone)]
|
||||
@ -94,6 +94,18 @@ impl DebugPlots {
|
||||
));
|
||||
});
|
||||
}
|
||||
PlotData::F32(v) => {
|
||||
ui.heading("f32 plot");
|
||||
let line = Line::new(PlotPoints::from_ys_f32(&v));
|
||||
let plot = Plot::new(title);
|
||||
plot.show(ui, |plot_ui| {
|
||||
plot_ui.line(line);
|
||||
plot_ui.set_plot_bounds(PlotBounds::from_min_max(
|
||||
[-1.0, -2.0],
|
||||
[(v.len() + 1) as f64, 2.0],
|
||||
));
|
||||
});
|
||||
}
|
||||
PlotData::Bode32(v) => {
|
||||
ui.heading("Bode Plot");
|
||||
let mag_line =
|
||||
|
||||
109
src/backend/dummy.rs
Normal file
109
src/backend/dummy.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use anyhow::Result;
|
||||
use core::panic;
|
||||
use std::{
|
||||
sync::mpsc::{self, RecvTimeoutError, SyncSender, TrySendError},
|
||||
time::{Duration, Instant},
|
||||
usize,
|
||||
};
|
||||
|
||||
use crate::app::debug_plot::{DebugPlotSender, PlotData};
|
||||
|
||||
const LUT_LEN: usize = 4096;
|
||||
|
||||
pub struct DummyDevice {
|
||||
close: SyncSender<()>,
|
||||
}
|
||||
impl DummyDevice {
|
||||
pub fn new(
|
||||
sample_rate: usize,
|
||||
fft_input: SyncSender<Vec<f32>>,
|
||||
_plot_tx: DebugPlotSender,
|
||||
) -> Result<Self> {
|
||||
let sin_lut: Vec<f32> = (0..LUT_LEN)
|
||||
.map(|i| ((i as f32 / LUT_LEN as f32) * std::f32::consts::TAU).sin())
|
||||
.collect();
|
||||
let (close, close_rx) = mpsc::sync_channel(0);
|
||||
let buffer_size: usize = 2048;
|
||||
let loop_interval = Duration::from_secs_f32((1. / sample_rate as f32) * buffer_size as f32);
|
||||
let freq = (sample_rate / 4) as f32;
|
||||
let phase_delta = sin_lut.len() as f32 * (freq / sample_rate as f32);
|
||||
std::thread::spawn(move || {
|
||||
let mut phase = 0_f32;
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
let samples: Vec<f32> = (0..buffer_size)
|
||||
.map(|_i| {
|
||||
phase = (phase + phase_delta) % sin_lut.len() as f32;
|
||||
sin_lut[phase as usize]
|
||||
})
|
||||
.collect();
|
||||
_plot_tx
|
||||
.send("Dummy output", PlotData::F32(samples.clone()))
|
||||
.unwrap();
|
||||
match fft_input.try_send(samples) {
|
||||
Ok(_) => {}
|
||||
Err(TrySendError::Full(_)) => log::warn!("Dummy Backend buffer full."),
|
||||
Err(TrySendError::Disconnected(_)) => {
|
||||
panic!("Dummy device lost connection to frontend!")
|
||||
}
|
||||
}
|
||||
match close_rx.recv_timeout(loop_interval - start.elapsed()) {
|
||||
Ok(_) => break,
|
||||
Err(RecvTimeoutError::Disconnected) => {
|
||||
panic!("Dummy device lost connection to frontend!")
|
||||
}
|
||||
Err(RecvTimeoutError::Timeout) => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Self { close })
|
||||
}
|
||||
}
|
||||
impl crate::backend::Device for DummyDevice {
|
||||
fn show_settings(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label("TODO");
|
||||
}
|
||||
|
||||
fn can_tune(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn tune(&mut self, _freq: usize) -> anyhow::Result<()> {
|
||||
anyhow::bail!("Can't tune this device")
|
||||
}
|
||||
|
||||
fn close(self: Box<Self>) {
|
||||
self.close.send(()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyBackend {
|
||||
sample_rate: usize,
|
||||
}
|
||||
impl DummyBackend {
|
||||
pub fn new() -> Self {
|
||||
Self { sample_rate: 48000 }
|
||||
}
|
||||
}
|
||||
impl super::Backend for DummyBackend {
|
||||
fn display_text(&self) -> &'static str {
|
||||
"Dummy"
|
||||
}
|
||||
|
||||
fn show_device_selection(&mut self, ui: &mut egui::Ui) {
|
||||
ui.label("TODO");
|
||||
}
|
||||
|
||||
fn build_device(
|
||||
&mut self,
|
||||
fft_input: SyncSender<Vec<f32>>,
|
||||
_plot_tx: DebugPlotSender,
|
||||
) -> anyhow::Result<Box<dyn super::Device>> {
|
||||
Ok(Box::new(DummyDevice::new(
|
||||
self.sample_rate,
|
||||
fft_input,
|
||||
_plot_tx,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ use egui::Ui;
|
||||
|
||||
use crate::app::debug_plot::DebugPlotSender;
|
||||
mod audio;
|
||||
mod dummy;
|
||||
pub trait Device {
|
||||
fn show_settings(&mut self, ui: &mut Ui);
|
||||
fn can_tune(&self) -> bool;
|
||||
@ -24,16 +25,23 @@ pub struct Backends(pub Vec<Box<dyn Backend>>);
|
||||
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
|
||||
impl Default for Backends {
|
||||
fn default() -> Self {
|
||||
Backends(vec![Box::new(audio::AudioBackend::new())])
|
||||
Backends(vec![
|
||||
Box::new(audio::AudioBackend::new()),
|
||||
Box::new(dummy::DummyBackend::new()),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
impl Default for Backends {
|
||||
fn default() -> Self {}
|
||||
fn default() -> Self {
|
||||
Backends(vec![Box::new(dummy::DummyBackend::new())])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
impl Default for Backends {
|
||||
fn default() -> Self {}
|
||||
fn default() -> Self {
|
||||
Backends(vec![Box::new(dummy::DummyBackend::new())])
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user