timbre/core.rs
1use std::sync::{Arc, Mutex};
2
3/// Used to know how to interpret audio data.
4#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
5pub struct AudioFormat {
6 pub channels: u8,
7 pub sample_rate: u32,
8}
9
10/// Indicates the state of an [`AudioSource`](crate::AudioSource).
11#[derive(Debug, Eq, PartialEq)]
12pub enum StreamState {
13 /// The source had sufficient data to fill the buffer.
14 Good,
15 /// The source had insufficient data to fill the buffer, but more may come later.
16 Underrun,
17 /// The source has no more data and doesn't expect more.
18 Finished,
19}
20
21/// Indicates the amount of data read and the status of an [`AudioSource`](crate::AudioSource).
22#[derive(Debug, Eq, PartialEq)]
23pub struct ReadResult {
24 pub state: StreamState,
25 pub read: usize,
26}
27
28impl ReadResult {
29 pub fn good(read: usize) -> Self {
30 ReadResult {
31 state: StreamState::Good,
32 read,
33 }
34 }
35
36 pub fn underrun(read: usize) -> Self {
37 ReadResult {
38 state: StreamState::Underrun,
39 read,
40 }
41 }
42
43 pub fn finished(read: usize) -> Self {
44 ReadResult {
45 state: StreamState::Finished,
46 read,
47 }
48 }
49}
50
51pub type Sample = f32;
52
53/// Bundles an [`AudioFormat`](crate::AudioFormat) with a buffer containing
54/// audio data in that format.
55pub struct AudioBuffer<'a> {
56 pub samples: &'a mut [Sample],
57 pub format: AudioFormat,
58}
59
60impl<'a> AudioBuffer<'a> {
61 pub fn new(format: AudioFormat, samples: &'a mut [Sample]) -> Self {
62 AudioBuffer { format, samples }
63 }
64}
65
66/// Trait implemented to provide audio data to consumers.
67///
68/// This is the center of this entire library. Almost everything
69/// is either an `AudioSource` or consumes an `AudioSource`.
70pub trait AudioSource {
71 /// Consume audio data and attempt to fill the given buffer.
72 ///
73 /// # Returns
74 ///
75 /// A [`ReadResult`](crate::ReadResult) indicating how much
76 /// data was put in the buffer and the state of the source.
77 ///
78 /// # Panics
79 ///
80 /// May panic if the format of the buffer is incompatible
81 /// with this source or its upstream sources.
82 fn read(&mut self, buffer: &mut AudioBuffer) -> ReadResult;
83}
84
85pub type SharedAudioSource = Arc<Mutex<dyn AudioSource + Send>>;
86
87/// Helpful extension to move [`AudioSource`](crate::AudioSource) implementations
88/// into an `Arc<Mutex<...>>`.
89pub trait IntoShared {
90 /// Move this audio source into an `Arc<Mutex<...>>` so that it can be
91 /// shared between threads.
92 fn into_shared(self) -> SharedAudioSource;
93}
94
95impl<T: AudioSource + Send + 'static> IntoShared for T {
96 fn into_shared(self) -> SharedAudioSource {
97 Arc::new(Mutex::new(self))
98 }
99}