X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=wavpack.git;a=blobdiff_plain;f=Codec%2FAudio%2FWavPack%2FWords.hs;fp=Codec%2FAudio%2FWavPack%2FWords.hs;h=09235472ba308379a99659ffd0218a94e82ee3c9;hp=0000000000000000000000000000000000000000;hb=5f113a044d1a17a7313124802b58c91819bc54eb;hpb=c12220b6ce900bced2b48b1fbc3a098e06d94946 diff --git a/Codec/Audio/WavPack/Words.hs b/Codec/Audio/WavPack/Words.hs new file mode 100644 index 0000000..0923547 --- /dev/null +++ b/Codec/Audio/WavPack/Words.hs @@ -0,0 +1,62 @@ +{-# LANGUAGE + BangPatterns + , UnboxedTuples + , UnicodeSyntax + #-} +-- | FIXME +module Codec.Audio.WavPack.Words + ( WordsData(..) + ) + where +import Codec.Audio.WavPack.Entropy +import Codec.Audio.WavPack.Internal +import Data.Bits +import Data.Bitstream.Generic (Bitstream) +import qualified Data.Bitstream.Generic as B +import Data.Word +import Prelude.Unicode + +-- | FIXME +data WordsData + = WordsData { + wdBitrateDelta ∷ !(Word32, Word32) + , wdBitrateAcc ∷ !(Word32, Word32) + , wdPendingData ∷ !Word32 + , wdHoldingOne ∷ !Word32 + , wdZeroesAcc ∷ !Word32 + , wdHoldingZero ∷ !Bool + , wdPendingCount ∷ !Int + , wdEntropyData ∷ !(EntropyData, EntropyData) + } + deriving (Eq, Show) + +-- This is an optimized version of 'getWord' that is used for lossless +-- only (error_limit ≡ 0). Also, rather than obtaining a single +-- sample, it can be used to obtain an entire buffer of either mono or +-- stereo samples. +--getWordsLossless ∷ + +-- Read a single unsigned value from the specified bitstream with a +-- value from 0 to maxCode. If there are exactly a power of two number +-- of possible codes then this will read a fixed number of bits; +-- otherwise it reads the minimum number of bits and then determines +-- whether another bit is needed to define the code. +readCode ∷ Bitstream bs ⇒ bs → Word32 → (# Word32, bs #) +{-# INLINEABLE readCode #-} +readCode bs 0 = (# 0, bs #) +readCode bs 1 = (# b2n (B.head bs), B.tail bs #) +readCode bs maxCode + = let !bitCount = countBits maxCode + !extras = bit bitCount - maxCode - 1 + !code = B.toBits (B.take (bitCount - 1) bs) + (# code', bitCount' #) + = if code ≥ extras then + (# (code `shiftL` 1) + - extras + + b2n (bs B.!! bitCount) + , bitCount #) + else + (# code, bitCount - 1 #) + !bs' = B.drop bitCount' bs + in + (# code', bs' #)