module Sound.Analysis.Spear.PTPF.Reduce where
import Sound.Analysis.Spear.PTPF
type N_Reduction_F = ((Node,Node,Node) -> Bool)
n_reduction :: N_Reduction_F -> [Node] -> [Node]
n_reduction f n =
case n of
n1:n2:n3:n' -> if f (n1,n2,n3)
then n_reduction f (n1:n3:n')
else n1 : n_reduction f (n2:n3:n')
_ -> n
s_reduction :: N_Reduction_F -> Seq -> Seq
s_reduction f (Seq i s e _ d) =
let d' = n_reduction f d
in Seq i s e (length d') d'
cps_to_fmidi :: Floating a => a -> a
cps_to_fmidi a = (logBase 2 (a * (1 / 440)) * 12) + 69
ampDb :: Floating a => a -> a
ampDb a = logBase 10 a * 20
n_gradient :: Node -> Node -> (Double,Double)
n_gradient (Node _ t1 f1 a1) (Node _ t2 f2 a2) =
let dt = t2 t1
in ((cps_to_fmidi f2 cps_to_fmidi f1) / dt
,(ampDb a2 ampDb a1) / dt)
s_reduction_gradient :: (Double,Double) -> Seq -> Seq
s_reduction_gradient (p,q) =
let f (n1,n2,n3) = let (a,b) = n_gradient n1 n2
(c,d) = n_gradient n1 n3
in abs (a c) < p && abs (b d) < q
in s_reduction f
p_reduction_gradient :: (Double,Double) -> PTPF -> PTPF
p_reduction_gradient g (PTPF n s) = PTPF n (map (s_reduction_gradient g) s)