move plotter and refactor channel handling

This commit is contained in:
Hailey Somerville
2020-04-08 19:50:20 +10:00
parent 23ed463962
commit 2ff7f3837a
6 changed files with 32 additions and 35 deletions
+1
View File
@@ -4,5 +4,6 @@ pub mod fm_sine;
pub mod icecast_input;
pub mod mixer_4ch;
pub mod output_device;
pub mod plotter;
pub mod sine_generator;
pub mod trigger;
@@ -1,4 +1,3 @@
use itertools::{Itertools, Either};
use plotters::prelude::*;
use web_sys::HtmlCanvasElement;
use yew::{html, Component, ComponentLink, Html, ShouldRender, Properties, NodeRef};
@@ -13,10 +12,13 @@ pub struct PlotterProps {
pub width: usize,
}
struct Plot {
canvas: NodeRef,
}
pub struct Plotter {
props: PlotterProps,
canvas_1: NodeRef,
canvas_2: NodeRef,
plots: Vec<Plot>,
}
impl Component for Plotter {
@@ -26,8 +28,10 @@ impl Component for Plotter {
fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
Plotter {
props,
canvas_1: NodeRef::default(),
canvas_2: NodeRef::default(),
plots: vec![
Plot { canvas: NodeRef::default() },
Plot { canvas: NodeRef::default() },
],
}
}
@@ -42,21 +46,11 @@ impl Component for Plotter {
fn change(&mut self, props: Self::Properties) -> ShouldRender {
self.props = props;
if let Some(input) = &self.props.indication.inputs[0] {
let (channel_1, channel_2): (Vec<f32>, Vec<f32>) = input.into_iter().enumerate().partition_map(|(i, sample)| {
if i % 2 == 0 {
Either::Left(sample)
} else {
Either::Right(sample)
for (index, input) in self.props.indication.inputs.iter().enumerate() {
if let Some(plot) = self.plots.get(index) {
if let Some(canvas) = plot.canvas.cast::<HtmlCanvasElement>() {
render_plot(canvas, input);
}
});
if let Some(canvas) = self.canvas_1.cast::<HtmlCanvasElement>() {
plot(canvas, &channel_1);
}
if let Some(canvas) = self.canvas_2.cast::<HtmlCanvasElement>() {
plot(canvas, &channel_2);
}
}
@@ -65,15 +59,14 @@ impl Component for Plotter {
fn view(&self) -> Html {
html! {
<>
<canvas ref={self.canvas_1.clone()} width={self.props.width} height={self.props.height}></canvas>
<canvas ref={self.canvas_2.clone()} width={self.props.width} height={self.props.height}></canvas>
</>
{ for self.plots.iter().map(|plot| {
html! { <canvas ref={plot.canvas.clone()} width={self.props.width} height={self.props.height} /> }
})}
}
}
}
fn plot(canvas: HtmlCanvasElement, channel: &[f32]) {
fn render_plot(canvas: HtmlCanvasElement, channel: &[f32]) {
let backend = CanvasBackend::with_canvas_object(canvas).unwrap();
let root = backend.into_drawing_area();
root.fill(&WHITE).unwrap();
+1 -4
View File
@@ -1,7 +1,3 @@
mod components;
use components::plotter::Plotter;
use std::cell::RefCell;
use std::collections::{BTreeMap, HashSet};
use std::mem;
@@ -19,6 +15,7 @@ use crate::module::fm_sine::FmSine;
use crate::module::icecast_input::IcecastInput;
use crate::module::mixer_4ch::Mixer4ch;
use crate::module::output_device::OutputDevice;
use crate::module::plotter::Plotter;
use crate::module::sine_generator::SineGenerator;
use crate::module::trigger::Trigger;
use crate::util::{callback_ex, stop_propagation, prevent_default};
-1
View File
@@ -1 +0,0 @@
pub mod plotter;
+1 -1
View File
@@ -161,7 +161,7 @@ pub enum OutputDeviceWarning {
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PlotterIndication {
pub inputs: Vec<Option<Vec<Sample>>>,
pub inputs: Vec<Vec<Sample>>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
+12 -5
View File
@@ -11,7 +11,7 @@ impl ModuleT for Plotter {
type Indication = PlotterIndication;
fn create(_: Self::Params) -> (Self, Self::Indication) {
(Plotter, PlotterIndication { inputs: vec![None] })
(Plotter, PlotterIndication { inputs: vec![vec![], vec![]] })
}
fn params(&self) -> Self::Params {
@@ -24,11 +24,18 @@ impl ModuleT for Plotter {
fn run_tick(&mut self, t: u64, inputs: &[Option<&[Sample]>], _outputs: &mut [&mut [Sample]]) -> Option<Self::Indication> {
if t % 10 == 1 {
let inputs: Vec<_> = inputs.iter().map(|input| {
input.map(|x|x.to_vec())
}).collect();
inputs[0].map(|input| {
let samples = input.len() / 2;
let mut left = Vec::with_capacity(samples);
let mut right = Vec::with_capacity(samples);
Some(PlotterIndication { inputs })
for i in 0..samples {
left.push(input[i * 2]);
right.push(input[i * 2 + 1]);
}
PlotterIndication { inputs: vec![left, right] }
})
} else {
None
}