{-# LANGUAGE UnicodeSyntax #-} -- | FIXME module Codec.Audio.WavPack.Entropy ( EntropyData(..) , clearMedian , getMedian0 , getMedian1 , getMedian2 , incMedian0 , decMedian0 , incMedian1 , decMedian1 , incMedian2 , decMedian2 ) where import Control.Monad.ST import Control.Monad.Unicode import Data.Bits import Data.STRef import Data.Word import Prelude.Unicode -- | FIXME data EntropyData s = EntropyData { -- | Median log2 values for a channel. edMedian0 ∷ !(STRef s Word32) , edMedian1 ∷ !(STRef s Word32) , edMedian2 ∷ !(STRef s Word32) -- | FIXME , edSlowLevel ∷ !(STRef s Word32) -- | FIXME , edErrorLimit ∷ !(STRef s Word32) } clearMedian ∷ EntropyData s → ST s () clearMedian e = writeSTRef (edMedian0 e) 0 ≫ writeSTRef (edMedian1 e) 0 ≫ writeSTRef (edMedian2 e) 0 -- | The time constant of the 3 median level breakpoints div0, div1, div2 ∷ Word32 div0 = 128 -- 5/ 7 of samples div1 = 64 -- 10/ 49 of samples div2 = 32 -- 20/343 of samples -- | Retrieve the specified median breakpoint (without frac; min = 1) getMedian0, getMedian1, getMedian2 ∷ EntropyData s → ST s Word32 getMedian0 = fmap ((`shiftR` 4) ∘ (+ 1)) ∘ readSTRef ∘ edMedian0 getMedian1 = fmap ((`shiftR` 4) ∘ (+ 1)) ∘ readSTRef ∘ edMedian1 getMedian2 = fmap ((`shiftR` 4) ∘ (+ 1)) ∘ readSTRef ∘ edMedian2 -- | Update the specified median breakpoints. Note that the median is -- incremented when the sample is higher than the median, else -- decremented. They are designed so that the median will never drop -- below 1 and the value is essentially stationary if there are 2 -- increments for every 5 decrements. incMedian0, decMedian0, incMedian1, decMedian1, incMedian2, decMedian2 ∷ EntropyData s → ST s () incMedian0 = flip modifySTRef (\x → x + ((x + div0 ) `div` div0) ⋅ 5) ∘ edMedian0 decMedian0 = flip modifySTRef (\x → x - ((x + (div0-2)) `div` div0) ⋅ 2) ∘ edMedian0 incMedian1 = flip modifySTRef (\x → x + ((x + div1 ) `div` div1) ⋅ 5) ∘ edMedian1 decMedian1 = flip modifySTRef (\x → x - ((x + (div1-2)) `div` div1) ⋅ 2) ∘ edMedian1 incMedian2 = flip modifySTRef (\x → x + ((x + div2 ) `div` div2) ⋅ 5) ∘ edMedian2 decMedian2 = flip modifySTRef (\x → x - ((x + (div2-2)) `div` div2) ⋅ 2) ∘ edMedian2