notation_audio/
mono_stream.rs

1use bevy::prelude::*;
2use bevy::audio::{Source, AddAudioSource};
3use ringbuffer::{AllocRingBuffer, RingBuffer};
4use bevy::utils::syncunsafecell::SyncUnsafeCell;
5use std::sync::Arc;
6
7pub struct MonoStreamDecoder {
8    buffer: Arc<SyncUnsafeCell<AllocRingBuffer<f32>>>,
9}
10
11impl std::fmt::Debug for MonoStreamDecoder {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        let buffer = unsafe {
14            self.buffer.as_ref().get().as_mut().unwrap()
15        };
16        write!(f, "<MonoStreamDecoder>({}/{})", buffer.len(), buffer.capacity())
17    }
18}
19
20impl Iterator for MonoStreamDecoder {
21    type Item = f32;
22
23    fn next(&mut self) -> Option<Self::Item> {
24        let buffer = unsafe {
25            self.buffer.as_ref().get().as_mut().unwrap()
26        };
27        if buffer.is_full() {
28            let capacity = buffer.capacity();
29            println!("<MonoStreamDecoder>[{}] buffer is full", capacity);
30        }
31        let data = buffer.dequeue().unwrap_or(0.0);
32        Some(data)
33    }
34}
35
36impl Source for MonoStreamDecoder {
37    fn current_frame_len(&self) -> Option<usize> {
38        None
39    }
40
41    fn channels(&self) -> u16 {
42        1
43    }
44
45    fn sample_rate(&self) -> u32 {
46        44_100
47    }
48
49    fn total_duration(&self) -> Option<std::time::Duration> {
50        None
51    }
52}
53
54#[derive(Asset, TypePath)]
55pub struct MonoStream {
56    pub volume: f32,
57    buffer: Arc<SyncUnsafeCell<AllocRingBuffer<f32>>>,
58}
59
60impl std::fmt::Debug for MonoStream {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        let buffer = unsafe {
63            self.buffer.as_ref().get().as_mut().unwrap()
64        };
65        write!(f, "<MonoStream>({}/{}, v:{})", buffer.len(), buffer.capacity(), self.volume)
66    }
67}
68
69impl Decodable for MonoStream {
70    type DecoderItem = <MonoStreamDecoder as Iterator>::Item;
71    type Decoder = MonoStreamDecoder;
72
73    fn decoder(&self) -> Self::Decoder {
74        MonoStreamDecoder {
75            buffer: self.buffer.clone(),
76        }
77    }
78}
79
80impl MonoStream {
81    pub const FRAME_STEP: f64 = 1.0 / 44_100.0;
82
83    pub const DEFAULT_CAPACITY: usize = 4096;
84    pub const DEFAULT_VOLUME: f32 = 1.0;
85
86    pub fn remaining(&self) -> usize {
87        let buffer = unsafe {
88            self.buffer.as_ref().get().as_mut().unwrap()
89        };
90        buffer.capacity() - buffer.len()
91    }
92
93    pub fn push(&mut self, data: f32) {
94        let buffer = unsafe {
95            self.buffer.as_ref().get().as_mut().unwrap()
96        };
97        buffer.push(data * self.volume);
98    }
99
100    pub fn push_batch(&mut self, volume_factor: f32, data: &[f32]) {
101        let buffer = unsafe {
102            self.buffer.as_ref().get().as_mut().unwrap()
103        };
104        for i in 0..data.len() {
105            buffer.push(data[i] * self.volume * volume_factor);
106        }
107    }
108
109    pub fn init_streaming(
110        app: &mut App,
111        setup_default_streaming: bool,
112    ) {
113        app.add_audio_source::<MonoStream>();
114        if setup_default_streaming {
115            app.add_systems(Startup, Self::setup_default_streaming);
116        }
117    }
118    pub fn setup_streaming(
119        commands: &mut Commands,
120        assets: &mut ResMut<Assets<MonoStream>>,
121        capacity: usize,
122        volume: f32,
123    ) {
124        let buffer = AllocRingBuffer::<f32>::new(capacity);
125        let stream = MonoStream {
126            volume,
127            buffer: Arc::new(SyncUnsafeCell::new(buffer)),
128        };
129        let stream_handle = assets.add(stream);
130        commands.spawn(AudioSourceBundle {
131            source: stream_handle,
132            ..default()
133        });
134    }
135    pub fn setup_default_streaming(
136        mut commands: Commands,
137        mut assets: ResMut<Assets<MonoStream>>,
138    ) {
139        Self::setup_streaming(&mut commands, &mut assets, Self::DEFAULT_CAPACITY, Self::DEFAULT_VOLUME);
140    }
141}