tear8 0.1.78

Tear8 is a Rust library that enables you to create your own games or fantasy consoles using Winit and Pixels.
Documentation
use rodio::source::Source;
use rodio::{OutputStream, Sink, OutputStreamHandle};
use std::time::Duration;

/// Normal sample rate for waves
pub const SAMPLE_RATE: u32 = 44100;

pub trait Wave {
    fn logic(&mut self, freq: f32) -> f32;
}

pub struct RawWave<T> 
where T:
    Wave
{
    logic: Box<T>,
    config: WaveConfigurator
}

impl<T> RawWave<T> 
where T:
    Wave
{
    pub fn new(config: WaveConfigurator, wave_type_struct: T) -> Self {
        Self {
            logic: Box::new(wave_type_struct),
            config
        }
    }
}

impl<T> Source for RawWave<T>
where T:
    Wave
{
    fn current_frame_len(&self) -> Option<usize> {
        None
    }

    fn channels(&self) -> u16 {
        1
    }

    fn sample_rate(&self) -> u32 {
        SAMPLE_RATE
    }

    fn total_duration(&self) -> Option<Duration> {
        None
    }
}

impl<T> Iterator for RawWave<T>
where T:
    Wave
{
    type Item = f32;

    fn next(&mut self) -> Option<f32> {
        let result = self.logic.logic(self.config.freq);
        return Some(result);
    }
}

pub struct WaveBuilder;

impl WaveBuilder {
    /// Create a builded wave
    pub fn build<T>(wave: RawWave<T>) -> BuildedWave
    where T: 
        Wave + Send + 'static
    {
        let (stream, handle) = OutputStream::try_default().unwrap();
        let sink = Sink::try_new(&handle).ok().unwrap();

        let volume = wave.config.volume;
        sink.set_volume(volume);
        sink.set_speed(wave.config.speed);
        
        sink.append(wave);
        sink.play();

        BuildedWave::new(sink, stream, handle)
    }
}

#[derive(Clone, Copy)]
/// A Configurator for waves
pub struct WaveConfigurator {
    freq: f32,
    volume: f32,
    speed: f32,
}

impl WaveConfigurator {
    /// Create new configurator
    pub fn new(freq: f32, volume: f32, speed: f32) -> Self {
        Self {
            freq,
            volume,
            speed,
        }
    }
}

/// A structure for creating a finite wave
pub struct BuildedWave {
    sink: Sink,
    _stream: OutputStream,
    _handle: OutputStreamHandle,
}

impl BuildedWave {
    /// Create a builded wave
    pub fn new(sink: Sink, _stream: OutputStream, _handle: OutputStreamHandle) -> Self {
        Self {
            sink,
            _stream,
            _handle,
        }
    }

    /// Change volume of the wave (default is 0.5)
    pub fn set_volume(&mut self, value: f32) {
        self.sink.set_volume(value);
    }

    /// Change speed of the wave (default is 1.)
    pub fn set_speed(&mut self, value: f32) {
        let mut speed = value;

        if speed <= 0. {
            speed = 0.1
        }
        
        self.sink.set_speed(speed);
    }

    /// Get wave sink speed
    pub fn speed(&self) -> f32 { 
        self.sink.speed()
    }

    /// Get wave sink volume
    pub fn volume(&self) -> f32 {
        self.sink.volume()
    }

    /// Plays wave if paused 
    pub fn play(&self) {
        self.sink.play();
    }

    /// Pause the wave
    pub fn pause(&self) {
        self.sink.pause();
    }

}

/// It is used to simplify the creation of a wave, 
/// it contains a wave configurator which has as 
/// 
/// preset parameters: 
///     the `frequency` at 300., 
///     the `volume` at: 0.5, 
///     and the `speed` at: 1. 
/// 
/// which can be modified through the functions: 
///     `set_freq(value: f32)`, 
///     `set_volume(value: f32)`, 
///     `set_speed(value: f32)`.
/// 
/// Finally, to create the wave you need to call the build_wave function which will create a raw_wave 
/// 
/// and a built wave which will be returned.
/// # Examples
/// ```no_run
/// let sine_wave = WaveCreator::new()
///     .set_freq(250.)
///     .set_volume(0.1)
///     .build_wave(SineWave::new());
/// ```
pub struct WaveCreator {
    wave_configurator: WaveConfigurator
}

