]> gitweb @ CieloNegro.org - wavpack.git/blob - Codec/Audio/WavPack/Entropy.hs
f031d118d112342b25bf005b2e13234a04d0a502
[wavpack.git] / Codec / Audio / WavPack / Entropy.hs
1 {-# LANGUAGE
2     UnicodeSyntax
3   #-}
4 -- | FIXME
5 module Codec.Audio.WavPack.Entropy
6     ( EntropyData(..)
7
8     , clearMedian
9
10     , getMedian0
11     , getMedian1
12     , getMedian2
13
14     , incMedian0
15     , decMedian0
16     , incMedian1
17     , decMedian1
18     , incMedian2
19     , decMedian2
20     )
21     where
22 import Data.Bits
23 import Data.Word
24 import Prelude.Unicode
25
26 -- | FIXME
27 data EntropyData
28     = EntropyData {
29         -- | Median log2 values for a channel.
30         edMedian0    ∷ !Word32
31       , edMedian1    ∷ !Word32
32       , edMedian2    ∷ !Word32
33         -- | FIXME
34       , edSlowLevel  ∷ !Word32
35         -- | FIXME
36       , edErrorLimit ∷ !Word32
37       }
38     deriving (Eq, Show)
39
40 clearMedian ∷ EntropyData → EntropyData
41 {-# INLINE clearMedian #-}
42 clearMedian e = e {
43                   edMedian0 = 0
44                 , edMedian1 = 0
45                 , edMedian2 = 0
46                 }
47
48 -- | The time constant of the 3 median level breakpoints
49 div0, div1, div2 ∷ Word32
50 div0 = 128 --  5/  7 of samples
51 div1 =  64 -- 10/ 49 of samples
52 div2 =  32 -- 20/343 of samples
53
54 -- | Retrieve the specified median breakpoint (without frac; min = 1)
55 getMedian0, getMedian1, getMedian2 ∷ EntropyData → Word32
56 {-# INLINE getMedian0 #-}
57 {-# INLINE getMedian1 #-}
58 {-# INLINE getMedian2 #-}
59 getMedian0 e = (edMedian0 e `shiftR` 4) + 1
60 getMedian1 e = (edMedian1 e `shiftR` 4) + 1
61 getMedian2 e = (edMedian2 e `shiftR` 4) + 1
62
63 -- | Update the specified median breakpoints. Note that the median is
64 -- incremented when the sample is higher than the median, else
65 -- decremented.  They are designed so that the median will never drop
66 -- below 1 and the value is essentially stationary if there are 2
67 -- increments for every 5 decrements.
68 incMedian0, decMedian0, incMedian1, decMedian1, incMedian2, decMedian2 ∷ EntropyData → EntropyData
69 incMedian0 e
70     = e { edMedian0 =
71               edMedian0 e + ((edMedian0 e +  div0   ) `div` div0) ⋅ 5 }
72 decMedian0 e
73     = e { edMedian0 =
74               edMedian0 e - ((edMedian0 e + (div0-2)) `div` div0) ⋅ 2 }
75 incMedian1 e
76     = e { edMedian1 =
77               edMedian1 e + ((edMedian1 e +  div1   ) `div` div1) ⋅ 5 }
78 decMedian1 e
79     = e { edMedian1 =
80               edMedian1 e - ((edMedian1 e + (div1-2)) `div` div1) ⋅ 2 }
81 incMedian2 e
82     = e { edMedian2 =
83               edMedian2 e + ((edMedian2 e +  div2   ) `div` div2) ⋅ 5 }
84 decMedian2 e
85     = e { edMedian2 =
86               edMedian2 e - ((edMedian2 e + (div2-2)) `div` div2) ⋅ 2 }