mkaudiolibrary 0.1.8

Modular audio processing library including MKAU plugin format based on Rust.
Documentation
use std::alloc::{alloc_zeroed, dealloc, Layout};

///The buffer that pushes the whole buffer when index meets the size of the buffer.
#[derive(Clone)]
pub struct PushBuffer<T>
{
    buffer : * mut T,
    pub index : isize,
    len : isize
}
impl PushBuffer<f32>
{
    ///New PushBuffer with length.
    pub fn new(len : usize) -> Self
    {
        let layout = Layout::array::<f32>(len);

        match layout
        {
            Ok(layout) =>
                {
                    let buffer = unsafe { alloc_zeroed(layout) as * mut f32 };
                    return PushBuffer { buffer, index : 0, len : len as isize };
                }
            Err(error) => { panic!("{}", error); }
        }
    }
}
impl PushBuffer<f64>
{
    ///New PushBuffer with length.
    pub fn new(len : usize) -> Self
    {
        let layout = Layout::array::<f64>(len);

        match layout
        {
            Ok(layout) =>
                {
                    let buffer = unsafe { alloc_zeroed(layout) as * mut f64 };
                    return PushBuffer { buffer, index : 0, len : len as isize };
                }
            Err(error) => { panic!("{}", error); }
        }
    }
}
impl<T : Copy> PushBuffer<T>
{
    ///Pushes data to buffer.
    pub fn push(& mut self, value : T)
    {
        if self.index <= self.len
        {
            unsafe { * self.buffer.offset(self.index) = value; }
            self.index += 1;
        }
        else
        {
            unsafe
                {
                    (1..self.len).for_each(|x| * self.buffer.offset(x - 1) = * self.buffer.offset(x));
                    * self.buffer.offset(self.index) = value;
                }
        }
    }
    ///Returns the length of the buffer.
    pub fn len(& self) -> isize { return self.len; }
}
impl<T> std::ops::Index<usize> for PushBuffer<T>
{
    type Output = T;
    fn index(&self, index: usize) -> & Self::Output
    {
        let data = unsafe { self.buffer.offset(index as isize).as_ref() };
        match data
        {
            None => { panic!("Access to invalid memory"); }
            Some(reference) => { return reference; }
        }
    }
}
impl<T> std::ops::IndexMut<usize> for PushBuffer<T>
{
    fn index_mut(&mut self, index: usize) -> & mut Self::Output
    {
        let data = unsafe { self.buffer.offset(index as isize).as_mut() };
        match data
        {
            None => { panic!("Access to invalid memory"); }
            Some(reference) => { return reference; }
        }
    }
}
impl<T> Drop for PushBuffer<T>
{
    fn drop(&mut self)
    {
        let layout = Layout::array::<f64>(self.len as usize);
        match layout
        {
            Ok(layout) => { unsafe { dealloc(self.buffer as * mut u8, layout); } }
            Err(error) => { panic!("{}", error); }
        }
    }
}

///Circular buffer or ring buffer. When index returns to 0 when index meets the size of the buffer.
#[derive(Clone)]
pub struct CircularBuffer<T>
{
    buffer : * mut T,
    read : isize,
    write : isize,
    len : isize
}
impl CircularBuffer<f32>
{
    ///New CircularBuffer with length.
    pub fn new(len : usize) -> Self
    {
        let layout = Layout::array::<f32>(len);

        match layout
        {
            Ok(layout) =>
                {
                    let buffer = unsafe { alloc_zeroed(layout) as * mut f32 };
                    return CircularBuffer { buffer, read : 0, write : 0, len : len as isize };
                }
            Err(error) => { panic!("{}", error); }
        }
    }
}
impl CircularBuffer<f64>
{
    ///New CircularBuffer with length.
    pub fn new(len : usize) -> Self
    {
        let layout = Layout::array::<f64>(len);

        match layout
        {
            Ok(layout) =>
                {
                    let buffer = unsafe { alloc_zeroed(layout) as * mut f64 };
                    return CircularBuffer { buffer, read : 0, write : 0, len : len as isize };
                }
            Err(error) => { panic!("{}", error); }
        }
    }
}
impl<T : Copy + PartialEq> CircularBuffer<T>
{
    ///Pushes data to buffer.
    pub fn push(& mut self, value : T)
    {
        unsafe { * self.buffer.offset(self.write) = value; }
        if self.write < self.len() { self.write += 1; } else { self.write = 0; }
    }
    ///Reads next data of the buffer.
    pub fn next(& mut self) -> T
    {
        let value = unsafe { *self.buffer.offset(self.read) };
        if self.write < self.len() { self.read += 1; } else { self.read = 0; }
        return value;
    }
    ///Initializes write index.
    pub fn init_write(& mut self, index : isize) { self.write = index; }
    ///Initializes read index.
    pub fn init_read(& mut self, index : isize) { self.write = index; }
    ///Returns the length of the buffer.
    pub fn len(& self) -> isize { return self.len; }
}
impl<T> Drop for CircularBuffer<T>
{
    fn drop(&mut self)
    {
        let layout = Layout::array::<f64>(self.len as usize);
        match layout
        {
            Ok(layout) => { unsafe { dealloc(self.buffer as * mut u8, layout); } }
            Err(error) => { panic!("{}", error); }
        }
    }
}