impl WaveCreator {
    pub fn new() -> Self {
        Self {
            wave_configurator: WaveConfigurator::new(300., 0.5, 1.),
        }
    }

    /// Set wave freq (default is 300.)
    pub fn set_freq(&mut self, value: f32) -> &mut Self {
        self.wave_configurator.freq = value;
        self
    }

    /// Set wave volume (default is 0.5)
    pub fn set_volume(&mut self, value: f32) -> &mut Self {
        self.wave_configurator.volume = value;
        self
    }

    /// Set wave speed (default is 1.)
    pub fn set_speed(&mut self, value: f32) -> &mut Self {
        self.wave_configurator.speed = value;
        self
    }

    /// Build the finished wave
    pub fn build_wave<T>(&self, wave_type: T) -> BuildedWave
        where T: Wave + Send + Clone + 'static
    {
        let raw_wave = RawWave::new(
            self.wave_configurator,
            wave_type,
        );

        WaveBuilder::build(raw_wave)
    }
}

//
// -------------------- Defaults wave types --------------------
/// Square Wave
#[derive(Clone, Copy)]
pub struct SquareWave { 
    phase: f32
}

impl SquareWave {
    /// Create new Square wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for SquareWave {
    fn logic(&mut self, freq: f32) -> f32 {
        let result = if self.phase < 0.5 { 1.0 } else { -1.0 };
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}

/// Sawtooth Wave
#[derive(Clone, Copy)]
pub struct SawtoothWave { 
    phase: f32
}

impl SawtoothWave {
    /// Create new Sawtooth Wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for SawtoothWave {
    fn logic(&mut self, freq: f32) -> f32 { 
        let result = self.phase * 2.0 - 1.0;
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}

/// Triangle wave
#[derive(Clone, Copy)]
pub struct TriangleWave { 
    phase: f32
}

impl TriangleWave {
    /// Create new Triangle Wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for TriangleWave {
    fn logic(&mut self, freq: f32) -> f32 {
        let result = if self.phase < 0.5 {
            self.phase * 4.0 - 1.0
        } else {
            -(self.phase * 4.0 - 3.0)
        };
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}

/// Sine wave
#[derive(Clone, Copy)]
pub struct SineWave { 
    phase: f32
}

impl SineWave {
    /// Create new Sine Wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for SineWave {
    fn logic(&mut self, freq: f32) -> f32 { 
        let result = (self.phase * 2.0 * std::f32::consts::PI).sin();
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}

/// SemiTriangle wave
#[derive(Clone, Copy)]
pub struct SemiTriangleWave { 
    phase: f32
}

impl SemiTriangleWave {
    /// Create new SemiTriangle Wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for SemiTriangleWave {
    fn logic(&mut self, freq: f32) -> f32 { 
        let result = if self.phase <= 0.25 {
            self.phase * 8.0 - 1.0
        } else if self.phase <= 0.5 {
            1.0 - (self.phase - 0.25) * 4.0
        } else if self.phase <= 0.75 {
            (self.phase - 0.5) * 4.0
        } else {
            1.0 - ((self.phase - 0.75) * 8.0)
        };
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}

/// StepSquare wave
#[derive(Clone, Copy)]
pub struct StepSquareWave { 
    phase: f32
}

impl StepSquareWave {
    /// Create new StepSquare wave
    pub fn new() -> Self {
        Self { phase: 0. }
    }
}

impl Wave for StepSquareWave {
    fn logic(&mut self, freq: f32) -> f32 { 
        let result = if self.phase <= 0.25 {
            -1.0
        } else if self.phase <= 0.5 {
            0.0
        } else if self.phase <= 0.75 {
            1.0
        } else {
            0.0
        };
        self.phase = (self.phase + freq / SAMPLE_RATE as f32) % 1.0;

        return result;
    }
}