fully implemented Unpack.readCode
authorPHO <pho@cielonegro.org>
Sun, 10 Jul 2011 08:07:20 +0000 (17:07 +0900)
committerPHO <pho@cielonegro.org>
Sun, 10 Jul 2011 08:07:20 +0000 (17:07 +0900)
Codec/Audio/WavPack/Internal.hs
Codec/Audio/WavPack/Unpack.hs
wavpack.cabal

index 7d3cdf4948136fc21755425ad41d3128055027c2..99ff05c811326c2293bb6eb1ea073bf71c3c668e 100644 (file)
@@ -154,6 +154,7 @@ getNBits ∷ Num a ⇒ Word8 → a
 getNBits = fromIntegral ∘ UV.unsafeIndex nbitsTable ∘ fromIntegral
     where
       nbitsTable ∷ UV.Vector Word8
+      {-# NOINLINE nbitsTable #-}
       nbitsTable
           = UV.fromList
             [ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 --   0 -  15
@@ -179,6 +180,7 @@ getLog2 ∷ Num n ⇒ Word8 → n
 getLog2 = fromIntegral ∘ UV.unsafeIndex log2Table ∘ fromIntegral
     where
       log2Table ∷ UV.Vector Word8
+      {-# NOINLINE log2Table #-}
       log2Table
           = UV.fromList
             [ 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0B, 0x0D, 0x0E, 0x10, 0x11, 0x12, 0x14, 0x15
@@ -204,6 +206,7 @@ getExp2 ∷ Num n ⇒ Word8 → n
 getExp2 = fromIntegral ∘ UV.unsafeIndex exp2Table ∘ fromIntegral
     where
       exp2Table ∷ UV.Vector Word8
+      {-# NOINLINE exp2Table #-}
       exp2Table
           = UV.fromList
             [ 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0B
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' #)
index 399a28491fd12f2808da90f08829c4062e831076..e635c8f2ba4d1dff4745540925c3eea02eb4d8bd 100644 (file)
@@ -35,7 +35,7 @@ Library
         base-unicode-symbols == 0.2.*,
         binary               == 0.5.*,
         binary-strict        == 0.4.*,
-        bitstream            == 0.1.*,
+        bitstream            == 0.2.*,
         bytestring           == 0.9.*,
         strict               == 0.3.*,
         vector               == 0.7.*