1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use crate::sounds::wrappers::Controllable;
use crate::sounds::wrappers::Wrapper;
use crate::sounds::SoundMixer;
use crate::NextSample;
use crate::Sound;

/// Final mixed samples are pulled from the Renderer.
///
/// Samples are delivered via the Renderer to a backend.
/// Different backends are implemented in external crates for different
/// platforms and use cases.
///
/// The backend is responsible for:
///
///  1. storing the renderer
///  2. calling renderer.set_output_channel_count_and_sample_rate()
///  3. periodically calling renderer.on_start_of_batch() followed by some
///     number of renderer.next_sample() calls (normally enough to fill some
///     number of milliseconds of an output buffer).
pub struct Renderer {
    mixer: Controllable<SoundMixer>,
}

impl Renderer {
    pub(crate) fn new(mixer: Controllable<SoundMixer>) -> Self {
        Renderer { mixer }
    }

    /// Set the output channel count and sample rate that the rendered should
    /// return to the backend.
    pub fn set_output_channel_count_and_sample_rate(
        &mut self,
        output_channel_count: u16,
        output_sample_rate: u32,
    ) {
        self.mixer
            .inner_mut()
            .set_output_channel_count_and_sample_rate(output_channel_count, output_sample_rate);
    }
}

impl Sound for Renderer {
    fn channel_count(&self) -> u16 {
        self.mixer.channel_count()
    }

    fn sample_rate(&self) -> u32 {
        self.mixer.sample_rate()
    }

    /// Get the next sample.
    /// `MetadataChanged` will only be returned from Renderer if
    /// `set_output_channel_count_and_sample_rate` was called. If `Paused` is
    /// returned the backend may choose to pause itself or play silence (e.g.
    /// `.next_sample().unwrap_or(0)`). `Finished` will be returned if no sounds
    /// are playing and the Manager of the Renderer has been dropped.
    fn next_sample(&mut self) -> Result<NextSample, crate::Error> {
        self.mixer.next_sample()
    }

    /// Inform the playing or queued sounds that a new batch of samples will be
    /// requested. This must only be called when the next sample to be delivered
    /// from `next_sample` is for the first channel.
    ///
    /// See [Sound::on_start_of_batch]
    fn on_start_of_batch(&mut self) {
        self.mixer.on_start_of_batch()
    }
}