use crate::controller::Controller;
#[allow(unused)]
use crate::controller::KnystCommands;
use crate::KnystError;
use crate::{resources::ResourcesSettings, Resources, Sample};
use std::time::Duration;
use crate::{
graph::{Graph, GraphSettings, RunGraphSettings},
modal_interface::{register_sphere, set_active_sphere, SphereError, SphereId},
prelude::{AudioBackend, MultiThreadedKnystCommands},
};
pub struct KnystSphere {
#[allow(unused)]
name: String,
knyst_commands: MultiThreadedKnystCommands,
}
impl KnystSphere {
pub fn start<B: AudioBackend>(
backend: &mut B,
settings: SphereSettings,
error_handler: impl FnMut(KnystError) + Send + 'static,
) -> Result<SphereId, SphereError> {
let resources = Resources::new(settings.resources_settings);
let graph_settings = GraphSettings {
name: settings.name.clone(),
num_inputs: backend
.native_input_channels()
.unwrap_or(settings.num_inputs),
num_outputs: backend
.native_output_channels()
.unwrap_or(settings.num_outputs),
block_size: backend.block_size().unwrap_or(64),
sample_rate: backend.sample_rate() as Sample,
..Default::default()
};
let graph: Graph = Graph::new(graph_settings);
let k = backend.start_processing(
graph,
resources,
RunGraphSettings {
scheduling_latency: settings.scheduling_latency,
},
Box::new(error_handler),
)?;
let s = Self {
name: settings.name,
knyst_commands: k,
};
let sphere_id = register_sphere(s)?;
set_active_sphere(sphere_id)?;
Ok(sphere_id)
}
pub fn start_return_controller<B: AudioBackend>(
backend: &mut B,
settings: SphereSettings,
error_handler: impl FnMut(KnystError) + Send + 'static,
) -> Result<(SphereId, Controller), SphereError> {
let resources = Resources::new(settings.resources_settings);
let graph_settings = GraphSettings {
name: settings.name.clone(),
num_inputs: backend
.native_input_channels()
.unwrap_or(settings.num_inputs),
num_outputs: backend
.native_output_channels()
.unwrap_or(settings.num_outputs),
block_size: backend.block_size().unwrap_or(64),
sample_rate: backend.sample_rate() as Sample,
ring_buffer_size: settings.scheduling_ring_buffer_capacity,
..Default::default()
};
let graph: Graph = Graph::new(graph_settings);
let controller = backend.start_processing_return_controller(
graph,
resources,
RunGraphSettings {
scheduling_latency: settings.scheduling_latency,
},
Box::new(error_handler),
)?;
let s = Self {
name: settings.name,
knyst_commands: controller.get_knyst_commands(),
};
let sphere_id = register_sphere(s)?;
set_active_sphere(sphere_id)?;
Ok((sphere_id, controller))
}
#[must_use]
pub fn commands(&self) -> MultiThreadedKnystCommands {
self.knyst_commands.clone()
}
}
#[derive(Debug, Clone)]
pub struct SphereSettings {
pub name: String,
pub resources_settings: ResourcesSettings,
pub num_inputs: usize,
pub num_outputs: usize,
pub scheduling_latency: Duration,
pub scheduling_ring_buffer_capacity: usize,
}
impl Default for SphereSettings {
fn default() -> Self {
Self {
name: Default::default(),
resources_settings: Default::default(),
scheduling_latency: Duration::from_millis(100),
num_inputs: 2,
num_outputs: 2,
scheduling_ring_buffer_capacity: 1000,
}
}
}