pub use std::any::TypeId;
pub use std::cell::UnsafeCell;
pub use std::marker::PhantomData;
pub use std::any::Any;
pub use super::types::{ContextHandle, Context, BufferIdx};
pub use super::Runtime;
pub use super::router::PortHandle;
pub use std::ops::{Deref, DerefMut};
pub trait Port{
fn port_type() -> PortType;
}
pub enum PortType{
SystemInput,
SystemOutput,
Input,
Output
}
pub struct Input<'a>(Option<&'a [f32]>);
pub struct Output<'a>(&'a mut [f32]);
pub struct State<'a, T: Default + Send + 'static>(&'a mut T);
pub struct Events<'a, E>(&'a mut E);
impl<'a> Deref for Input<'a> {
type Target = Option<&'a [f32]>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> Deref for Output<'a> {
type Target = [f32];
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a> DerefMut for Output<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}
impl<T: Default + Send> Deref for State<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0 }
}
impl<T: Default + Send> DerefMut for State<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0 }
}
impl<'a, E> Deref for Events<'a, E> {
type Target = E;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a, E> DerefMut for Events<'a, E> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}
impl Port for Input<'_> {
fn port_type() -> PortType {
PortType::Input
}
}
impl Port for Output<'_> {
fn port_type() -> PortType {
PortType::Output
}
}
pub struct SystemInput;
impl Port for SystemInput {
fn port_type() -> PortType {
PortType::SystemInput
}
}
pub struct SystemOutput;
impl Port for SystemOutput {
fn port_type() -> PortType {
PortType::SystemOutput
}
}
pub trait Processor: 'static {
type Handle: ProcessorHandle;
fn buffers_count() -> usize;
fn slot_count() -> usize;
fn call<E: Clone + Copy>(runtime: &Runtime<E>, handle: ContextHandle);
fn create_states() -> Vec<Box<UnsafeCell<dyn Any + Send + 'static>>>;
fn get_handle() -> Self::Handle;
}
pub trait ProcessorHandle {}
pub fn get_input<E: Clone + Copy + 'static>(runtime: &Runtime<E>, buffer_idx: BufferIdx) -> Input {
let buffer_id = runtime.buffer_ids[buffer_idx.0]
.expect("Input buffer not routed to physical buffer");
if let Some(buffer_cell) = runtime.buffers.get(&buffer_id) {
let buffer_ref = unsafe { &*buffer_cell.get() };
return Input(Some(buffer_ref));
} else {
return Input(None);
};
}
pub fn get_output<E: Clone + Copy + 'static>(runtime: &Runtime<E>, buffer_idx: BufferIdx) -> Output {
let buffer_id = runtime.buffer_ids[buffer_idx.0]
.expect("Output buffer not routed to physical buffer");
let buffer_cell = runtime.buffers.get(&buffer_id)
.expect("Physical buffer not found");
let buffer_ref = unsafe { &mut *buffer_cell.get() };
Output(buffer_ref)
}
pub fn get_state<T: Default + Send + 'static, E: Clone + Copy + 'static>(
runtime: &Runtime<E>,
state_idx: usize
) -> State<T> {
let state_cell = &runtime.states[state_idx];
let state_any = unsafe { &mut *state_cell.get() };
let state_ref = state_any.downcast_mut::<T>()
.expect("State type mismatch");
State(state_ref)
}
pub struct ProcessorName<P: Processor>{
pub name: &'static str,
pub _phantom: PhantomData<P>,
}
pub fn output() -> PortHandle<SystemOutput> {
PortHandle::new("__system_output__", 0, TypeId::of::<SystemOutput>(), TypeId::of::<SystemOutput>())
}
pub fn input() -> PortHandle<SystemInput> {
PortHandle::new("__system_input__", 0, TypeId::of::<SystemInput>(), TypeId::of::<SystemInput>())
}
mod test_filter{
use super::*;
#[derive(Default)]
struct FilterState{
z1: f32,
z2: f32,
z3: f32
}
fn filter(audio_in: Input, audio_out: Output, state: State<FilterState>){
}
struct Filter;
struct FilterHandle {
audio_in: PortHandle<Input<'static>>,
audio_out: PortHandle<Output<'static>>,
}
impl ProcessorHandle for FilterHandle {}
impl Processor for Filter {
type Handle = FilterHandle;
fn buffers_count() -> usize {2}
fn slot_count() -> usize {1}
fn call<E: Clone + Copy>(runtime: &Runtime<E>, ctx_handle: ContextHandle){
let ctx = runtime.get_ctx(ctx_handle);
let audio_in_idx = ctx.handle.buffer_ids_start + 0;
let audio_out_idx = ctx.handle.buffer_ids_start + 1;
let state_idx = ctx.handle.slot_ids_start + 0;
let audio_in = get_input(runtime, audio_in_idx);
let audio_out = get_output(runtime, audio_out_idx);
let state = get_state::<FilterState, E>(runtime, state_idx);
filter(audio_in, audio_out, state);
}
fn create_states() -> Vec<Box<UnsafeCell<dyn Any + Send + 'static>>> {
vec![
Box::new(UnsafeCell::new(FilterState::default())),
]
}
fn get_handle() -> FilterHandle {
FilterHandle {
audio_in: PortHandle::new("audio_in", 0, TypeId::of::<Input>(), TypeId::of::<Filter>()),
audio_out: PortHandle::new("audio_out", 1, TypeId::of::<Output>(), TypeId::of::<Filter>())
}
}
}
pub fn audio_in() -> PortHandle<Input<'static>> {
PortHandle::new("audio_in", 0, TypeId::of::<Input>(), TypeId::of::<Filter>())
}
pub fn audio_out() -> PortHandle<Output<'static>> {
PortHandle::new("audio_out", 1, TypeId::of::<Output>(), TypeId::of::<Filter>())
}
pub fn new() -> Filter{
Filter
}
}