notation_audio/
mono_stream.rs1use 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}