sva_samples/machine/
tape.rs1use crate::buffer::Buffer;
4use crate::collapse::Extent;
5
6#[derive(Clone, Debug, PartialEq)]
8pub struct Tape {
9 planes: Vec<Vec<f64>>,
10 base: i64,
11 origin: i64,
12}
13
14impl Tape {
15 pub fn new(width: usize, capacity: usize, origin: i64) -> Tape {
16 Tape {
17 planes: (0..width.max(1))
18 .map(|_| Vec::with_capacity(capacity))
19 .collect(),
20 base: origin,
21 origin,
22 }
23 }
24
25 pub fn width(&self) -> usize {
26 self.planes.len()
27 }
28
29 pub fn base(&self) -> i64 {
30 self.base
31 }
32
33 pub fn origin(&self) -> i64 {
34 self.origin
35 }
36
37 pub fn planes(&self) -> &[Vec<f64>] {
38 &self.planes
39 }
40
41 pub fn capacity(&self) -> usize {
42 self.planes[0].capacity()
43 }
44
45 pub fn end(&self) -> i64 {
46 self.base + self.planes[0].len() as i64
47 }
48
49 pub fn window(&self) -> Window<'_> {
50 self.within(Extent::from(self.origin))
51 }
52
53 pub fn within(&self, support: Extent) -> Window<'_> {
54 Window {
55 planes: &self.planes,
56 base: self.base,
57 support,
58 period: None,
59 offset: 0,
60 }
61 }
62
63 pub fn since(&self, c: usize, from: i64) -> &[f64] {
64 &self.planes[c][(from - self.base) as usize..]
65 }
66
67 pub fn push(&mut self, c: usize, value: f64) {
68 self.planes[c].push(value);
69 }
70
71 pub fn cut(&mut self, end: i64) {
73 let kept = (end - self.base).clamp(0, self.planes[0].len() as i64) as usize;
74 for plane in &mut self.planes {
75 plane.truncate(kept);
76 }
77 }
78
79 pub fn forget_before(&mut self, from: i64) {
80 let gone = (from - self.base).clamp(0, self.planes[0].len() as i64) as usize;
81 if gone == 0 {
82 return;
83 }
84 for plane in &mut self.planes {
85 plane.drain(..gone);
86 }
87 self.base += gone as i64;
88 }
89
90 pub fn into_planes(self) -> Vec<Vec<f64>> {
91 self.planes
92 }
93
94 pub fn into_buffer(self, rate: u32) -> Buffer {
95 let mut out = Buffer::of_planes(rate, self.planes);
96 out.start = self.base;
97 out
98 }
99}
100
101impl From<Buffer> for Tape {
103 fn from(buffer: Buffer) -> Tape {
104 Tape {
105 planes: buffer.planes,
106 base: buffer.start,
107 origin: buffer.start,
108 }
109 }
110}
111
112#[derive(Clone, Copy, Debug)]
115pub struct Window<'a> {
116 planes: &'a [Vec<f64>],
117 base: i64,
118 support: Extent,
119 period: Option<i64>,
120 offset: i64,
122}
123
124impl<'a> Window<'a> {
125 pub fn of(buffer: &'a Buffer, support: Extent) -> Window<'a> {
126 Window {
127 planes: &buffer.planes,
128 base: buffer.start,
129 support,
130 period: None,
131 offset: 0,
132 }
133 }
134
135 pub fn folded(self, period: Option<i64>) -> Window<'a> {
136 Window { period, ..self }
137 }
138
139 pub fn shifted(self, by: i64) -> Window<'a> {
140 Window {
141 offset: self.offset + by,
142 ..self
143 }
144 }
145
146 fn fold(&self, k: i64) -> i64 {
147 let k = k.saturating_add(self.offset);
148 match self.period {
149 Some(n) if self.support.contains(k) => k.rem_euclid(n),
150 _ => k,
151 }
152 }
153
154 pub fn get(&self, c: usize, k: i64) -> Option<f64> {
156 let k = self.fold(k);
157 let plane = &self.planes[c];
158 let held = k
159 .checked_sub(self.base)
160 .and_then(|at| usize::try_from(at).ok())
161 .and_then(|at| plane.get(at));
162 match held {
163 Some(v) => Some(*v),
164 None => (!self.support.contains(k)).then_some(0.0),
165 }
166 }
167
168 pub fn at(&self, c: usize, k: i64) -> f64 {
170 let k = self.fold(k);
171 let plane = &self.planes[c];
172 if let Some(held) = k
173 .checked_sub(self.base)
174 .and_then(|at| usize::try_from(at).ok())
175 .and_then(|at| plane.get(at))
176 {
177 return *held;
178 }
179 if !self.support.contains(k) {
180 return 0.0;
181 }
182 panic!(
183 "sample {k} is not held: this node holds [{}, {}) and is nonzero over [{}, {})",
184 self.base,
185 self.base + plane.len() as i64,
186 self.support.start,
187 self.support.end
188 )
189 }
190}