{-# LANGUAGE NoImplicitPrelude #-}
{- | Noise and random processes. -}
module Synthesizer.Plain.Noise where

import qualified Synthesizer.Plain.Signal as Sig

import qualified Algebra.RealRing              as RealRing
import qualified Algebra.Ring                  as Ring

import System.Random (Random, RandomGen, randomRs, mkStdGen, )

import Data.List.HT (sliceVertical, )

import NumericPrelude.Numeric
import NumericPrelude.Base


{-|
Deterministic white noise, uniformly distributed between -1 and 1.
That is, variance is 1\/3.
-}
white :: (Ring.C y, Random y) =>
   Sig.T y
white :: forall y. (C y, Random y) => T y
white = StdGen -> T y
forall y g. (C y, Random y, RandomGen g) => g -> T y
whiteGen (Int -> StdGen
mkStdGen Int
12354)

whiteGen :: (Ring.C y, Random y, RandomGen g) =>
   g -> Sig.T y
whiteGen :: forall y g. (C y, Random y, RandomGen g) => g -> T y
whiteGen = (y, y) -> g -> [y]
forall g. RandomGen g => (y, y) -> g -> [y]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (-y
1,y
1)

{- |
Approximates normal distribution with variance 1
by a quadratic B-spline distribution.
-}
whiteQuadraticBSplineGen :: (Ring.C y, Random y, RandomGen g) =>
   g -> Sig.T y
whiteQuadraticBSplineGen :: forall y g. (C y, Random y, RandomGen g) => g -> T y
whiteQuadraticBSplineGen =
   ([y] -> y) -> [[y]] -> [y]
forall a b. (a -> b) -> [a] -> [b]
map [y] -> y
forall a. C a => [a] -> a
sum ([[y]] -> [y]) -> (g -> [[y]]) -> g -> [y]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [y] -> [[y]]
forall a. Int -> [a] -> [[a]]
sliceVertical Int
3 ([y] -> [[y]]) -> (g -> [y]) -> g -> [[y]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (y, y) -> g -> [y]
forall g. RandomGen g => (y, y) -> g -> [y]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (-y
1,y
1)


randomPeeks :: (RealRing.C y, Random y) =>
      Sig.T y    {- ^ momentary densities, @p@ means that there is about one peak
                      in the time range of @1\/p@ samples -}
   -> Sig.T Bool {- ^ Every occurence of 'True' represents a peak. -}
randomPeeks :: forall y. (C y, Random y) => T y -> T Bool
randomPeeks =
   StdGen -> T y -> T Bool
forall y g. (C y, Random y, RandomGen g) => g -> T y -> T Bool
randomPeeksGen (Int -> StdGen
mkStdGen Int
876)

randomPeeksGen :: (RealRing.C y, Random y, RandomGen g) =>
      g
   -> Sig.T y
   -> Sig.T Bool
randomPeeksGen :: forall y g. (C y, Random y, RandomGen g) => g -> T y -> T Bool
randomPeeksGen =
   (y -> y -> Bool) -> [y] -> [y] -> T Bool
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith y -> y -> Bool
forall a. Ord a => a -> a -> Bool
(<) ([y] -> [y] -> T Bool) -> (g -> [y]) -> g -> [y] -> T Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (y, y) -> g -> [y]
forall g. RandomGen g => (y, y) -> g -> [y]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (y
0,y
1)