use std::path::Path;
use crate::processor::{AudioIO, Processor};
use super::{HostError, HostResult, HostedPlugin, PluginDescriptor, PluginFormat};
pub(super) fn scan(directory: &Path) -> Vec<PluginDescriptor> {
let Ok(entries) = std::fs::read_dir(directory) else {
return Vec::new();
};
entries
.filter_map(|e| e.ok())
.filter(|e| e.path().extension().is_some_and(|ext| ext == "mkap"))
.filter_map(|e| {
let path = e.path();
let name = path.file_stem()?.to_str()?.to_string();
Some(PluginDescriptor {
format: PluginFormat::Mkap,
name,
vendor: String::new(),
path: Some(path),
category: String::new(),
au_component: None,
vst3_class_id: None,
})
})
.collect()
}
struct MkapHosted {
inner: Box<dyn Processor>,
}
unsafe impl Send for MkapHosted {}
impl HostedPlugin for MkapHosted {
fn name(&self) -> String {
self.inner.name()
}
fn vendor(&self) -> String {
String::new()
}
fn num_inputs(&self) -> usize {
self.inner.num_inputs()
}
fn num_outputs(&self) -> usize {
self.inner.num_outputs()
}
fn num_parameters(&self) -> usize {
self.inner.num_parameters()
}
fn parameter_name(&self, index: usize) -> String {
self.inner.get_parameter_name(index)
}
fn get_parameter(&self, index: usize) -> f32 {
self.inner.get_parameter(index)
}
fn set_parameter(&mut self, index: usize, value: f32) {
self.inner.set_parameter(index, value);
}
fn prepare(&mut self, sample_rate: usize, block_size: usize) -> HostResult<()> {
self.inner.prepare_to_play(block_size, sample_rate);
Ok(())
}
fn set_active(&mut self, _active: bool) -> HostResult<()> {
Ok(())
}
fn process(&mut self, audio: &mut AudioIO<'_>) {
self.inner.run(audio);
}
}
pub(super) fn load(descriptor: &PluginDescriptor) -> HostResult<Box<dyn HostedPlugin>> {
let path = descriptor
.path
.as_ref()
.ok_or_else(|| HostError::LoadFailed("MKAP descriptor is missing a path".into()))?;
let dir = path.parent().and_then(|p| p.to_str()).unwrap_or(".");
let name = path
.file_stem()
.and_then(|s| s.to_str())
.ok_or_else(|| HostError::LoadFailed(format!("invalid MKAP path: {}", path.display())))?;
let processor =
crate::processor::load(dir, name).map_err(|e| HostError::LoadFailed(e.to_string()))?;
Ok(Box::new(MkapHosted { inner: processor }))
}