1use std::borrow::Cow;
4use std::ops::Range;
5
6#[derive(Clone, Debug, PartialEq)]
7pub struct Buffer {
8 pub rate: u32,
9 pub start: i64,
11 pub width: usize,
12 pub planes: Vec<Vec<f64>>,
13}
14
15impl Buffer {
16 pub fn silence(rate: u32, width: usize, len: usize) -> Buffer {
17 Buffer {
18 rate,
19 start: 0,
20 width,
21 planes: vec![vec![0.0; len]; width],
22 }
23 }
24
25 pub fn mono(rate: u32, samples: Vec<f64>) -> Buffer {
26 Buffer {
27 rate,
28 start: 0,
29 width: 1,
30 planes: vec![samples],
31 }
32 }
33
34 pub fn of_planes(rate: u32, planes: Vec<Vec<f64>>) -> Buffer {
35 let len = planes.iter().map(Vec::len).min().unwrap_or(0);
36 Buffer {
37 rate,
38 start: 0,
39 width: planes.len(),
40 planes: planes
41 .into_iter()
42 .map(|mut p| {
43 p.truncate(len);
44 p
45 })
46 .collect(),
47 }
48 }
49
50 pub fn plane(&self, c: usize) -> &[f64] {
51 &self.planes[c]
52 }
53
54 pub fn plane_mut(&mut self, c: usize) -> &mut [f64] {
55 &mut self.planes[c]
56 }
57
58 pub fn slices(&self) -> Vec<&[f64]> {
59 self.planes.iter().map(Vec::as_slice).collect()
60 }
61
62 pub fn len(&self) -> usize {
63 self.planes.iter().map(Vec::len).min().unwrap_or(0)
64 }
65
66 pub fn is_empty(&self) -> bool {
67 self.len() == 0
68 }
69
70 pub fn at(&self, c: usize, i: usize) -> f64 {
71 self.planes[c][i]
72 }
73
74 pub fn origin_secs(&self) -> f64 {
75 self.start as f64 / f64::from(self.rate)
76 }
77
78 pub fn extent(&self) -> crate::Extent {
80 crate::Extent::new(self.start, self.start + self.len() as i64)
81 }
82
83 pub fn over(&self, over: crate::Extent, support: crate::Extent) -> Buffer {
85 let window = crate::Window::of(self, support);
86 let planes = (0..self.width)
87 .map(|c| (over.start..over.end).map(|n| window.at(c, n)).collect())
88 .collect();
89 let mut out = Buffer::of_planes(self.rate, planes);
90 out.start = over.start;
91 out
92 }
93
94 pub fn window(&self, c: usize, range: Range<usize>) -> Cow<'_, [f64]> {
95 let plane = self.plane(c);
96 if range.end <= plane.len() {
97 return Cow::Borrowed(&plane[range]);
98 }
99 let mut out = vec![0.0; range.len()];
100 let held = plane.len().clamp(range.start, range.end) - range.start;
101 out[..held].copy_from_slice(&plane[range.start.min(plane.len())..][..held]);
102 Cow::Owned(out)
103 }
104
105 pub fn as_f32(&self, c: usize) -> Vec<f32> {
107 self.plane(c).iter().map(|&x| x as f32).collect()
108 }
109}