module Synthesizer.Basic.WaveSmoothed (
T,
fromFunction,
fromWave,
fromControlledWave,
raise,
amplify,
distort,
apply,
sine,
cosine,
saw,
square,
triangle,
Wave.Harmonic,
Wave.harmonic,
composedHarmonics,
) where
import qualified Synthesizer.Basic.Wave as Wave
import qualified Synthesizer.Basic.Phase as Phase
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Module as Module
import qualified Algebra.Field as Field
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import qualified MathObj.Polynomial as Poly
import qualified Number.Complex as Complex
import NumericPrelude.Numeric
import NumericPrelude.Base
newtype T t y = Cons {decons :: t -> Phase.T t -> y}
fromFunction :: (t -> t -> y) -> (T t y)
fromFunction wave =
Cons (\f p -> wave f (Phase.toRepresentative p))
fromWave ::
(Field.C t, RealRing.C t, Additive.C y) =>
Wave.T t y -> (T t y)
fromWave wave =
fromControlledWaveAux (\f -> if abs f >= 1/2 then zero else wave)
fromControlledWave ::
(Field.C t, RealRing.C t, Additive.C y) =>
(t -> Wave.T t y) -> (T t y)
fromControlledWave wave =
fromControlledWaveAux (\f0 ->
let f = abs f0
in if f >= 1/2
then zero
else wave f)
fromControlledWaveAux :: (t -> Wave.T t y) -> (T t y)
fromControlledWaveAux wave =
Cons (\f p -> Wave.apply (wave f) p)
raise :: (Additive.C y) => y -> T t y -> T t y
raise y = distort (y+)
amplify :: (Ring.C y) => y -> T t y -> T t y
amplify k = distort (k*)
distort :: (y -> z) -> T t y -> T t z
distort g (Cons w) = Cons (\f p -> g (w f p))
apply :: T t y -> (t -> Phase.T t -> y)
apply = decons
instance Additive.C y => Additive.C (T t y) where
zero = Cons (const zero)
(+) (Cons w) (Cons v) = Cons (\f p -> w f p + v f p)
() (Cons w) (Cons v) = Cons (\f p -> w f p v f p)
negate = distort negate
instance Module.C a y => Module.C a (T t y) where
s *> w = distort (s*>) w
sine :: (Trans.C a, RealRing.C a) => T a a
sine = fromWave Wave.sine
cosine :: (Trans.C a, RealRing.C a) => T a a
cosine = fromWave Wave.cosine
saw :: (RealRing.C a, Field.C a) => T a a
saw =
fromControlledWave (\f -> Wave.triangleAsymmetric (2*f1))
square :: (RealRing.C a, Field.C a) => T a a
square =
fromControlledWave (\f -> Wave.trapezoid (12*f))
triangle :: (RealRing.C a, Field.C a) => T a a
triangle = fromWave Wave.triangle
composedHarmonics :: (Trans.C a, RealRing.C a) => [Wave.Harmonic a] -> T a a
composedHarmonics hs =
let c = map (\h -> Complex.fromPolar (Wave.harmonicAmplitude h)
(2*pi * Phase.toRepresentative (Wave.harmonicPhase h))) hs
trunc f =
map snd . takeWhile ((<1/2) . fst) . zip (iterate (abs f +) zero)
in fromControlledWaveAux $ \f ->
Wave.distort
(Complex.imag . Poly.evaluate (Poly.fromCoeffs (trunc f c)))
Wave.helix