use crate::prelude::*;
use std::marker::PhantomData;
mod buffer;
pub mod poly;
pub mod unison;
pub use buffer::{LoopBuf, OnceBuf};
pub use poly::Polyphony;
pub use unison as uni;
#[derive(Clone, Copy, Debug, Default)]
pub struct CurvePlayer<S: smp::Sample, C: Map<Input = unt::Val, Output = f64>> {
pub curve: C,
phantom: PhantomData<S>,
}
impl<S: smp::Sample, C: Map<Input = unt::Val, Output = f64>> CurvePlayer<S, C> {
pub const fn new(curve: C) -> Self {
Self {
curve,
phantom: PhantomData,
}
}
}
impl<S: smp::Sample, C: Map<Input = unt::Val, Output = f64>> Map for CurvePlayer<S, C> {
type Input = unt::Val;
type Output = S;
fn eval(&self, val: unt::Val) -> S {
S::from_val(self.curve.eval(val))
}
}
#[derive(Clone, Debug)]
pub struct OnceCurve<C: Map<Input = unt::Val>>
where
C::Output: smp::Sample,
{
map: C,
elapsed: unt::Time,
time: unt::Time,
}
impl<C: Map<Input = unt::Val>> OnceCurve<C>
where
C::Output: smp::Sample,
{
pub const fn new_curve(map: C, time: unt::Time) -> Self {
Self {
map,
elapsed: unt::Time::ZERO,
time,
}
}
pub const fn map(&self) -> &C {
&self.map
}
pub fn map_mut(&mut self) -> &mut C {
&mut self.map
}
pub const fn elapsed(&self) -> unt::Time {
self.elapsed
}
pub const fn time(&self) -> unt::Time {
self.time
}
pub fn val(&self) -> unt::Val {
unt::Val::new(self.elapsed / self.time)
}
}
impl<C: Map<Input = unt::Val>> Signal for OnceCurve<C>
where
C::Output: smp::Sample,
{
type Sample = C::Output;
fn get(&self) -> C::Output {
self.map.eval(self.val())
}
}
impl<C: Map<Input = unt::Val>> SignalMut for OnceCurve<C>
where
C::Output: smp::Sample,
{
fn advance(&mut self) {
self.elapsed.advance();
if self.elapsed > self.time {
self.elapsed = self.time;
}
}
fn retrigger(&mut self) {
self.elapsed = unt::Time::ZERO;
}
}
impl<C: Map<Input = unt::Val>> Base for OnceCurve<C>
where
C::Output: smp::Sample,
{
impl_base!();
}
impl<C: Map<Input = unt::Val>> Done for OnceCurve<C>
where
C::Output: smp::Sample,
{
fn is_done(&self) -> bool {
self.elapsed == self.time
}
}
impl<C: Map<Input = unt::Val>> Stop for OnceCurve<C>
where
C::Output: smp::Sample,
{
fn stop(&mut self) {
self.elapsed = self.time;
}
}
impl<C: Map<Input = unt::Val>> Panic for OnceCurve<C>
where
C::Output: smp::Sample,
{
fn panic(&mut self) {
self.stop();
}
}
pub type Once<S, C> = OnceCurve<CurvePlayer<S, C>>;
impl<S: smp::Sample, C: Map<Input = unt::Val, Output = f64>> gen::Once<S, C> {
pub const fn new(curve: C, time: unt::Time) -> Self {
Self::new_curve(CurvePlayer::new(curve), time)
}
pub const fn curve(&self) -> &C {
&self.map().curve
}
pub fn curve_mut(&mut self) -> &mut C {
&mut self.map_mut().curve
}
}
#[derive(Clone, Debug, Default)]
pub struct LoopCurve<C: Map<Input = unt::Val>>
where
C::Output: smp::Sample,
{
map: C,
val: unt::Val,
freq: unt::Freq,
}
impl<C: Map<Input = unt::Val>> LoopCurve<C>
where
C::Output: smp::Sample,
{
pub const fn new_curve_phase(map: C, freq: unt::Freq, phase: unt::Val) -> Self {
Self {
map,
freq,
val: phase,
}
}
pub const fn new_curve(map: C, freq: unt::Freq) -> Self {
Self::new_curve_phase(map, freq, unt::Val::ZERO)
}
pub const fn map(&self) -> &C {
&self.map
}
pub fn map_mut(&mut self) -> &mut C {
&mut self.map
}
pub const fn val(&self) -> unt::Val {
self.val
}
pub fn val_mut(&mut self) -> &mut unt::Val {
&mut self.val
}
pub const fn freq(&self) -> unt::Freq {
self.freq
}
pub fn freq_mut(&mut self) -> &mut unt::Freq {
&mut self.freq
}
}
impl<C: Map<Input = unt::Val>> Signal for LoopCurve<C>
where
C::Output: smp::Sample,
{
type Sample = C::Output;
fn get(&self) -> C::Output {
self.map.eval(self.val())
}
}
impl<C: Map<Input = unt::Val>> SignalMut for LoopCurve<C>
where
C::Output: smp::Sample,
{
fn advance(&mut self) {
self.val.advance_freq(self.freq());
}
fn retrigger(&mut self) {
self.val = unt::Val::ZERO;
}
}
impl<C: Map<Input = unt::Val>> Frequency for LoopCurve<C>
where
C::Output: smp::Sample,
{
fn freq(&self) -> unt::Freq {
self.freq
}
fn freq_mut(&mut self) -> &mut unt::Freq {
&mut self.freq
}
}
impl<C: Map<Input = unt::Val>> Base for LoopCurve<C>
where
C::Output: smp::Sample,
{
impl_base!();
}
pub type Loop<S, C> = LoopCurve<CurvePlayer<S, C>>;
impl<S: smp::Sample, C: Map<Input = unt::Val, Output = f64>> gen::Loop<S, C> {
pub const fn new_phase(curve: C, freq: unt::Freq, phase: unt::Val) -> Self {
Self::new_curve_phase(CurvePlayer::new(curve), freq, phase)
}
pub fn new_rand_phase(curve: C, freq: unt::Freq) -> Self {
use rand::Rng;
Self::new_phase(curve, freq, rand::thread_rng().gen())
}
pub const fn new(curve: C, freq: unt::Freq) -> Self {
Self::new_phase(curve, freq, unt::Val::ZERO)
}
pub const fn curve(&self) -> &C {
&self.map().curve
}
pub fn curve_mut(&mut self) -> &mut C {
&mut self.map_mut().curve
}
}
#[derive(Clone, Copy, Debug)]
pub struct NoiseGen<S: smp::Sample> {
current: S,
}
impl<S: smp::Sample> Default for NoiseGen<S> {
fn default() -> Self {
Self { current: S::rand() }
}
}
impl<S: smp::Sample> NoiseGen<S> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl<S: smp::Sample> Signal for NoiseGen<S> {
type Sample = S;
fn get(&self) -> Self::Sample {
self.current
}
}
impl<S: smp::Sample> SignalMut for NoiseGen<S> {
fn advance(&mut self) {
self.retrigger();
}
fn retrigger(&mut self) {
self.current = S::rand();
}
}
impl<S: smp::Sample> Base for NoiseGen<S> {
impl_base!();
}