9 module Codec.Audio.WavPack.Words
13 import Codec.Audio.WavPack.Entropy
14 import Codec.Audio.WavPack.Internal
16 import Data.Bitstream.Generic (Bitstream)
17 import qualified Data.Bitstream.Generic as B
19 import qualified Data.Vector.Generic as GV
20 import qualified Data.Vector.Generic.Mutable as MV
21 import Data.Vector.Generic.New (New)
22 import qualified Data.Vector.Generic.New as New
24 import Prelude.Unicode
29 wdBitrateDelta ∷ !(Word32, Word32)
30 , wdBitrateAcc ∷ !(Word32, Word32)
31 , wdPendingData ∷ !Word32
32 , wdHoldingOne ∷ !Word32
33 , wdZeroesAcc ∷ !Word32
34 , wdHoldingZero ∷ !Bool
35 , wdPendingCount ∷ !Int
36 , wdEntropyData ∷ !(EntropyData, EntropyData)
40 -- | This is an optimized version of 'getWord' that is used for
41 -- lossless only ('edErrorLimit' ≡ 0). Also, rather than obtaining a
42 -- single sample, it can be used to obtain an entire buffer of either
43 -- mono or stereo samples.
44 getWordsLossless ∷ ∀bs n v. (Bitstream bs, Integral n, GV.Vector v Int32)
45 ⇒ Bool -- ^ Is the stream monaural?
47 → bs -- ^ WV bitstream.
48 → n -- ^ Number of samples to get.
49 → (# WordsData, bs, v Int32 #)
50 {-# INLINEABLE getWordsLossless #-}
51 getWordsLossless isMono w0 bs0 nSamples0
52 = let v0 = New.create $ MV.new $ fromIntegral nSamples
55 v2 = GV.new $ New.take (fromIntegral n1) v1
60 {-# INLINE nSamples #-}
69 → (# WordsData, bs, n, New v Int32 #)
72 | n ≥ nSamples = (# w, bs, n, v #)
77 c | n `rem` 2 ≡ 0 = fst $ wdEntropyData w
78 | otherwise = snd $ wdEntropyData w
80 -- | Read a single unsigned value from the specified bitstream with a
81 -- value from 0 to maxCode. If there are exactly a power of two number
82 -- of possible codes then this will read a fixed number of bits;
83 -- otherwise it reads the minimum number of bits and then determines
84 -- whether another bit is needed to define the code.
85 readCode ∷ Bitstream bs ⇒ bs → Word32 → (# Word32, bs #)
86 {-# INLINEABLE readCode #-}
87 readCode bs 0 = (# 0, bs #)
88 readCode bs 1 = (# b2n (B.head bs), B.tail bs #)
90 = let !bitCount = countBits maxCode
91 !extras = bit bitCount - maxCode - 1
92 !code = B.toBits (B.take (bitCount - 1) bs)
93 (# code', bitCount' #)
94 = if code ≥ extras then
97 + b2n (bs B.!! bitCount)
100 (# code, bitCount - 1 #)
101 !bs' = B.drop bitCount' bs