caw_modules/
sample_playback.rs1use caw_builder_proc_macros::builder;
2use caw_core::{Buf, Sig, SigCtx, SigT};
3
4pub struct SamplePlayback<P>
5where
6 P: SigT<Item = bool>,
7{
8 play_gate: P,
10 sample_buffer: Vec<f32>,
11 index: usize,
12 buf: Vec<f32>,
13}
14
15impl<P> SamplePlayback<P>
16where
17 P: SigT<Item = bool>,
18{
19 fn new(play_gate: P, sample_buffer: Vec<f32>) -> Sig<Self> {
20 Sig(Self {
21 play_gate,
22 sample_buffer,
23 index: 0,
24 buf: Vec::new(),
25 })
26 }
27}
28
29impl<P> SigT for SamplePlayback<P>
30where
31 P: SigT<Item = bool>,
32{
33 type Item = f32;
34
35 fn sample(&mut self, ctx: &SigCtx) -> impl Buf<Self::Item> {
36 if self.play_gate.sample(ctx).iter().next().unwrap() {
40 let next_index =
41 (self.index + ctx.num_samples).min(self.sample_buffer.len());
42 let samples_this_frame =
43 &self.sample_buffer[self.index..next_index];
44 self.index = next_index;
45 self.buf.resize(samples_this_frame.len(), 0.0);
46 self.buf.copy_from_slice(samples_this_frame);
47 } else {
48 self.buf.clear();
50 }
51 self.buf.resize(ctx.num_samples, 0.0);
53 &self.buf
54 }
55}
56
57builder! {
58 #[constructor = "sample_playback"]
59 #[constructor_doc = "Play back samples from a buffer"]
60 #[build_fn = "SamplePlayback::new"]
61 #[build_ty = "Sig<SamplePlayback<P>>"]
62 #[generic_setter_type_name = "X"]
63 pub struct PropsBuilder {
64 #[generic_with_constraint = "SigT<Item = bool>"]
65 #[generic_name = "P"]
66 #[default = true]
67 play_gate: bool,
68 sample_buffer: Vec<f32>,
69 }
70}