X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=wavpack.git;a=blobdiff_plain;f=Codec%2FAudio%2FWavPack%2FUnpack.hs;fp=Codec%2FAudio%2FWavPack%2FUnpack.hs;h=f816657e9924e8b105b7bf99c232fdf5fb40332f;hp=8d2790619f2f5440511b54a95b9c035cfd9256f7;hb=c12220b6ce900bced2b48b1fbc3a098e06d94946;hpb=37c42ce6bcf9fef0a16b9c142288a2655a2b3556 diff --git a/Codec/Audio/WavPack/Unpack.hs b/Codec/Audio/WavPack/Unpack.hs index 8d27906..f816657 100644 --- a/Codec/Audio/WavPack/Unpack.hs +++ b/Codec/Audio/WavPack/Unpack.hs @@ -1,5 +1,6 @@ {-# LANGUAGE BangPatterns + , UnboxedTuples , UnicodeSyntax #-} module Codec.Audio.WavPack.Unpack @@ -11,18 +12,29 @@ 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) +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 0 = (# 0, bs #) +readCode bs 1 = (# b2n (B.head bs), B.tail bs #) readCode bs maxCode = let !bitCount = countBits maxCode - !extras = (1 `shiftL` bitCount) - maxCode - 1 + !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 - error "unk" \ No newline at end of file + (# code', bs' #)