{-# LANGUAGE NoImplicitPrelude #-}
module Synthesizer.Plain.Filter.Delay (
   phaser,
   plane,

   -- for testing
   propAll,
   ) where

import qualified Synthesizer.Plain.Filter.NonRecursive as FiltNR
import qualified Synthesizer.Plain.Displacement as Syn
import qualified Synthesizer.Plain.Control as Ctrl
import qualified Synthesizer.Plain.Noise   as Noise
import System.Random (randomRs, mkStdGen, )

import qualified Algebra.Module    as Module
import qualified Algebra.RealField as RealField

import qualified Synthesizer.Plain.Interpolation as Interpolation

import qualified Synthesizer.Plain.Filter.Delay.ST    as DelayST
import qualified Synthesizer.Plain.Filter.Delay.List  as DelayList
import qualified Synthesizer.Plain.Filter.Delay.Block as DelayBlock

import NumericPrelude.Numeric
import NumericPrelude.Base


phaser :: (Module.C a v, RealField.C a) => a -> [a] -> [v] -> [v]
phaser :: forall a v. (C a v, C a) => a -> [a] -> [v] -> [v]
phaser a
maxDelay [a]
ts [v]
xs =
   a -> [v] -> [v]
forall a v. C a v => a -> T v -> T v
FiltNR.amplifyVector (a
0.5 a -> a -> a
forall a. a -> a -> a
`asTypeOf` [a] -> a
forall a. HasCallStack => [a] -> a
head [a]
ts)
      ([v] -> [v] -> [v]
forall v. C v => T v -> T v -> T v
Syn.mix [v]
xs
          (T a v -> Int -> [a] -> [v] -> [v]
forall a v. (C a, C v) => T a v -> Int -> T a -> T v -> T v
DelayBlock.modulated T a v
forall t y. T t y
Interpolation.constant (a -> Int
forall b. C b => a -> b
forall a b. (C a, C b) => a -> b
ceiling a
maxDelay) [a]
ts [v]
xs))


plane :: Double -> [Double]
plane :: Double -> [Double]
plane Double
sampleRate =
   let maxDelay :: Double
maxDelay = Double
500
   in  Double -> [Double] -> [Double] -> [Double]
forall a v. (C a v, C a) => a -> [a] -> [v] -> [v]
phaser
          Double
maxDelay
          ((Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double
maxDelayDouble -> Double -> Double
forall a. C a => a -> a -> a
-)
               (Double -> Double -> [Double]
forall y. C y => y -> y -> T y
Ctrl.exponential2 (Double
10Double -> Double -> Double
forall a. C a => a -> a -> a
*Double
sampleRate) Double
maxDelay))
          [Double]
forall y. (C y, Random y) => T y
Noise.white


-- move to test suite ***
propSingle :: Interpolation.T Double Double -> [Bool]
propSingle :: T Double Double -> [Bool]
propSingle T Double Double
ip =
   let maxDelay :: Int
maxDelay = (Int
5::Int)
       xs :: [Double]
xs = (Double, Double) -> StdGen -> [Double]
forall g. RandomGen g => (Double, Double) -> g -> [Double]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (-Double
1,Double
1) (Int -> StdGen
mkStdGen Int
1037)
       ts :: [Double]
ts = Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
20 ((Double, Double) -> StdGen -> [Double]
forall g. RandomGen g => (Double, Double) -> g -> [Double]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
randomRs (Double
0, Int -> Double
forall a b. (C a, C b) => a -> b
fromIntegral Int
maxDelay) (Int -> StdGen
mkStdGen Int
2330))
       pm0 :: [Double]
pm0 = T Double Double -> Int -> [Double] -> [Double] -> [Double]
forall a v. (C a, C v) => T a v -> Int -> T a -> T v -> T v
DelayST.modulated      T Double Double
ip Int
maxDelay [Double]
ts [Double]
xs
       pm1 :: [Double]
pm1 = T Double Double -> Int -> [Double] -> [Double] -> [Double]
forall a v. (C a, C v) => T a v -> Int -> T a -> T v -> T v
DelayList.modulatedRev T Double Double
ip Int
maxDelay [Double]
ts [Double]
xs
       pm2 :: [Double]
pm2 = T Double Double -> Int -> [Double] -> [Double] -> [Double]
forall a v. (C a, C v) => T a v -> Int -> T a -> T v -> T v
DelayList.modulated    T Double Double
ip Int
maxDelay [Double]
ts [Double]
xs
       pm3 :: [Double]
pm3 = T Double Double -> Int -> [Double] -> [Double] -> [Double]
forall a v. (C a, C v) => T a v -> Int -> T a -> T v -> T v
DelayBlock.modulated   T Double Double
ip Int
maxDelay [Double]
ts [Double]
xs
       approx :: a -> a -> Bool
approx a
x a
y = a -> a
forall a. C a => a -> a
abs (a
xa -> a -> a
forall a. C a => a -> a -> a
-a
y) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
1e-10
       -- equal as = and (zipWith (==) as (tail as))
       -- equal [pm0, pm1 {-, pm2-}]
   in  [[Double]
pm0[Double] -> [Double] -> Bool
forall a. Eq a => a -> a -> Bool
==[Double]
pm1, [Double]
pm2[Double] -> [Double] -> Bool
forall a. Eq a => a -> a -> Bool
==[Double]
pm3, [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((Double -> Double -> Bool) -> [Double] -> [Double] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Double -> Double -> Bool
forall {a}. (Ord a, C a, C a) => a -> a -> Bool
approx [Double]
pm1 [Double]
pm2)]

{- |
The test for constant interpolation will fail,
due to different point of views in forward and backward interpolation.
-}
propAll :: [[Bool]]
propAll :: [[Bool]]
propAll =
   (T Double Double -> [Bool]) -> [T Double Double] -> [[Bool]]
forall a b. (a -> b) -> [a] -> [b]
map T Double Double -> [Bool]
propSingle ([T Double Double] -> [[Bool]]) -> [T Double Double] -> [[Bool]]
forall a b. (a -> b) -> a -> b
$
      T Double Double
forall t y. T t y
Interpolation.constant T Double Double -> [T Double Double] -> [T Double Double]
forall a. a -> [a] -> [a]
:
      T Double Double
forall t y. C t y => T t y
Interpolation.linear T Double Double -> [T Double Double] -> [T Double Double]
forall a. a -> [a] -> [a]
:
      T Double Double
forall t y. (C t, C t y) => T t y
Interpolation.cubic T Double Double -> [T Double Double] -> [T Double Double]
forall a. a -> [a] -> [a]
:
      []