timbre 0.3.0

A library for audio processing with composable effects.
Documentation
use crate::{AudioSource, ReadResult};
use tracing::instrument;

/// An [`AudioSource`](crate::AudioSource) that generates a sine wave.
///
/// # Examples
/// ```
/// # use timbre::generators::SineWave;
/// let sin = SineWave::new(1.0, 440.0);
/// ```
#[derive(Clone)]
pub struct SineWave {
    amplitude: f32,
    phase: f32,
    frequency: f32,
}

impl SineWave {
    /// Construct a new sine wave generator with the given amplitude and frequency.
    ///
    /// # Arguments
    ///
    /// * `amplitude` -- The peak value of samples generated by the generator.
    /// * `frequency` -- The frequency of the wave generated, in Hz.
    pub fn new(amplitude: f32, frequency: f32) -> Self {
        SineWave {
            amplitude,
            phase: 0.0,
            frequency,
        }
    }
}

impl AudioSource for SineWave {
    #[instrument(name = "SineWave::read", skip(self, buffer))]
    fn read(&mut self, buffer: &mut crate::core::AudioBuffer) -> crate::ReadResult {
        let increment =
            std::f32::consts::PI * 2.0 * self.frequency / buffer.format.sample_rate as f32;

        let channels = buffer.format.channels as usize;
        let frames = buffer.samples.len() / channels;

        for i in 0..frames {
            let amplitude = self.amplitude * self.phase.sin();
            for channel in 0..channels as usize {
                buffer.samples[i * channels + channel] = amplitude;
            }
            self.phase += increment;
        }

        ReadResult::good(buffer.samples.len())
    }
}