audioviz 0.5.0

a simple and easy to use library that helps you visualise raw audio-data
Documentation
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

// I know it can be replaced with Option<>, but I want to add things in the future
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum VolumeNormalisation {
    None,
    Exponential,
    Logarithmic,

    /// both Exponential and Logarithmic
    Mixture,
}

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PositionNormalisation {
    Linear,
    Exponential,
    Harmonic,
}

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Interpolation {
    /// Not recommended
    ///
    /// All frequencies are tightly packed together without space distribution applied
    ///
    /// you would have to manually apply positions of frequencies and interpolation
    /// ```text
    ///     |
    ///     |
    ///   | |
    ///   | | | |
    ///   | | | |
    /// | | | | | |
    /// ++++++++++++
    ///
    /// ```
    None,

    /// ```text
    ///           | |
    ///           | |
    ///       | | | |
    ///       | | | | | |
    ///       | | | | | |
    /// | | | | | | | | | |
    /// +++++++++++++++++++
    /// ```
    Step,

    /// best looking, but might be inaccurate
    Cubic,

    /// ```text
    ///           |
    ///         | | |  
    ///       | | | |
    ///     | | | | | | |
    ///   | | | | | | | |
    /// | | | | | | | | | |
    /// +++++++++++++++++++
    /// ```
    Linear,

    /// ```text
    ///           |  
    ///           |  
    ///       |   |   | |
    ///       |   |   | |
    /// |     |   |   | | |
    /// +++++++++++++++++++
    /// ```
    /// The Gaps are empty Frequencies, (`Frequency::empty()`)
    Gaps,
}

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ProcessorConfig {
    /// neccessary so that the Audiostream knows what the hightest frequency is. (`sampling_rate` / 2)
    pub sampling_rate: u32,

    /// range of frequencies
    pub frequency_bounds: [usize; 2],

    /// number of total frequencies in processed data, None to disable up or downscaling
    /// 
    /// when `position_normalisation` and `resolution` is `None` no frequency information is lost
    /// 
    /// but when `position_normalisation` is set to anything else,
    /// information will be lost on high frequencies if no upscaling is done.
    pub resolution: Option<usize>,

    pub volume: f32,

    /// to even volume of low and high frequencies
    pub volume_normalisation: VolumeNormalisation,

    /// to mimic human hearing
    /// 
    /// might result in information loss on higher frequencies
    pub position_normalisation: PositionNormalisation,

    /// manually apply scale of frequencies
    ///
    /// frequencies around 50hz have double the scale: `vec![ (0, 1.0), (50, 2.0), (20000, 1.0) ]`
    ///
    /// this can be applied to an infinite number of frequencies: `vec![ (20, 1.0), (500, 2.0), (5000, 0.5) ... ]`
    pub manual_position_distribution: Option<Vec<(usize, f32)>>,

    /// applies positions of frequencies
    pub interpolation: Interpolation,
}
impl Default for ProcessorConfig {
    fn default() -> Self {
        ProcessorConfig {
            sampling_rate: 44_100,
            frequency_bounds: [50, 20000],
            resolution: None,
            volume: 1.0,
            volume_normalisation: VolumeNormalisation::Mixture,
            position_normalisation: PositionNormalisation::Harmonic,
            manual_position_distribution: None,
            interpolation: Interpolation::Cubic,
        }
    }
}

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StreamConfig {
    pub channel_count: u16,
    pub processor: ProcessorConfig,

    /// with higher resolution comes better precision, that is mostly needed for lower frequencies
    /// at the cost of latency and 'punchiness'
    pub fft_resolution: usize,

    /// should be set to match fps of output, gravity will be affected, because I have not implemented delta-time
    pub refresh_rate: usize,

    pub gravity: Option<f32>,
}
impl Default for StreamConfig {
    fn default() -> Self {
        StreamConfig {
            channel_count: 2,
            processor: ProcessorConfig::default(),
            fft_resolution: 1024 * 2,
            refresh_rate: 60,
            gravity: Some(1.0),
        }
    }
}