module Synthesizer.Oscillator
  ( sawToothOscillator
  , sineOscillator
  ) where

import Data.Fixed            (mod')
import Numeric               (Floating (pi, sin))
import Prelude               hiding (cycle)
import Synthesizer.Structure (Frequency, SamplingRate)

type WaveFunction = Double -> Double

-- | Create a saw tooth oscillator with a given frequency
sawToothOscillator :: Frequency -> SamplingRate -> [Double]
sawToothOscillator :: Frequency -> SamplingRate -> [Frequency]
sawToothOscillator Frequency
frequency = WaveFunction -> Frequency -> SamplingRate -> [Frequency]
oscillator WaveFunction
sawTooth Frequency
frequency
  where
    sawTooth :: WaveFunction
    sawTooth :: WaveFunction
sawTooth Frequency
x = Frequency
x Frequency -> WaveFunction
forall a. Real a => a -> a -> a
`mod'` Frequency
frequency

-- | Create a sine wave oscillator with a given frequency
sineOscillator :: Frequency -> SamplingRate -> [Double]
sineOscillator :: Frequency -> SamplingRate -> [Frequency]
sineOscillator = WaveFunction -> Frequency -> SamplingRate -> [Frequency]
oscillator WaveFunction
forall a. Floating a => a -> a
sin

-- | Create a oscillator based on some wave function and a frequency
oscillator :: WaveFunction -> Frequency -> SamplingRate -> [Double]
oscillator :: WaveFunction -> Frequency -> SamplingRate -> [Frequency]
oscillator WaveFunction
waveFunction Frequency
frequency SamplingRate
samplingRate = WaveFunction
waveFunction WaveFunction -> [Frequency] -> [Frequency]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Frequency
0, Frequency
delta..]
  where
    sr :: Double
    sr :: Frequency
sr = SamplingRate -> Frequency
forall a b. (Integral a, Num b) => a -> b
fromIntegral SamplingRate
samplingRate
    cycle :: Double
    cycle :: Frequency
cycle = Frequency
2 Frequency -> WaveFunction
forall a. Num a => a -> a -> a
* Frequency
forall a. Floating a => a
pi
    delta :: Double
    delta :: Frequency
delta = (Frequency
frequency Frequency -> WaveFunction
forall a. Num a => a -> a -> a
* Frequency
cycle) Frequency -> WaveFunction
forall a. Fractional a => a -> a -> a
/ Frequency
sr