1use std::collections::HashMap;
2use std::error::Error;
3
4use super::misc::*;
5use super::error::*;
6use super::binned::BinnedWaveformRenderer;
7
8pub struct MultiWaveformRenderer<T: Sample> {
14 pub binned: HashMap<usize, BinnedWaveformRenderer<T>>,
15 sample_rate: f64,
16}
17
18impl<T: Sample> MultiWaveformRenderer<T> {
19 pub fn new(samples: &SampleSequence<T>, bin_sizes: &[usize], config: WaveformConfig) -> Result<Self, Box<Error>> {
31 let mut r = MultiWaveformRenderer {
32 binned: HashMap::new(),
33 sample_rate: samples.sample_rate,
34 };
35 let mut bss = Vec::with_capacity(bin_sizes.len());
36 for bs in bin_sizes {
37 bss.push(*bs);
38 }
39 bss.sort();
40
41 for bs in bss.iter() {
45 r.binned
46 .insert(*bs, try!(BinnedWaveformRenderer::new(samples, *bs, config)));
47 }
48
49 Ok(r)
50 }
51
52 fn get_optimal_bin_size(&self, samples_per_pixel: f64) -> Option<usize> {
53
54 let mut bin_sizes: Vec<usize> = self.binned.keys().map(|x| *x).collect();
55 if bin_sizes.len() == 0 {
56 return None;
57 }
58
59 bin_sizes.sort();
60 let mut bin_size = bin_sizes[0];
61 for bs in bin_sizes.iter() {
62 if (*bs as f64) <= samples_per_pixel {
63 bin_size = *bs;
64 } else {
65 break;
66 }
67 }
68
69 Some(bin_size)
70 }
71
72 pub fn render_vec(&mut self, range: TimeRange, shape: (usize, usize)) -> Option<Vec<u8>> {
81 let (w, h) = shape;
82 if w == 0 || h == 0 {
83 return None;
84 }
85
86 let (begin, end) = range.to_sample_tuple(self.sample_rate);
87
88 let samples_per_pixel = ((end - begin) as f64) / (w as f64);
89
90 if let Some(bin_size) = self.get_optimal_bin_size(samples_per_pixel) {
91 return self.binned
92 .get_mut(&bin_size)
93 .unwrap()
94 .render_vec(range, shape);
95 }else{
96 return None;
97 }
98 }
99
100
101 pub fn render_write(&mut self, range: TimeRange, offsets: (usize, usize), shape: (usize, usize), img: &mut [u8], full_shape: (usize, usize)) -> Result<(), Box<Error>> {
124 let (begin, end) = range.to_sample_tuple(self.sample_rate);
125
126 let samples_per_pixel = ((end - begin) as f64) / (shape.0 as f64);
127
128 if let Some(bin_size) = self.get_optimal_bin_size(samples_per_pixel) {
129 return self.binned
130 .get_mut(&bin_size)
131 .unwrap()
132 .render_write(range, offsets, shape, img, full_shape);
133 }else{
134 return Err(Box::new(InvalidSizeError{var_name: "bin sizes".to_string()}));
135 }
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::MultiWaveformRenderer;
142 use misc::*;
143
144 #[test]
145 fn multi() {
146 let data = vec![0f64; 50000];
147 let sample_rate = 44100f64;
148 let ss = SampleSequence {
149 data: &data[..],
150 sample_rate,
151 };
152 let foreground = Color::Vector4(255, 0, 0, 255);
153 let background = Color::Vector4(0, 0, 0, 0);
154 let config = WaveformConfig::new(-100f64, 100f64, foreground, background).unwrap();
155 let bss = vec![10, 50, 100];
156 let mut mwr = MultiWaveformRenderer::new(&ss, &bss, config).unwrap();
157
158 for bs in bss.iter() {
159 assert_eq!(mwr.binned.get(bs).unwrap().get_bin_size(), *bs);
160 assert_eq!(mwr.binned.get(bs).unwrap().get_sample_rate(), sample_rate);
161 }
162
163 mwr.render_vec(TimeRange::Seconds(0f64, 1f64), (1000, 100))
164 .unwrap();
165 }
166
167 #[test]
168 fn markers() {
169 let c = Color::Scalar(0);
170 let config = WaveformConfig::new(-1f64, 1f64, c, c).unwrap();
171 let wfr = MultiWaveformRenderer::new(
172 &SampleSequence {
173 data: &vec![0f64; 100],
174 sample_rate: 44100f64,
175 },
176 &vec![10usize], config
177 ).unwrap();
178 let _test: &(Sync+Send) = 𝔴
179 }
180}