Use FunDSP crate for beepboops

This commit is contained in:
Alex Page 2022-01-31 18:10:39 -05:00
parent 784e205357
commit 9219b6c475
4 changed files with 142 additions and 76 deletions

View file

@ -1,11 +1,11 @@
use std::{f32::consts::PI, sync::Arc};
use std::sync::Arc;
use cpal::{
traits::{DeviceTrait, HostTrait, StreamTrait},
SampleRate, Stream,
};
use fundsp::prelude::*;
use oddio::{Frames, FramesSignal, Gain, Handle, Mixer, MonoToStereo, Stop};
use rand::Rng;
use super::sound_effects::{SoundEffect, SoundType};
@ -70,43 +70,30 @@ impl SoundOutput {
.map(|_| 0f32)
.collect::<Vec<f32>>(),
SoundType::Tone(freq) => {
if freq == 0 {
return (0..(self.sample_rate.0 as f32 * sound.duration.as_secs_f32())
as usize)
.map(|_| 0f32)
.collect::<Vec<f32>>();
}
let num_harmonics = self.sample_rate.0 / (freq as u32 * 2);
let coefficients = (0..=num_harmonics)
.map(|i| {
if i == 0 {
return 0.0;
}
(i as f32 * 0.5 * PI).sin() * 2.0 / (i as f32 * PI)
})
.collect::<Vec<f32>>();
let scaler = freq as f32 * PI * 2.0 / self.sample_rate.0 as f32;
let mut c = square_hz(freq as f32);
c.reset(Some(self.sample_rate.0 as f64));
(0..(self.sample_rate.0 as f32 * sound.duration.as_secs_f32()) as usize)
.map(|i| {
let temp = scaler * i as f32;
coefficients
.iter()
.enumerate()
.map(|(j, coef)| coef * (j as f32 * temp).cos())
.sum::<f32>()
})
.map(|_| c.get_mono())
.collect::<Vec<f32>>()
}
SoundType::Sweep(start_freq, end_freq) => {
let mut c = lfo(|t| {
lerp(
start_freq as f32,
end_freq as f32,
t * sound.duration.as_secs_f32(),
)
}) >> square();
c.reset(Some(self.sample_rate.0 as f64));
(0..(self.sample_rate.0 as f32 * sound.duration.as_secs_f32()) as usize)
.map(|_| c.get_mono())
.collect::<Vec<f32>>()
}
SoundType::Noise(min, max) => {
let mut c =
(((white() + dc(1.0)) * dc(max as f32 / 2.0)) + dc(min as f32)) >> square();
(0..(self.sample_rate.0 as f32 * sound.duration.as_secs_f32()) as usize)
.map(|i| {
let t = i as f32 / self.sample_rate.0 as f32;
(t * (rand::thread_rng().gen_range(min as f32..max as f32))
* 2.0
* std::f32::consts::PI)
.sin()
.signum()
})
.map(|_| c.get_mono())
.collect::<Vec<f32>>()
}
})
@ -120,7 +107,7 @@ impl SoundOutput {
.control::<oddio::Mixer<_>, _>()
.play(oddio::MonoToStereo::new(oddio::Gain::new(
oddio::FramesSignal::from(samples),
0.20,
0.50,
)))
}
}