]> gitweb @ CieloNegro.org - wavpack.git/blobdiff - Codec/Audio/WavPack/Unpack.hs
fully implemented Unpack.readCode
[wavpack.git] / Codec / Audio / WavPack / Unpack.hs
index 8d2790619f2f5440511b54a95b9c035cfd9256f7..f816657e9924e8b105b7bf99c232fdf5fb40332f 100644 (file)
@@ -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' #)