use crate::context::{AudioNodeId, AudioParamId};
use crate::events::EventDispatch;
use crate::RENDER_QUANTUM_SIZE;
use super::{graph::Node, AudioRenderQuantum};
use crossbeam_channel::Sender;
use rustc_hash::FxHashMap;
use std::cell::{Cell, RefCell};
use std::ops::Deref;
#[non_exhaustive] pub struct RenderScope {
pub current_frame: u64,
pub current_time: f64,
pub sample_rate: f32,
pub(crate) node_id: Cell<AudioNodeId>,
pub(crate) event_sender: Option<Sender<EventDispatch>>,
}
impl RenderScope {
pub(crate) fn send_ended_event(&self) {
if let Some(sender) = self.event_sender.as_ref() {
let _ = sender.try_send(EventDispatch::ended(self.node_id.get()));
}
}
}
pub trait AudioProcessor: Send {
fn process(
&mut self,
inputs: &[AudioRenderQuantum],
outputs: &mut [AudioRenderQuantum],
params: AudioParamValues,
scope: &RenderScope,
) -> bool;
}
struct DerefAudioRenderQuantumChannel<'a>(std::cell::Ref<'a, Node>);
impl Deref for DerefAudioRenderQuantumChannel<'_> {
type Target = [f32];
fn deref(&self) -> &Self::Target {
let buffer = self.0.get_buffer();
let len = if buffer.single_valued() {
1
} else {
RENDER_QUANTUM_SIZE
};
&buffer.channel_data(0)[..len]
}
}
pub struct AudioParamValues<'a> {
nodes: &'a FxHashMap<AudioNodeId, RefCell<Node>>,
}
impl<'a> AudioParamValues<'a> {
pub(crate) fn from(nodes: &'a FxHashMap<AudioNodeId, RefCell<Node>>) -> Self {
Self { nodes }
}
#[allow(clippy::missing_panics_doc)]
pub fn get(&self, index: &AudioParamId) -> impl Deref<Target = [f32]> + '_ {
DerefAudioRenderQuantumChannel(self.nodes.get(&index.into()).unwrap().borrow())
}
pub(crate) fn listener_params(&self) -> [impl Deref<Target = [f32]> + '_; 9] {
crate::context::LISTENER_AUDIO_PARAM_IDS.map(|p| self.get(&p))
}
}