use rodio::source::Source;
use rodio::{OutputStream, Sink, OutputStreamHandle};
use std::time::Duration;
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 {
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)]
pub struct WaveConfigurator {
freq: f32,
volume: f32,
speed: f32,
}
impl WaveConfigurator {
pub fn new(freq: f32, volume: f32, speed: f32) -> Self {
Self {
freq,
volume,
speed,
}
}
}
pub struct BuildedWave {
sink: Sink,
_stream: OutputStream,
_handle: OutputStreamHandle,
}
impl BuildedWave {
pub fn new(sink: Sink, _stream: OutputStream, _handle: OutputStreamHandle) -> Self {
Self {
sink,
_stream,
_handle,
}
}
pub fn set_volume(&mut self, value: f32) {
self.sink.set_volume(value);
}
pub fn set_speed(&mut self, value: f32) {
let mut speed = value;
if speed <= 0. {
speed = 0.1
}
self.sink.set_speed(speed);
}
pub fn speed(&self) -> f32 {
self.sink.speed()
}
pub fn volume(&self) -> f32 {
self.sink.volume()
}
pub fn play(&self) {
self.sink.play();
}
pub fn pause(&self) {
self.sink.pause();
}
}
pub struct WaveCreator {
wave_configurator: WaveConfigurator
}
impl WaveCreator {
pub fn new() -> Self {
Self {
wave_configurator: WaveConfigurator::new(300., 0.5, 1.),
}
}
pub fn set_freq(&mut self, value: f32) -> &mut Self {
self.wave_configurator.freq = value;
self
}
pub fn set_volume(&mut self, value: f32) -> &mut Self {
self.wave_configurator.volume = value;
self
}
pub fn set_speed(&mut self, value: f32) -> &mut Self {
self.wave_configurator.speed = value;
self
}
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)
}
}
#[derive(Clone, Copy)]
pub struct SquareWave {
phase: f32
}
impl SquareWave {
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;
}
}
#[derive(Clone, Copy)]
pub struct SawtoothWave {
phase: f32
}
impl SawtoothWave {
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;
}
}
#[derive(Clone, Copy)]
pub struct TriangleWave {
phase: f32
}
impl TriangleWave {
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;
}
}
#[derive(Clone, Copy)]
pub struct SineWave {
phase: f32
}
impl SineWave {
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;
}
}
#[derive(Clone, Copy)]
pub struct SemiTriangleWave {
phase: f32
}
impl SemiTriangleWave {
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;
}
}
#[derive(Clone, Copy)]
pub struct StepSquareWave {
phase: f32
}
impl StepSquareWave {
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;
}
}