{-# LANGUAGE BangPatterns , UnboxedTuples , UnicodeSyntax #-} module Codec.Audio.WavPack.Unpack ( ) where 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 -- 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' #)