mkaudiolibrary 0.1.4

Modular audio processing library including MKAU plugin format based on Rust.
Documentation
//! ### Use
//! ```
//! use mkaudiolibrary::buffer::*;
//! use mkaudiolibrary::processor::*;
//!
//! #[derive(Debug, Default)]
//! struct Plugin
//! {
//!     parameters : [(String, f64);1],
//! }
//! impl Plugin { fn new() -> Self { return Plugin { parameters : [(parameter.to_string(), 0.5)] }; } }
//! impl Processor for Plugin
//! {
//!     fn init(& mut self) {}
//!     fn name(& self) -> String { return "Plugin".to_string(); }
//! fn get_parameter(& self, index: usize) -> f64 { return self.parameters[index].1; }
//! fn set_parameter(& mut self, index: usize, value: f64) { self.parameters[index].1 = value; }
//! fn get_parameter_name(self, index: usize) -> String { return self.parameters[index].0.clone(); }
//! fn run(& self, input: & mut Box<[CircularBuffer<f64>]>, sidechain_in: & mut Option<CircularBuffer<f64>>, output: & mut Box<[CircularBuffer<f64>]>, sidechain_out: & mut Option<CircularBuffer<f64>>, next: & bool, state: & bool)
//!     {
//!         (0..input.len()).for_each(|x|
//!         {
//!             let in_data = input[x].next();
//!             output[x].push(data * self.parameters[0].1);
//!         });
//!     }
//! }
//! mkaudiolibrary::declare_plugin!(Plugin, Plugin::new());
//! ```

extern crate libloading;

use std::ops::Add;
use libloading::{Library, Symbol};
use crate::buffer::CircularBuffer;

/// Declare plugin.
#[macro_export]
macro_rules! declare_plugin
{
    ($plugin_type:ty, $constructor:path) =>
    {
        #[no_mangle]
        pub extern "C" fn _create() -> * mut dyn Processor
        {
            let constructor : fn() -> plugin_type = constructor;
            let object = constructor();
            let boxed : Box<dyn Processor> = Box::new(object);
            return Box::into_raw(boxed);
        }
    };
}
pub trait Processor
{
    ///Initialize processor when loaded.
    fn init(& mut self);
    ///Returns name.
    fn name(& self) -> String;
    ///Get the value of the parameter of the index.
    fn get_parameter(& self, index : usize) -> f64;
    ///Set the value of the parameter of the index.
    fn set_parameter(& mut self, index : usize, value : f64);
    ///Get the name of the parameter of the index.
    fn get_parameter_name( self, index : usize) -> String;
    ///Process with the plugin. Optional sidechain I/O. Next to pause by buffer size. State to stop.
    fn run(& self, input: & mut Box<[CircularBuffer<f64>]>, sidechain_in : & mut Option<CircularBuffer<f64>>,
           output: & mut Box<[CircularBuffer<f64>]>, sidechain_out : & mut Option<CircularBuffer<f64>>,
           next : & bool, state : & bool);
}
///Loads plugin.
pub fn load(filename : String) -> Result<Box<dyn Processor>, Box<dyn std::error::Error>>
{
    unsafe
        {
            let lib = Library::new(filename.add(".mkap").as_str())?;
            let constructor : Symbol<unsafe extern fn() -> * mut dyn Processor> = lib.get(b"_create\0")?;
            let mut plugin = Box::from_raw(constructor());
            plugin.init();
            Ok(plugin)
        }
}