1use std::sync::Arc;
6
7use malloc_size_of_derive::MallocSizeOf;
8
9use crate::audio_node::{
10 AudioNodeEngine, AudioNodeType, AudioScheduledSourceNodeMessage, BlockInfo, ChannelInfo,
11 OnEndedCallback, ShouldPlay,
12};
13use crate::block::{Block, Chunk, FRAMES_PER_BLOCK, Tick};
14use crate::param::{Param, ParamType};
15
16#[derive(Debug, Clone, MallocSizeOf)]
18pub enum AudioBufferSourceNodeMessage {
19 SetBuffer(#[conditional_malloc_size_of] Option<Arc<AudioBuffer>>),
21 SetLoopEnabled(bool),
23 SetLoopEnd(f64),
25 SetLoopStart(f64),
27 SetStartParams(f64, Option<f64>, Option<f64>),
29}
30
31#[derive(Debug, Clone, MallocSizeOf)]
33pub struct AudioBufferSourceNodeOptions {
34 #[conditional_malloc_size_of]
36 pub buffer: Option<Arc<AudioBuffer>>,
37 pub detune: f32,
39 pub loop_enabled: bool,
41 pub loop_end: Option<f64>,
43 pub loop_start: Option<f64>,
45 pub playback_rate: f32,
47}
48
49impl Default for AudioBufferSourceNodeOptions {
50 fn default() -> Self {
51 AudioBufferSourceNodeOptions {
52 buffer: None,
53 detune: 0.,
54 loop_enabled: false,
55 loop_end: None,
56 loop_start: None,
57 playback_rate: 1.,
58 }
59 }
60}
61
62#[derive(AudioScheduledSourceNode, AudioNodeCommon)]
65#[allow(dead_code)]
66pub(crate) struct AudioBufferSourceNode {
67 channel_info: ChannelInfo,
68 buffer: Option<Arc<AudioBuffer>>,
70 buffer_duration: f64,
72 buffer_pos: f64,
77 detune: Param,
79 initialized_pos: bool,
81 loop_enabled: bool,
84 loop_end: Option<f64>,
87 loop_start: Option<f64>,
90 playback_rate: Param,
94 start_at: Option<Tick>,
96 start_offset: Option<f64>,
98 start_duration: Option<f64>,
100 start_when: f64,
103 stop_at: Option<Tick>,
105 pub onended_callback: Option<OnEndedCallback>,
107}
108
109impl AudioBufferSourceNode {
110 pub fn new(options: AudioBufferSourceNodeOptions, channel_info: ChannelInfo) -> Self {
111 Self {
112 channel_info,
113 buffer: options.buffer,
114 buffer_pos: 0.,
115 detune: Param::new_krate(options.detune),
116 initialized_pos: false,
117 loop_enabled: options.loop_enabled,
118 loop_end: options.loop_end,
119 loop_start: options.loop_start,
120 playback_rate: Param::new_krate(options.playback_rate),
121 buffer_duration: f64::INFINITY,
122 start_at: None,
123 start_offset: None,
124 start_duration: None,
125 start_when: 0.,
126 stop_at: None,
127 onended_callback: None,
128 }
129 }
130
131 pub fn handle_message(&mut self, message: AudioBufferSourceNodeMessage, _: f32) {
132 match message {
133 AudioBufferSourceNodeMessage::SetBuffer(buffer) => {
134 self.buffer = buffer;
135 },
136 AudioBufferSourceNodeMessage::SetLoopEnabled(loop_enabled) => {
139 self.loop_enabled = loop_enabled
140 },
141 AudioBufferSourceNodeMessage::SetLoopEnd(loop_end) => self.loop_end = Some(loop_end),
142 AudioBufferSourceNodeMessage::SetLoopStart(loop_start) => {
143 self.loop_start = Some(loop_start)
144 },
145 AudioBufferSourceNodeMessage::SetStartParams(when, offset, duration) => {
146 self.start_when = when;
147 self.start_offset = offset;
148 self.start_duration = duration;
149 },
150 }
151 }
152}
153
154impl AudioNodeEngine for AudioBufferSourceNode {
155 fn node_type(&self) -> AudioNodeType {
156 AudioNodeType::AudioBufferSourceNode
157 }
158
159 fn input_count(&self) -> u32 {
160 0
161 }
162
163 fn process(&mut self, mut inputs: Chunk, info: &BlockInfo) -> Chunk {
164 debug_assert!(inputs.is_empty());
165
166 if self.buffer.is_none() {
167 inputs.blocks.push(Default::default());
168 return inputs;
169 }
170
171 let (start_at, stop_at) = match self.should_play_at(info.frame) {
172 ShouldPlay::No => {
173 inputs.blocks.push(Default::default());
174 return inputs;
175 },
176 ShouldPlay::Between(start, end) => (start.0 as usize, end.0 as usize),
177 };
178
179 let buffer = self.buffer.as_ref().unwrap();
180
181 let (mut actual_loop_start, mut actual_loop_end) = (0., buffer.len() as f64);
182 if self.loop_enabled {
183 let loop_start = self.loop_start.unwrap_or(0.);
184 let loop_end = self.loop_end.unwrap_or(0.);
185
186 if loop_start >= 0. && loop_end > loop_start {
187 actual_loop_start = loop_start * (buffer.sample_rate as f64);
188 actual_loop_end = loop_end * (buffer.sample_rate as f64);
189 }
190 }
191
192 self.playback_rate.update(info, Tick(0));
194 self.detune.update(info, Tick(0));
195 let computed_playback_rate =
197 self.playback_rate.value() as f64 * (2.0_f64).powf(self.detune.value() as f64 / 1200.);
198 let forward = computed_playback_rate >= 0.;
199
200 if !self.initialized_pos {
201 self.initialized_pos = true;
202
203 if let Some(start_offset) = self.start_offset {
207 self.buffer_pos = start_offset * (buffer.sample_rate as f64);
208 if self.buffer_pos < 0. {
209 self.buffer_pos = 0.
210 } else if self.buffer_pos > buffer.len() as f64 {
211 self.buffer_pos = buffer.len() as f64;
212 }
213 }
214
215 if self.loop_enabled {
216 if forward && self.buffer_pos >= actual_loop_end {
217 self.buffer_pos = actual_loop_start;
218 }
219 if !forward && self.buffer_pos < actual_loop_start {
221 self.buffer_pos = actual_loop_end;
222 }
223 }
224
225 if let Some(start_duration) = self.start_duration {
226 self.buffer_duration = start_duration * (buffer.sample_rate as f64);
227 }
228
229 if self.start_when > info.time - 1. / info.sample_rate as f64 {
239 let first_time = info.time + start_at as f64 / info.sample_rate as f64;
240 if self.start_when <= first_time {
241 let subsample_offset = (first_time - self.start_when) *
242 (buffer.sample_rate as f64) *
243 computed_playback_rate;
244 self.buffer_pos += subsample_offset;
245 self.buffer_duration -= subsample_offset.abs();
246 }
247 }
248 }
249
250 let mut buffer_offset_per_tick =
251 computed_playback_rate * (buffer.sample_rate as f64 / info.sample_rate as f64);
252
253 if self.loop_enabled && actual_loop_end > actual_loop_start {
264 let loop_length = actual_loop_end - actual_loop_start;
265 if loop_length > 0. {
266 let step = buffer_offset_per_tick.abs();
267 if step >= loop_length {
268 let mut wrapped = step.rem_euclid(loop_length);
269 if wrapped == 0. {
270 wrapped = loop_length;
271 }
272 buffer_offset_per_tick = wrapped.copysign(buffer_offset_per_tick);
273 }
274 }
275 }
276
277 let frames_to_output = stop_at - start_at;
279
280 if frames_to_output == FRAMES_PER_BLOCK.0 as usize &&
283 forward &&
284 buffer_offset_per_tick == 1. &&
285 self.buffer_pos.trunc() == self.buffer_pos &&
286 self.buffer_pos + (FRAMES_PER_BLOCK.0 as f64) <= actual_loop_end &&
287 FRAMES_PER_BLOCK.0 as f64 <= self.buffer_duration
288 {
289 let mut block = Block::empty();
290 let pos = self.buffer_pos as usize;
291
292 for chan in 0..buffer.chans() {
293 block.push_chan(&buffer.buffers[chan as usize][pos..(pos + frames_to_output)]);
294 }
295
296 inputs.blocks.push(block);
297 self.buffer_pos += FRAMES_PER_BLOCK.0 as f64;
298 self.buffer_duration -= FRAMES_PER_BLOCK.0 as f64;
299 } else {
300 let mut block = Block::default();
302 block.repeat(buffer.chans());
303 block.explicit_repeat();
304
305 debug_assert!(buffer.chans() > 0);
306
307 for chan in 0..buffer.chans() {
308 let data = block.data_chan_mut(chan);
309 let (_, data) = data.split_at_mut(start_at);
310 let (data, _) = data.split_at_mut(frames_to_output);
311
312 let mut pos = self.buffer_pos;
313 let mut duration = self.buffer_duration;
314
315 for sample in data {
316 if duration <= 0. {
317 break;
318 }
319
320 if self.loop_enabled {
321 if forward && pos >= actual_loop_end {
322 pos -= actual_loop_end - actual_loop_start;
323 } else if !forward && pos < actual_loop_start {
324 pos += actual_loop_end - actual_loop_start;
325 }
326 } else if pos < 0. || pos >= buffer.len() as f64 {
327 break;
328 }
329
330 *sample = buffer.interpolate(chan, pos);
331 pos += buffer_offset_per_tick;
332 duration -= buffer_offset_per_tick.abs();
333 }
334
335 if chan == buffer.chans() - 1 {
337 self.buffer_pos = pos;
338 self.buffer_duration = duration;
339 }
340 }
341
342 inputs.blocks.push(block);
343 }
344
345 if !self.loop_enabled && (self.buffer_pos < 0. || self.buffer_pos >= buffer.len() as f64) ||
346 self.buffer_duration <= 0.
347 {
348 self.maybe_trigger_onended_callback();
349 }
350
351 inputs
352 }
353
354 fn get_param(&mut self, id: ParamType) -> &mut Param {
355 match id {
356 ParamType::PlaybackRate => &mut self.playback_rate,
357 ParamType::Detune => &mut self.detune,
358 _ => panic!("Unknown param {:?} for AudioBufferSourceNode", id),
359 }
360 }
361
362 make_message_handler!(
363 AudioBufferSourceNode: handle_message,
364 AudioScheduledSourceNode: handle_source_node_message
365 );
366}
367
368#[derive(Debug, Clone, MallocSizeOf)]
369pub struct AudioBuffer {
370 pub buffers: Vec<Vec<f32>>,
372 pub sample_rate: f32,
373}
374
375impl AudioBuffer {
376 pub fn new(chan: u8, len: usize, sample_rate: f32) -> Self {
377 assert!(chan > 0);
378 let mut buffers = Vec::with_capacity(chan as usize);
379 let single = vec![0.; len];
380 buffers.resize(chan as usize, single);
381 AudioBuffer {
382 buffers,
383 sample_rate,
384 }
385 }
386
387 pub fn from_buffers(buffers: Vec<Vec<f32>>, sample_rate: f32) -> Self {
388 for buf in &buffers {
389 assert_eq!(buf.len(), buffers[0].len())
390 }
391
392 Self {
393 buffers,
394 sample_rate,
395 }
396 }
397
398 pub fn from_buffer(buffer: Vec<f32>, sample_rate: f32) -> Self {
399 AudioBuffer::from_buffers(vec![buffer], sample_rate)
400 }
401
402 pub fn len(&self) -> usize {
403 self.buffers[0].len()
404 }
405
406 pub fn is_empty(&self) -> bool {
407 self.len() == 0
408 }
409
410 pub fn chans(&self) -> u8 {
411 self.buffers.len() as u8
412 }
413
414 pub fn interpolate(&self, chan: u8, pos: f64) -> f32 {
419 debug_assert!(pos >= 0. && pos < self.len() as f64);
420
421 let prev = pos.floor() as usize;
422 let offset = pos - pos.floor();
423 match self.buffers[chan as usize].get(prev + 1) {
424 Some(next_sample) => {
425 ((1. - offset) * (self.buffers[chan as usize][prev] as f64) +
426 offset * (*next_sample as f64)) as f32
427 },
428 _ => {
429 if prev > 0 {
431 ((1. + offset) * (self.buffers[chan as usize][prev] as f64) -
432 offset * (self.buffers[chan as usize][prev - 1] as f64))
433 as f32
434 } else {
435 self.buffers[chan as usize][prev]
436 }
437 },
438 }
439 }
440
441 pub fn scale(&mut self, scale: f64) {
442 for buffer in self.buffers.as_mut_slice() {
443 *buffer = buffer
444 .iter()
445 .map(|x| (*x as f64 * scale) as f32)
446 .collect::<Vec<_>>();
447 }
448 }
449
450 pub fn data_chan_mut(&mut self, chan: u8) -> &mut [f32] {
451 &mut self.buffers[chan as usize]
452 }
453}