packages feed

synthesizer-core-0.2: src/Test/Sound/Synthesizer/Plain/Wave.hs

module Test.Sound.Synthesizer.Plain.Wave (Ring, ringWave, tests) where

import qualified Synthesizer.Basic.Wave       as Wave
import qualified Synthesizer.Basic.Phase      as Phase

import Test.QuickCheck (test, Arbitrary(..), elements, oneof, choose, {- Property, (==>), -} )
-- import Test.Utility

import qualified Number.NonNegative       as NonNeg

import qualified Algebra.RealTranscendental    as RealTrans
-- import qualified Algebra.Module                as Module
-- import qualified Algebra.RealField             as RealField
-- import qualified Algebra.Field                 as Field
import qualified Algebra.Ring                  as Ring
import qualified Algebra.Additive              as Additive

import Control.Monad (liftM, liftM2, )
import System.Random (Random)


import NumericPrelude
import PreludeBase
import Prelude ()




data Ring a = Ring {ringName :: String, ringWave :: Wave.T a a}

instance Show (Ring a) where
   show = ringName

instance (Ord a, Ring.C a) => Arbitrary (Ring a) where
   arbitrary = elements $
      Ring "saw"      Wave.saw :
      Ring "square"   Wave.square :
      Ring "triangle" Wave.triangle :
      []
   coarbitrary = undefined




data ZeroDCOffset a = ZeroDCOffset {zdcName :: String, zdcWave :: Wave.T a a}

instance Show (ZeroDCOffset a) where
   show = zdcName

instance (RealTrans.C a, Random a) => Arbitrary (ZeroDCOffset a) where
   arbitrary =
      let cons n w = return (ZeroDCOffset n w)
      in  oneof $
            cons "sine"     Wave.sine :
            cons "saw"      Wave.saw :
            cons "square"   Wave.square :
            cons "triangle" Wave.triangle :
            liftM
               (ZeroDCOffset "squareBalanced" . Wave.squareBalanced)
               (choose (negate one, one)) :
            liftM2
               (\w r -> ZeroDCOffset "trapezoidBalanced" (Wave.trapezoidBalanced w r))
               (choose (zero, one))
               (choose (negate one, one)) :
            []
   coarbitrary = undefined


zeroDCOffset :: ZeroDCOffset Double -> NonNeg.Int -> Bool
zeroDCOffset w periodIntNN =
   let periodInt = 100 + NonNeg.toNumber periodIntNN
       period    = fromIntegral periodInt
       xs = take periodInt $ map Phase.fromRepresentative $
            map (/period) $ iterate (1+) 0.5
   in  abs (sum (map (Wave.apply (zdcWave w)) xs))  <  period / fromInteger 100


tests :: [(String, IO ())]
tests =
   ("zeroDCOffset",  test zeroDCOffset) :
   []