rg3d_sound/buffer/
streaming.rs1use crate::buffer::RawStreamingDataSource;
30use crate::{
31 buffer::{generic::GenericBuffer, DataSource},
32 decoder::Decoder,
33 error::SoundError,
34};
35use rg3d_core::visitor::{Visit, VisitResult, Visitor};
36use std::ops::{Deref, DerefMut};
37use std::time::Duration;
38
39#[derive(Debug, Default)]
41pub struct StreamingBuffer {
42 pub(in crate) generic: GenericBuffer,
43 pub(in crate) use_count: usize,
47 streaming_source: StreamingSource,
48}
49
50#[derive(Debug)]
51enum StreamingSource {
52 Null,
53 Decoder(Decoder),
54 Raw(Box<dyn RawStreamingDataSource>),
55}
56
57impl Default for StreamingSource {
58 fn default() -> Self {
59 Self::Null
60 }
61}
62
63impl StreamingSource {
64 #[inline]
65 fn new(data_source: DataSource) -> Result<Self, DataSource> {
66 match data_source {
67 DataSource::File { .. } | DataSource::Memory(_) => {
68 Ok(Self::Decoder(Decoder::new(data_source)?))
69 }
70 DataSource::RawStreaming(raw) => Ok(Self::Raw(raw)),
71 _ => Err(data_source),
73 }
74 }
75
76 #[inline]
77 fn sample_rate(&self) -> usize {
78 match self {
79 StreamingSource::Decoder(decoder) => decoder.get_sample_rate(),
80 StreamingSource::Raw(raw) => raw.sample_rate(),
81 StreamingSource::Null => 0,
82 }
83 }
84
85 #[inline]
86 fn channel_count(&self) -> usize {
87 match self {
88 StreamingSource::Decoder(decoder) => decoder.get_channel_count(),
89 StreamingSource::Raw(raw) => raw.channel_count(),
90 StreamingSource::Null => 0,
91 }
92 }
93
94 fn duration(&self) -> Option<Duration> {
95 match self {
96 StreamingSource::Null => None,
97 StreamingSource::Decoder(decoder) => decoder.duration(),
98 StreamingSource::Raw(raw) => raw.duration(),
99 }
100 }
101
102 fn rewind(&mut self) -> Result<(), SoundError> {
103 match self {
104 StreamingSource::Null => Ok(()),
105 StreamingSource::Decoder(decoder) => decoder.rewind(),
106 StreamingSource::Raw(raw) => raw.rewind(),
107 }
108 }
109
110 fn time_seek(&mut self, location: Duration) {
111 match self {
112 StreamingSource::Null => {}
113 StreamingSource::Decoder(decoder) => decoder.time_seek(location),
114 StreamingSource::Raw(raw) => raw.time_seek(location),
115 }
116 }
117
118 #[inline]
119 fn read_next_samples_block_into(&mut self, buffer: &mut Vec<f32>) -> usize {
120 buffer.clear();
121 let count = StreamingBuffer::STREAM_SAMPLE_COUNT * self.channel_count();
122 match self {
123 StreamingSource::Decoder(decoder) => {
124 for _ in 0..count {
125 if let Some(sample) = decoder.next() {
126 buffer.push(sample)
127 } else {
128 break;
129 }
130 }
131 }
132 StreamingSource::Raw(raw_streaming) => {
133 for _ in 0..count {
134 if let Some(sample) = raw_streaming.next() {
135 buffer.push(sample)
136 } else {
137 break;
138 }
139 }
140 }
141 StreamingSource::Null => (),
142 }
143
144 buffer.len()
145 }
146}
147
148impl StreamingBuffer {
149 pub const STREAM_SAMPLE_COUNT: usize = 44100;
151
152 pub fn new(source: DataSource) -> Result<Self, DataSource> {
161 let external_source_path = if let DataSource::File { path, .. } = &source {
162 path.clone()
163 } else {
164 Default::default()
165 };
166
167 let mut streaming_source = StreamingSource::new(source)?;
168
169 let mut samples = Vec::new();
170 let channel_count = streaming_source.channel_count();
171 streaming_source.read_next_samples_block_into(&mut samples);
172 debug_assert_eq!(samples.len() % channel_count, 0);
173
174 Ok(Self {
175 generic: GenericBuffer {
176 samples,
177 sample_rate: streaming_source.sample_rate(),
178 channel_count: streaming_source.channel_count(),
179 external_source_path,
180 },
181 use_count: 0,
182 streaming_source,
183 })
184 }
185
186 pub fn duration(&self) -> Option<Duration> {
188 self.streaming_source.duration()
189 }
190
191 #[inline]
192 pub(in crate) fn read_next_block(&mut self) {
193 self.streaming_source
194 .read_next_samples_block_into(&mut self.generic.samples);
195 }
196
197 #[inline]
198 pub(in crate) fn rewind(&mut self) -> Result<(), SoundError> {
199 self.streaming_source.rewind()
200 }
201
202 #[inline]
203 pub(in crate) fn time_seek(&mut self, location: Duration) {
204 self.streaming_source.time_seek(location);
205 }
206}
207
208impl Deref for StreamingBuffer {
209 type Target = GenericBuffer;
210
211 fn deref(&self) -> &Self::Target {
214 &self.generic
215 }
216}
217
218impl DerefMut for StreamingBuffer {
219 fn deref_mut(&mut self) -> &mut Self::Target {
221 &mut self.generic
222 }
223}
224
225impl Visit for StreamingBuffer {
226 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
227 visitor.enter_region(name)?;
228
229 self.generic.visit("Generic", visitor)?;
230
231 visitor.leave_region()
232 }
233}