rawdio/effects/sampler/
sampler_node.rs

1use super::{sampler_event::*, sampler_processor::*};
2use crate::{commands::Id, effects::Channel, graph::DspParameters, prelude::*};
3
4/// A node that can play or loop a sample
5pub struct Sampler {
6    /// The node to connect to the audio graph
7    pub node: GraphNode,
8    event_transmitter: EventTransmitter,
9}
10
11static EVENT_CHANNEL_CAPACITY: usize = 32;
12
13impl Sampler {
14    /// Create a Sampler with a specified capacity of events in the event queue
15    pub fn new_with_event_capacity(
16        context: &dyn Context,
17        sample: OwnedAudioBuffer,
18        capacity: usize,
19    ) -> Self {
20        let id = Id::generate();
21
22        let (event_transmitter, event_receiver) = Channel::bounded(capacity);
23
24        let input_count = 0;
25        let output_count = sample.channel_count();
26        let sample_rate = sample.sample_rate();
27        let processor = Box::new(SamplerDspProcess::new(sample_rate, sample, event_receiver));
28
29        Self {
30            node: GraphNode::new(
31                id,
32                context,
33                input_count,
34                output_count,
35                processor,
36                DspParameters::empty(),
37            ),
38            event_transmitter,
39        }
40    }
41
42    /// Create a new sampler with the given sample
43    pub fn new(context: &dyn Context, sample: OwnedAudioBuffer) -> Self {
44        Self::new_with_event_capacity(context, sample, EVENT_CHANNEL_CAPACITY)
45    }
46
47    /// Start the sampler playing
48    pub fn start_now(&mut self) {
49        self.send_event(SamplerEvent::start_now());
50    }
51
52    /// Stop the sampler playing
53    pub fn stop_now(&mut self) {
54        self.send_event(SamplerEvent::stop_now());
55    }
56
57    /// Start from the specified time, at the specified position in the sample
58    pub fn start_from_position_at_time(
59        &mut self,
60        start_time: Timestamp,
61        position_in_sample: Timestamp,
62    ) {
63        self.send_event(SamplerEvent::start(start_time, position_in_sample));
64    }
65
66    /// Stop at the specified time
67    pub fn stop_at_time(&mut self, stop_time: Timestamp) {
68        self.send_event(SamplerEvent::stop(stop_time));
69    }
70
71    /// Enable looping
72    ///
73    /// # Arguments
74    ///
75    /// * `loop_start` - The position in the sample to start the loop
76    /// * `loop_end` - The position in the sample to go back to `loop_start`
77    pub fn enable_loop(&mut self, loop_start: Timestamp, loop_end: Timestamp) {
78        self.send_event(SamplerEvent::enable_loop(loop_start, loop_end));
79    }
80
81    /// Cancel a loop
82    ///
83    /// This will clear the loop points and finish when it reaches the end of the sample
84    pub fn cancel_loop(&mut self) {
85        self.send_event(SamplerEvent::cancel_loop());
86    }
87
88    /// Cancel all scheduled events that haven't occurred yet
89    pub fn cancel_all(&mut self) {
90        self.send_event(SamplerEvent::cancel_all());
91    }
92
93    /// Enable loop at a time
94    ///
95    /// # Arguments
96    ///
97    /// * `enable_at_time` - The time to enable loop points
98    /// * `loop_start` - The position in the loop to start looping
99    /// * `loop_end` - The position in the loop to go back to the start
100    pub fn enable_loop_at_time(
101        &mut self,
102        enable_at_time: Timestamp,
103        loop_start: Timestamp,
104        loop_end: Timestamp,
105    ) {
106        self.send_event(SamplerEvent::enable_loop_at_time(
107            enable_at_time,
108            loop_start,
109            loop_end,
110        ));
111    }
112
113    /// Cancel the loop at a time
114    pub fn cancel_loop_at_time(&mut self, cancel_time: Timestamp) {
115        self.send_event(SamplerEvent::cancel_loop_at_time(cancel_time));
116    }
117
118    fn send_event(&mut self, event: SamplerEvent) {
119        debug_assert!(!self.event_transmitter.is_full());
120        let _ = self.event_transmitter.send(event);
121    }
122}