From c12220b6ce900bced2b48b1fbc3a098e06d94946 Mon Sep 17 00:00:00 2001 From: PHO Date: Sun, 10 Jul 2011 17:07:20 +0900 Subject: [PATCH] fully implemented Unpack.readCode --- Codec/Audio/WavPack/Internal.hs | 3 +++ Codec/Audio/WavPack/Unpack.hs | 22 +++++++++++++++++----- wavpack.cabal | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Codec/Audio/WavPack/Internal.hs b/Codec/Audio/WavPack/Internal.hs index 7d3cdf4..99ff05c 100644 --- a/Codec/Audio/WavPack/Internal.hs +++ b/Codec/Audio/WavPack/Internal.hs @@ -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 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' #) diff --git a/wavpack.cabal b/wavpack.cabal index 399a284..e635c8f 100644 --- a/wavpack.cabal +++ b/wavpack.cabal @@ -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.* -- 2.40.0