mp3decoder (empty) → 0.0.1
raw patch · 18 files changed
+4268/−0 lines, 18 filesdep +basedep +binary-strictdep +bytestringsetup-changed
Dependencies added: base, binary-strict, bytestring, haskell98, mtl
Files
- Codec/Audio/MP3/Decoder.hs +301/−0
- Codec/Audio/MP3/Huffman.hs +81/−0
- Codec/Audio/MP3/HybridFilterBank.hs +223/−0
- Codec/Audio/MP3/IMDCT.hs +56/−0
- Codec/Audio/MP3/SynthesisFilterBank.hs +68/−0
- Codec/Audio/MP3/Tables.hs +1889/−0
- Codec/Audio/MP3/Types.hs +125/−0
- Codec/Audio/MP3/Unpack.hs +893/−0
- Codec/Audio/MP3/c_imdct.c +77/−0
- Codec/Audio/MP3/c_imdct.h +15/−0
- Codec/Audio/MP3/c_synth.c +198/−0
- Codec/Audio/MP3/c_synth.h +17/−0
- LICENSE +22/−0
- README +59/−0
- Setup.lhs +4/−0
- example/Driver.hs +50/−0
- example/PCMWriter.hs +127/−0
- mp3decoder.cabal +63/−0
+ Codec/Audio/MP3/Decoder.hs view
@@ -0,0 +1,301 @@+-- +-- module Decoder - Decode MP3.+--+-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--+-- TODO:+--+-- *) Better performance. Right now the decoder is not fast enough to decode+-- in real-time. (Biggest culprit right now is the Huffman decoding).+--+-- *) Check if frames with MixedBlocks are decoded correctly. This feature +-- seems to be unusual.+--+-- *) Implement Intensity Stereo. Also unusual.+--+ +module Codec.Audio.MP3.Decoder (+ -- From MP3Unpack.hs+ mp3Seek+ ,mp3Unpack+ ,MP3Bitstream(..)+ -- From here+ ,mp3Decode+ ,MP3DecodeState(..)+ ,emptyMP3DecodeState+) where++import Codec.Audio.MP3.Unpack+import Codec.Audio.MP3.Types+import Codec.Audio.MP3.Tables+import Codec.Audio.MP3.HybridFilterBank++-- +-- mp3Requantize+--+-- The heart of mp3 encoding is taking the 576 frequency lines and quantize+-- the values to remove irrelevant information, while keeping enough data to+-- keep noise to the minimum. This function does the reverse: it takes the+-- quantized integer frequency samples and requantizes them to a floating+-- point representation.+--+-- There are several parameters that affect the requantization:+--+-- gain, sg0, sg1, sg2 are "global" gains that affect the whole+-- frequency spectra, from 0-576. gain are for long blocks of 576 samples, +-- and sg0-sg2 are for the three short blocks of 192 samples each.+--+-- There are also "local" gains, that only scale some frequency regions. The+-- 576 frequency regions are divided in 21 bands (for long blocks), scaled +-- separately. The scale factors are saved in 'large' for long blocks and +-- 'small' for small blocks.+--+-- *Codec.Audio.MP3.Tables> tableScaleBandIndexShort 32000+-- [(0,0),(0,0),(0,0),(0,0),(0,1),(0,1),(0,1),(0,1),(0,2),(0,2),(0,2),(0,2),+-- (1,0),(1,0),(1,0),(1,0),(1,1),(1,1),(1,1),(1,1),(1,2),(1,2),(1,2),(1,2),+-- (2,0),(2,0),(2,0),(2,0),(2,1),(2,1),(2,1),(2,1),(2,2),(2,2),(2,2),(2,2),+-- (3,0),(3,0),(3,0),(3,0),...+-- +mp3Requantize :: SampleRate -> MP3DataChunk -> [Frequency]+mp3Requantize samplerate (MP3DataChunk _ bf gain (sg0, sg1, sg2) + longsf shortsf _ compressed)+ | bf == LongBlocks = long+ | bf == ShortBlocks = short+ | bf == MixedBlocks = take 36 long ++ drop 36 short+ where + long = zipWith procLong compressed longbands+ short = zipWith procShort compressed shortbands++ procLong sample sfb = + let localgain = longsf !! sfb+ dsample = fromIntegral sample+ in gain * localgain * dsample **^ (4/3)++ procShort sample (sfb, win) =+ let localgain = (shortsf !! sfb) !! win+ blockgain = case win of 0 -> sg0+ 1 -> sg1+ 2 -> sg2+ dsample = fromIntegral sample+ in gain * localgain * blockgain * dsample **^ (4/3)+ + -- Frequency index (0-575) to scale factor band index (0-21).+ longbands = tableScaleBandIndexLong samplerate+ -- Frequency index to scale factor band index and window index (0-2).+ shortbands = tableScaleBandIndexShort samplerate+++-- b **^ e == sign(b) * abs(b)**e+(**^) :: (Floating a, Ord a) => a -> a -> a+b **^ e = let sign = if b < 0 then -1 else 1+ b' = abs b+ in sign * b' ** e+infixr 8 **^+++--+-- mp3Reorder+--+-- The MP3 encoder reorders Short granules before Huffman coding for better+-- compression ratio. There are actually two different reorderings;+-- this function does both at the same time.+--+-- The Huffman decoded samples (chunkData) are ordered first by +-- scale factor band, then by 192-granule, then by frequency. So if the+-- first scale factor band has size 4, the first 13 samples are+-- a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],c[0],c[1],c[2],c[3],a[4],...+-- where a,b,c are the three 192-granules.+-- As samples within bands are quantized together, this gives a good+-- compression by the Huffman coder.+--+-- As the hybrid filter bank works on 18 samples a time, and the scale+-- factor bands don't have this fixed size, the samples are reordered to+-- work with the filter banks. This can be thought of as two reorderings:+-- First the samples are interleaved, ordered strictly by frequency:+-- a[0],b[0],c[0],a[1],b[1],c[1],... This ensures the hybrid filter bank+-- can transform it back to the time domain, 18 samples a time.+--+-- Then these samples are reordered again so the short IMDCT can be+-- performed on consecutive blocks of six samples. _This is strictly+-- for convienience_. If we don't do this second reordering, the+-- three short IMDCT's have to be done like this in the hybrid filter+-- bank:+-- imdct 6 [f!!0,f!!3,f!!6,f!!9,f!!12,f!!15] +-- imdct 6 [f!!1,f!!4,f!!7,f!!10,f!!13,f!!16]+-- imdct 6 [f!!2,f!!5,f!!8,f!!11,f!!14,f!!17]+-- After the seceond reordering, we can instead split "f" into three equal+-- parts, and do+-- imdct 6 f0+-- for example.+--+mp3Reorder :: SampleRate -> BlockFlag -> [Frequency] -> [Frequency]+mp3Reorder sr bf freq + | bf == LongBlocks = freq+ | bf == ShortBlocks = freq'+ | bf == MixedBlocks = take 36 freq ++ drop 36 freq'+ where+ -- We want the output list to be as long as the input list to + -- correctly handle IS Stereo decoding, but the unsafe reorderList + -- requires the input to be as long as the index list.+ inlen = length freq+ freq' = take inlen $ reorderList rtable (padWith 576 0.0 freq)+ rtable = tableReorder sr+++-- 'reorderList' takes a list of indices and a list of elements and+-- reorders the list based on the indices. Example:+-- reorderList [1,2,0] [a,b,c] == [b,c,a]+-- UNSAFE, SLOW+reorderList :: [Int] -> [a] -> [a]+reorderList indices list = map (list !!) indices+++-- Pads a list until it's length is n.+-- padWith 5 0 [1,2,3] == [1,2,3,0,0]+padWith :: Int -> a -> [a] -> [a]+padWith n padding xs = xs ++ replicate (n - length xs) padding+++-- +-- mp3StereoMS+--+-- When two channels are similiar, the encoder can transmit the sum (M)+-- and the difference (S) of the two channels instead of the two independent+-- channels. In these cases, the sum signal will contain much more +-- information than the difference signal. This is lossless.+--+mp3StereoMS :: [Frequency] -> [Frequency] -> ([Frequency], [Frequency])+mp3StereoMS middle side =+ let sqrtinv = 1 / (sqrt 2)+ left = zipWith0 (\x y -> (x+y)*sqrtinv) 0.0 middle side+ right = zipWith0 (\x y -> (x-y)*sqrtinv) 0.0 middle side+ in (left, right)+++zipWith0 :: (a -> a -> a) -> a -> [a] -> [a] -> [a]+zipWith0 f pad (a:as) (b:bs) = f a b : zipWith0 f pad as bs+zipWith0 f pad [] (b:bs) = f pad b : zipWith0 f pad [] bs+zipWith0 f pad (a:as) [] = f a pad : zipWith0 f pad as []+zipWith0 _ _ _ _ = []+++-- +-- mp3StereoIS+--+-- Another Joint Stereo mode.+--+-- TODO: Not implemented yet - unusual.+--+mp3StereoIS :: BlockFlag -> [Int] -> [[Int]] -> + [Frequency] -> [Frequency] -> ([Frequency], [Frequency])+mp3StereoIS _ _ _ left right = (left, right)+{-+mp3StereoIS bf long short left right = helper bf+ where+ helper MixedBlocks = (left, right) -- TODO.+ helper LongBlocks = (left, right)+ helper ShortBlocks = (left, right)++ procOne 7 sl sr = (sl, sr)+ procOne 6 sl sr = (sl, 0.0)+ procOne p sl sr = let ratio = tan $ ((fromIntegral p) * pi) / 12.0+ ratiol = ratio / (1.0 + ratio)+ ratior = 1.0 / (1.0 + ratio)+ sl' = ratiol * sl+ sr' = ratior * sr+ in (sl', sr')+-}++-- +-- mp3Decode+--+-- Decode the MP3.+--+-- Return value:+--+-- 1152 samples (-1.0 - 1.0) for the left and right channel.+--+-- TODO: Shouldn't need ~50 lines for this.+--+mp3Decode :: MP3DecodeState -> MP3Data -> (MP3DecodeState, [Sample], [Sample])+mp3Decode decstate chunks = decode chunks+ where+ decode (MP3Data2Channels sr ch (ms, is) gr0ch0 gr0ch1 gr1ch0 gr1ch1) =+ let s00 = step0 gr0ch0 sr -- granule 0 begin+ s01 = step0 gr0ch1 sr+ (s00',s01') = decodeStereo ch gr0ch0 s00 gr0ch1 s01+ (state00, output00) = step1 gr0ch0 s00' (decodeState0 decstate)+ (state01, output01) = step1 gr0ch1 s01' (decodeState1 decstate)+ s10 = step0 gr1ch0 sr+ s11 = step0 gr1ch1 sr+ (s10', s11') = decodeStereo ch gr1ch0 s10 gr1ch1 s11+ (state10, output10) = step1 gr1ch0 s10' state00+ (state11, output11) = step1 gr1ch1 s11' state01+ in (MP3DecodeState state10 state11,+ output00 ++ output10, output01 ++ output11)+ where+ decodeStereo JointStereo chunkch0 ch0 chunkch1 ch1 = + let bf0 = chunkBlockFlag chunkch0+ (isL, isS) = chunkISParam chunkch0+ (ch0', ch1') = + if ms then mp3StereoMS ch0 ch1 + else (ch0, ch1)+ (ch0'', ch1'') = + if is then mp3StereoIS bf0 isL isS ch0' ch1'+ else (ch0', ch1')+ in (ch0'', ch1'')+ decodeStereo _ _ ch0 _ ch1 = (ch0, ch1)++ decode (MP3Data1Channels sr _ _ gr0ch0 gr1ch0) =+ let s00 = step0 gr0ch0 sr+ s10 = step0 gr1ch0 sr+ (state0, output0) = step1 gr0ch0 s00 (decodeState0 decstate)+ (state1, output1) = step1 gr1ch0 s10 state0+ output = output0 ++ output1+ in (MP3DecodeState state1 state1, output, output)++ -- At this point the audio samples are _not_ padded with the zeros+ -- from the zero huffman region. This is to make the IS stereo+ -- implementation less messy. (Of course, IS is not implemented as of+ -- version 0.0.1).+ step0 chunk sr = + let freq = mp3Requantize sr chunk+ freq' = mp3Reorder sr (chunkBlockFlag chunk) freq+ in freq'++ -- ... The hybrid filter bank will however pad.+ step1 chunk inp state =+ let bf = chunkBlockFlag chunk+ bt = chunkBlockType chunk+ in mp3HybridFilterBank bf bt state inp+++data MP3DecodeState = MP3DecodeState {+ decodeState0 :: MP3HybridState,+ decodeState1 :: MP3HybridState+} +++emptyMP3DecodeState :: MP3DecodeState+emptyMP3DecodeState = MP3DecodeState emptyMP3HybridState emptyMP3HybridState+
+ Codec/Audio/MP3/Huffman.hs view
@@ -0,0 +1,81 @@+-- +-- module Huffman - Functions for dealing with Huffman +-- trees. This is not a full-fledged Huffman module+-- and has only limited functionality.+-- +-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--++module Codec.Audio.MP3.Huffman (+ HuffmanTree(..)+ ,huffmanFromList+ ,huffmanLookupM+) where++data HuffmanTree a = HuffmanNull+ | HuffmanLeaf a+ | HuffmanNode (HuffmanTree a) (HuffmanTree a)+ deriving (Show, Eq)++-- | 'huffmanFromList' builds a tree from a list representation of the tree.+-- The list is a [([Int], t)] where [Int] is a list of code bits and t is the +-- type of the value associated with the bits. Given the list +-- [([1],x), ([0,0,1],y), ([0,1],z), ([0,0,0],w)]+-- The function will construct the tree+-- HuffmanNode (HuffmanNode (HuffmanNode (HuffmanLeaf w) +-- (HuffmanLeaf y))+-- (HuffmanLeaf z)) +-- (HuffmanLeaf x)+-- This is mainly useful if we have a table representation of a tree,+-- say from a technical specification.+huffmanFromList :: [([Int], t)] -> HuffmanTree t+huffmanFromList = foldl huffmanUpdate HuffmanNull+++huffmanUpdate :: HuffmanTree t -> ([Int], t) -> HuffmanTree t+huffmanUpdate HuffmanNull ([], value) = HuffmanLeaf value+huffmanUpdate HuffmanNull (xs, value) = huffmanCreate xs value+ where+ huffmanCreate [] val = HuffmanLeaf val+ huffmanCreate (y:ys) val = + if y == 0 then HuffmanNode (huffmanCreate ys val) HuffmanNull+ else HuffmanNode HuffmanNull (huffmanCreate ys val)+huffmanUpdate (HuffmanNode left right) ((x:xs), value) =+ if x == 0 then HuffmanNode (huffmanUpdate left (xs, value)) right+ else HuffmanNode left (huffmanUpdate right (xs, value))+++-- | 'huffmanLookupM' looks up values in a tree. The first argument is a+-- monad action that decides whether to go left or right in the tree.+-- The second argument is the tree. The function returns error or+-- a pair with a value and number if bits consumed.+huffmanLookupM :: (Monad m) => m Bool -> HuffmanTree t -> m (Maybe (t, Int))+huffmanLookupM getbitfunc tree = helper getbitfunc tree 0+ where+ helper _ HuffmanNull _ = return Nothing+ helper bf (HuffmanNode q0 q1) n = + do bit <- bf+ r <- helper bf (if bit then q1 else q0) (n+1)+ return $ r+ helper _ (HuffmanLeaf leaf) n = return $ Just (leaf, n)+
+ Codec/Audio/MP3/HybridFilterBank.hs view
@@ -0,0 +1,223 @@+-- +-- module HybridFilterBank - Frequency to time.+-- +-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--++module Codec.Audio.MP3.HybridFilterBank (+ mp3HybridFilterBank+ ,MP3HybridState(..)+ ,emptyMP3HybridState+) where++import Codec.Audio.MP3.IMDCT+import Codec.Audio.MP3.SynthesisFilterBank+import Codec.Audio.MP3.Tables+import Codec.Audio.MP3.Types++{-+mapBlock :: Int -> ([a] -> [b]) -> [a] -> [b]+mapBlock blocksize func [] = []+mapBlock blocksize func seq = + let (block, rem) = splitAt blocksize seq+ in func block ++ mapBlock blocksize func rem+-}++mapBlock :: Int -> ([a] -> b) -> [a] -> [b]+mapBlock blocksize func [] = []+mapBlock blocksize func seq =+ let (block, rem) = splitAt blocksize seq+ in func block : mapBlock blocksize func rem+++-- 'windowWith' windows two signals. For readability, so we can do:+-- signal' = signal `windowWith` win+windowWith :: (Num a) => [a] -> [a] -> [a]+windowWith = zipWith (*)+++-- +-- mp3IMDCT+--+-- Input: 576 frequency samples and state from the last time the function+-- was called.+-- Output: 576 time domain samples and new state.+--+mp3IMDCT :: BlockFlag -> Int -> [Frequency] -> [Sample] -> ([Sample], [Sample])+mp3IMDCT blockflag blocktype freq overlap =+ let (samples, overlap') = + case blockflag of+ LongBlocks -> transf (doImdctLong blocktype) freq+ ShortBlocks -> transf (doImdctShort) freq+ MixedBlocks -> transf (doImdctLong 0) (take 36 freq) <++>+ transf (doImdctShort) (drop 36 freq)+ samples' = zipWith (+) samples overlap+ in (samples', overlap')+ where+ transf imdctfunc input = unzipConcat $ mapBlock 18 toSO input+ where+ -- toSO takes 18 input samples b and computes 36 time samples+ -- by the IMDCT. These are further divided into two equal+ -- parts (S, O) where S are time samples for this frame+ -- and O are values to be overlapped in the next frame.+ toSO b = splitAt 18 (imdctfunc b)+ unzipConcat xs = let (a, b) = unzip xs+ in (concat a, concat b)++--+-- doImdctLong, doImdctShort+--+-- IMDCT with windows. This also does the overlapping when short blocks+-- are used.+--+doImdctLong :: Int -> [Frequency] -> [Sample]+doImdctLong blocktype f = imdct 18 f `windowWith` tableImdctWindow blocktype+++doImdctShort :: [Frequency] -> [Sample]+doImdctShort f = overlap3 shorta shortb shortc+ where+ (f1, f2, f3) = splitAt2 6 f+ shorta = imdct 6 f1 `windowWith` tableImdctWindow 2+ shortb = imdct 6 f2 `windowWith` tableImdctWindow 2+ shortc = imdct 6 f3 `windowWith` tableImdctWindow 2+ --shorta = imdct 6 [f!!0,f!!3,f!!6,f!!9,f!!12,f!!15] `windowWith` tableImdctWindow 2+ --shortb = imdct 6 [f!!1,f!!4,f!!7,f!!10,f!!13,f!!16] `windowWith` tableImdctWindow 2+ --shortc = imdct 6 [f!!2,f!!5,f!!8,f!!11,f!!14,f!!17] `windowWith` tableImdctWindow 2++ overlap3 a b c = + p1 ++ (zipWith3 add3 (a ++ p2) (p1 ++ b ++ p1) (p2 ++ c)) ++ p1+ where+ add3 x y z = x+y+z+ p1 = [0,0,0, 0,0,0]+ p2 = [0,0,0, 0,0,0, 0,0,0, 0,0,0]+++splitAt2 :: Int -> [a] -> ([a], [a], [a])+splitAt2 n xs = let (part1, part23) = splitAt n xs+ (part2, part3) = splitAt n part23+ in (part1, part2, part3)++(<++>) :: ([a], [b]) -> ([a], [b]) -> ([a], [b])+(as, xs) <++> (bs, ys) = (as++bs, xs++ys)+infixr 5 <++>+++-- +-- mp3AA+--+-- Undo the encoders alias reduction.+--+-- TODO: Rewrite this, clumsy and non-intuitive.+--+mp3AA :: BlockFlag -> Int -> [Frequency] -> [Frequency]+mp3AA blockflag blocktype freq+ | blocktype == 2 && blockflag /= MixedBlocks = freq+ | blocktype == 2 && blockflag == MixedBlocks = + (take 9 freq) ++ aaHelper (take 18 (drop 9 freq)) ++ (drop 27 freq)+ | otherwise = + (take 9 freq) ++ aaHelper (take 558 (drop 9 freq)) ++ (drop 567 freq)+ where+ aaHelper [] = []+ aaHelper chunk = before ++ aaButterfly middle ++ after ++ + aaHelper (drop 18 chunk)+ where+ before = take 1 chunk+ middle = take 16 (drop 1 chunk)+ after = take 1 (drop 17 chunk)+ aaButterfly f = zipWith (-) (take 8 seqcs) (take 8 seqca) +++ zipWith (+) (drop 8 seqcs) (drop 8 seqca)+ where+ seqcs = zipWith (*) f (reverse cs ++ cs)+ seqca = reverse $ zipWith (*) f (reverse ca ++ ca)+ cs = [1 / sqrt (1.0 + c**2) | c <- aaCoeff]+ ca = [c / sqrt (1.0 + c**2) | c <- aaCoeff]+ aaCoeff = [-0.6, -0.535, -0.33, -0.185, + -0.095, -0.041, -0.0142, -0.0037]+++{-+mp3AliasCancel :: BlockFlag -> [Frequency] -> [Frequency]+mp3AliasCancel blockflag freq+ | blockflag == ShortBlocks = freq+ | blockflag == LongBlocks = helper 31+ | blockflag == MixedBlocks = helper 1+ where+ butterflies samples = let samplesa = zipWith (*) samples cs'+ samplesb = zipWith (*) (reverse samples) ca'+ in zipWith (+) samplesa samplesb+ -- Coeffs.+ cs' = reverse cs ++ cs+ ca' = map (-) (reverse ca) ++ ca+ cs = [1 / sqrt (1.0 + c**2) | c <- aaCoeff]+ ca = [c / sqrt (1.0 + c**2) | c <- aaCoeff]+ aaCoeff = [-0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037]+-}++-- +-- mp3FrequencyInvert+--+-- The time samples returned from mp3IMDCT are inverted. This is the same+-- as with bandpass sampling: odd subbands have inverted frequency spectra -+-- invert it by changing signs on odd samples.+--+mp3FrequencyInvert :: [Sample] -> [Sample]+mp3FrequencyInvert = zipWith (*) pattern+ where+ pattern = cycle $ replicate 18 1 ++ take 18 (cycle [1,-1])+++-- Pads a list until it's length is n.+-- padWith 5 0 [1,2,3] == [1,2,3,0,0]+padWith :: Int -> a -> [a] -> [a]+padWith n padding xs = xs ++ replicate (n - length xs) padding+++-- +-- mp3HybridFilterBank+--+-- Frequency domain to time domain.+--+mp3HybridFilterBank :: BlockFlag -> Int -> + MP3HybridState -> [Frequency] -> + (MP3HybridState, [Sample])+mp3HybridFilterBank bf bt (MP3HybridState simdct ssynthesis) input =+ let input' = padWith 576 0.0 input -- ensure length 576+ aa = mp3AA bf bt input'+ (samp, simdct') = mp3IMDCT bf bt aa simdct+ samp' = mp3FrequencyInvert samp++ --(ssynthesis', output) = (ssynthesis, take 18 samp) -- (See Driver.hs)+ (ssynthesis', output) = mp3SynthesisFilterBank ssynthesis samp'++ in (MP3HybridState simdct' ssynthesis', output)+++-- [Sample] = IMDCT output from previous granule, used for overlapping.+-- MP3SynthState = State for the synthesis filterbank.+data MP3HybridState = MP3HybridState [Sample] MP3SynthState++emptyMP3HybridState :: MP3HybridState+emptyMP3HybridState = MP3HybridState (replicate 576 0.0) + (MP3SynthState (replicate 1024 0.0))+
+ Codec/Audio/MP3/IMDCT.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-- +-- module IMDCT+-- +-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--+module Codec.Audio.MP3.IMDCT (+ imdct+) where++import Foreign.C.Types+import Foreign.Ptr+import Foreign.Marshal.Array+import System.IO.Unsafe+++foreign import ccall "c_imdct.h imdct"+ c_imdct :: CInt -> + Ptr CDouble -> + Ptr CDouble -> + IO ()++imdctIO :: Int -> [CDouble] -> IO [CDouble]+imdctIO points input+ = withArray input $ \cinput ->+ allocaArray (points*2) $ \coutput ->+ do c_imdct (fromIntegral points) cinput coutput+ peekArray (points*2) coutput+++imdct :: Int -> [Double] -> [Double]+imdct points input = let cinput = map realToFrac input+ coutput = unsafePerformIO (imdctIO points cinput)+ output = map realToFrac coutput+ in output+
+ Codec/Audio/MP3/SynthesisFilterBank.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-- +-- module SynthesisFilterBank - The MPEG synthesis filterbank.+-- +-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--++module Codec.Audio.MP3.SynthesisFilterBank (+ MP3SynthState(..)+ ,mp3SynthesisFilterBank+) where++import Foreign.C.Types+import Foreign.Ptr+import Foreign.Marshal.Array+import System.IO.Unsafe++foreign import ccall "c_synth.h synth"+ c_synth :: Ptr CDouble -> + Ptr CDouble -> + Ptr CDouble -> + Ptr CDouble -> + IO ()++synthIO :: [CDouble] -> [CDouble] -> IO ([CDouble], [CDouble])+synthIO state input+ = withArray state $ \cstate ->+ withArray input $ \cinput ->+ allocaArray 1024 $ \cstate' ->+ allocaArray 576 $ \coutput ->+ do c_synth cstate cinput cstate' coutput+ state' <- peekArray 1024 cstate'+ output <- peekArray 576 coutput+ return (state', output)++data MP3SynthState = MP3SynthState [Sample] deriving (Show)++type Sample = Double+mp3SynthesisFilterBank :: MP3SynthState -> [Sample] -> + (MP3SynthState, [Sample])+mp3SynthesisFilterBank (MP3SynthState state) input =+ let cstate = map realToFrac state+ cinput = map realToFrac input+ (cstate', coutput) = unsafePerformIO (synthIO cstate cinput)+ state' = map realToFrac cstate'+ output = map realToFrac coutput+ in (MP3SynthState state', output)+
+ Codec/Audio/MP3/Tables.hs view
@@ -0,0 +1,1889 @@+--+-- module Tables - Tables defined in the specification.+--+-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--+-- TODO: Change all tables to something more suitable with O(1) lookup.+--+module Codec.Audio.MP3.Tables (+ tableImdctWindow+ ,tableScaleBandBoundary+ ,tableScaleBandIndexLong+ ,tableScaleBandIndexShort+ ,tableSlen+ ,tableReorder+ ,tableReorder2 -- See below.+ ,tablePretab+ ,tableHuffman+ ,tableHuffmanQuad+) where++--+-- tableImdctWindow+--+-- Window coefficients for IMDCT transform.+-- +tableImdctWindow :: Floating a => Int -> [a]+tableImdctWindow blocktype+ | blocktype == 0 = [coeff n 36 0.5 | n <- [ 0..35]]+ | blocktype == 1 = [coeff n 36 0.5 | n <- [ 0..17]] +++ [1.0 | n <- [18..23]] +++ [coeff n 12 (-17.5) | n <- [24..29]] +++ [0.0 | n <- [30..35]]+ | blocktype == 2 = [coeff n 12 0.5 | n <- [ 0..11]] +++ [0.0 | n <- [12..35]]+ | blocktype == 3 = [0.0 | n <- [ 0.. 5]] +++ [coeff n 12 (-5.5) | n <- [ 6..11]] +++ [1.0 | n <- [12..17]] +++ [coeff n 36 0.5 | n <- [18..35]]+ | otherwise = error "Wrong blocktype."+ where+ coeff n div' add' = sin (pi/div' * ((fromIntegral n) + add'))++--+-- tableScaleBandBound{Long,Short}, tableScaleBandBoundary+--+-- These few tables represent the boundaries, in the 576 frequency +-- regions, of the scale factor bands. These bands approximate the+-- critical bands of the human auditory system, and are used to+-- determine scaling. This scaling controls the quantization noise.+--+tableScaleBandBoundLong :: Int -> [Int]+tableScaleBandBoundLong 44100 = [ 0, 4, 8, 12, 16, 20, 24, 30,+ 36, 44, 52, 62, 74, 90, 110, 134, + 162, 196, 238, 288, 342, 418, 576] +tableScaleBandBoundLong 48000 = [ 0, 4, 8, 12, 16, 20, 24, 30, + 36, 42, 50, 60, 72, 88, 106, 128, + 156, 190, 230, 276, 330, 384, 576] +tableScaleBandBoundLong 32000 = [ 0, 4, 8, 12, 16, 20, 24, 30,+ 36, 44, 54, 66, 82, 102, 126, 156, + 194, 240, 296, 364, 448, 550, 576]+tableScaleBandBoundLong _ = error "Wrong SR for Table."+++tableScaleBandBoundShort :: Int -> [Int]+tableScaleBandBoundShort 44100 = [ 0, 4, 8, 12, 16, 22, 30, 40, + 52, 66, 84, 106, 136, 192] +tableScaleBandBoundShort 48000 = [ 0, 4, 8, 12, 16, 22, 28, 38, + 50, 64, 80, 100, 126, 192] +tableScaleBandBoundShort 32000 = [ 0, 4, 8, 12, 16, 22, 30, 42, + 58, 78, 104, 138, 180, 192]+tableScaleBandBoundShort _ = error "Wrong SR for Table."++-- We only need to export the long boundaries for unpacking (Unpack.hs).+tableScaleBandBoundary :: Int -> Int -> Int+tableScaleBandBoundary sfreq index = (tableScaleBandBoundLong sfreq) !! index+++-- +-- tableScaleBandIndex{Long,Short}+-- +-- Long: The scale factor band indices. As the first band has length 4, this+-- gives [0,0,0,0,1,...] which simply means sample 0-3 belong to scale factor+-- band 0.+--+-- Short: The scale factor band indices + 192-granule indices. Due to the+-- encoders reordering, this gives [(0,0),(0,0),(0,0),(0,0),(0,1),...+-- This means sample 0 (of the 576) belongs to scale factor band 0, and the +-- first of the three 192-granules.+--++tableScaleBandIndexLong :: Int -> [Int]+tableScaleBandIndexLong = indexify . + consecutiveDiff . tableScaleBandBoundLong+ where+ indexify xs = concat (zipWith replicate xs [0..])+++tableScaleBandIndexShort :: Int -> [(Int, Int)]+tableScaleBandIndexShort = indexifyWindows . + consecutiveDiff . tableScaleBandBoundShort+ where+ indexifyWindows xs = concat (zipWith addFirst [0..] (map buildTriple xs))+ where+ addFirst n = map (\x -> (n, x))+ buildTriple n = replicate n 0 ++ replicate n 1 ++ replicate n 2+++consecutiveDiff :: Num a => [a] -> [a]+consecutiveDiff xs = zipWith (-) (tail xs) xs++-- +-- tablePretab+--+-- Modifies certain scale factors for higher range than 4 bits.+--+tablePretab :: [Int]+tablePretab = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0, 0]+++--+-- tableSlen+--+-- This table is used for parsing the scale factor bands.+--+tableSlen :: [(Int, Int)]+tableSlen = [(0,0), (0,1), (0,2), (0,3), (3,0), (1,1), (1,2), (1,3),+ (2,1), (2,2), (2,3), (3,1) ,(3,2), (3,3), (4,2), (4,3)] +++-- +-- tableReorder+--+-- Before Huffman coding the encoder reorders short chunks for better+-- compression. This does two reorderings; see Decoder.hs.+--+tableReorder :: Int -> [Int]+tableReorder 44100 = + [ 0, 1, 2, 3, 12, 13, 4, 5, 6, 7, 16, 17, 8, 9, 10, 11, 20, 21,+ 14, 15, 24, 25, 26, 27, 18, 19, 28, 29, 30, 31, 22, 23, 32, 33, 34, 35,+ 36, 37, 38, 39, 48, 49, 40, 41, 42, 43, 54, 55, 44, 45, 46, 47, 60, 61,+ 50, 51, 52, 53, 66, 67, 56, 57, 58, 59, 74, 75, 62, 63, 64, 65, 82, 83,+ 68, 69, 70, 71, 72, 73, 76, 77, 78, 79, 80, 81, 84, 85, 86, 87, 88, 89,+ 90, 91, 92, 93, 94, 95, 100, 101, 102, 103, 104, 105, 110, 111, 112, 113, 114, 115,+ 96, 97, 98, 99, 120, 121, 106, 107, 108, 109, 132, 133, 116, 117, 118, 119, 144, 145,+ 122, 123, 124, 125, 126, 127, 134, 135, 136, 137, 138, 139, 146, 147, 148, 149, 150, 151,+ 128, 129, 130, 131, 156, 157, 140, 141, 142, 143, 170, 171, 152, 153, 154, 155, 184, 185,+ 158, 159, 160, 161, 162, 163, 172, 173, 174, 175, 176, 177, 186, 187, 188, 189, 190, 191,+ 164, 165, 166, 167, 168, 169, 178, 179, 180, 181, 182, 183, 192, 193, 194, 195, 196, 197,+ 198, 199, 200, 201, 202, 203, 216, 217, 218, 219, 220, 221, 234, 235, 236, 237, 238, 239,+ 204, 205, 206, 207, 208, 209, 222, 223, 224, 225, 226, 227, 240, 241, 242, 243, 244, 245,+ 210, 211, 212, 213, 214, 215, 228, 229, 230, 231, 232, 233, 246, 247, 248, 249, 250, 251,+ 252, 253, 254, 255, 256, 257, 274, 275, 276, 277, 278, 279, 296, 297, 298, 299, 300, 301,+ 258, 259, 260, 261, 262, 263, 280, 281, 282, 283, 284, 285, 302, 303, 304, 305, 306, 307,+ 264, 265, 266, 267, 268, 269, 286, 287, 288, 289, 290, 291, 308, 309, 310, 311, 312, 313,+ 270, 271, 272, 273, 318, 319, 292, 293, 294, 295, 348, 349, 314, 315, 316, 317, 378, 379,+ 320, 321, 322, 323, 324, 325, 350, 351, 352, 353, 354, 355, 380, 381, 382, 383, 384, 385,+ 326, 327, 328, 329, 330, 331, 356, 357, 358, 359, 360, 361, 386, 387, 388, 389, 390, 391,+ 332, 333, 334, 335, 336, 337, 362, 363, 364, 365, 366, 367, 392, 393, 394, 395, 396, 397,+ 338, 339, 340, 341, 342, 343, 368, 369, 370, 371, 372, 373, 398, 399, 400, 401, 402, 403,+ 344, 345, 346, 347, 408, 409, 374, 375, 376, 377, 464, 465, 404, 405, 406, 407, 520, 521,+ 410, 411, 412, 413, 414, 415, 466, 467, 468, 469, 470, 471, 522, 523, 524, 525, 526, 527,+ 416, 417, 418, 419, 420, 421, 472, 473, 474, 475, 476, 477, 528, 529, 530, 531, 532, 533,+ 422, 423, 424, 425, 426, 427, 478, 479, 480, 481, 482, 483, 534, 535, 536, 537, 538, 539,+ 428, 429, 430, 431, 432, 433, 484, 485, 486, 487, 488, 489, 540, 541, 542, 543, 544, 545,+ 434, 435, 436, 437, 438, 439, 490, 491, 492, 493, 494, 495, 546, 547, 548, 549, 550, 551,+ 440, 441, 442, 443, 444, 445, 496, 497, 498, 499, 500, 501, 552, 553, 554, 555, 556, 557,+ 446, 447, 448, 449, 450, 451, 502, 503, 504, 505, 506, 507, 558, 559, 560, 561, 562, 563,+ 452, 453, 454, 455, 456, 457, 508, 509, 510, 511, 512, 513, 564, 565, 566, 567, 568, 569,+ 458, 459, 460, 461, 462, 463, 514, 515, 516, 517, 518, 519, 570, 571, 572, 573, 574, 575]++tableReorder 48000 = + [ 0, 1, 2, 3, 12, 13, 4, 5, 6, 7, 16, 17, 8, 9, 10, 11, 20, 21,+ 14, 15, 24, 25, 26, 27, 18, 19, 28, 29, 30, 31, 22, 23, 32, 33, 34, 35,+ 36, 37, 38, 39, 48, 49, 40, 41, 42, 43, 54, 55, 44, 45, 46, 47, 60, 61,+ 50, 51, 52, 53, 66, 67, 56, 57, 58, 59, 72, 73, 62, 63, 64, 65, 78, 79,+ 68, 69, 70, 71, 84, 85, 74, 75, 76, 77, 94, 95, 80, 81, 82, 83, 104, 105,+ 86, 87, 88, 89, 90, 91, 96, 97, 98, 99, 100, 101, 106, 107, 108, 109, 110, 111,+ 92, 93, 114, 115, 116, 117, 102, 103, 126, 127, 128, 129, 112, 113, 138, 139, 140, 141,+ 118, 119, 120, 121, 122, 123, 130, 131, 132, 133, 134, 135, 142, 143, 144, 145, 146, 147,+ 124, 125, 150, 151, 152, 153, 136, 137, 164, 165, 166, 167, 148, 149, 178, 179, 180, 181,+ 154, 155, 156, 157, 158, 159, 168, 169, 170, 171, 172, 173, 182, 183, 184, 185, 186, 187,+ 160, 161, 162, 163, 192, 193, 174, 175, 176, 177, 208, 209, 188, 189, 190, 191, 224, 225,+ 194, 195, 196, 197, 198, 199, 210, 211, 212, 213, 214, 215, 226, 227, 228, 229, 230, 231,+ 200, 201, 202, 203, 204, 205, 216, 217, 218, 219, 220, 221, 232, 233, 234, 235, 236, 237,+ 206, 207, 240, 241, 242, 243, 222, 223, 260, 261, 262, 263, 238, 239, 280, 281, 282, 283,+ 244, 245, 246, 247, 248, 249, 264, 265, 266, 267, 268, 269, 284, 285, 286, 287, 288, 289,+ 250, 251, 252, 253, 254, 255, 270, 271, 272, 273, 274, 275, 290, 291, 292, 293, 294, 295,+ 256, 257, 258, 259, 300, 301, 276, 277, 278, 279, 326, 327, 296, 297, 298, 299, 352, 353,+ 302, 303, 304, 305, 306, 307, 328, 329, 330, 331, 332, 333, 354, 355, 356, 357, 358, 359,+ 308, 309, 310, 311, 312, 313, 334, 335, 336, 337, 338, 339, 360, 361, 362, 363, 364, 365,+ 314, 315, 316, 317, 318, 319, 340, 341, 342, 343, 344, 345, 366, 367, 368, 369, 370, 371,+ 320, 321, 322, 323, 324, 325, 346, 347, 348, 349, 350, 351, 372, 373, 374, 375, 376, 377,+ 378, 379, 380, 381, 382, 383, 444, 445, 446, 447, 448, 449, 510, 511, 512, 513, 514, 515,+ 384, 385, 386, 387, 388, 389, 450, 451, 452, 453, 454, 455, 516, 517, 518, 519, 520, 521,+ 390, 391, 392, 393, 394, 395, 456, 457, 458, 459, 460, 461, 522, 523, 524, 525, 526, 527,+ 396, 397, 398, 399, 400, 401, 462, 463, 464, 465, 466, 467, 528, 529, 530, 531, 532, 533,+ 402, 403, 404, 405, 406, 407, 468, 469, 470, 471, 472, 473, 534, 535, 536, 537, 538, 539,+ 408, 409, 410, 411, 412, 413, 474, 475, 476, 477, 478, 479, 540, 541, 542, 543, 544, 545,+ 414, 415, 416, 417, 418, 419, 480, 481, 482, 483, 484, 485, 546, 547, 548, 549, 550, 551,+ 420, 421, 422, 423, 424, 425, 486, 487, 488, 489, 490, 491, 552, 553, 554, 555, 556, 557,+ 426, 427, 428, 429, 430, 431, 492, 493, 494, 495, 496, 497, 558, 559, 560, 561, 562, 563,+ 432, 433, 434, 435, 436, 437, 498, 499, 500, 501, 502, 503, 564, 565, 566, 567, 568, 569,+ 438, 439, 440, 441, 442, 443, 504, 505, 506, 507, 508, 509, 570, 571, 572, 573, 574, 575]++tableReorder 32000 = + [ 0, 1, 2, 3, 12, 13, 4, 5, 6, 7, 16, 17, 8, 9, 10, 11, 20, 21,+ 14, 15, 24, 25, 26, 27, 18, 19, 28, 29, 30, 31, 22, 23, 32, 33, 34, 35,+ 36, 37, 38, 39, 48, 49, 40, 41, 42, 43, 54, 55, 44, 45, 46, 47, 60, 61,+ 50, 51, 52, 53, 66, 67, 56, 57, 58, 59, 74, 75, 62, 63, 64, 65, 82, 83,+ 68, 69, 70, 71, 72, 73, 76, 77, 78, 79, 80, 81, 84, 85, 86, 87, 88, 89,+ 90, 91, 92, 93, 94, 95, 102, 103, 104, 105, 106, 107, 114, 115, 116, 117, 118, 119,+ 96, 97, 98, 99, 100, 101, 108, 109, 110, 111, 112, 113, 120, 121, 122, 123, 124, 125,+ 126, 127, 128, 129, 130, 131, 142, 143, 144, 145, 146, 147, 158, 159, 160, 161, 162, 163,+ 132, 133, 134, 135, 136, 137, 148, 149, 150, 151, 152, 153, 164, 165, 166, 167, 168, 169,+ 138, 139, 140, 141, 174, 175, 154, 155, 156, 157, 194, 195, 170, 171, 172, 173, 214, 215,+ 176, 177, 178, 179, 180, 181, 196, 197, 198, 199, 200, 201, 216, 217, 218, 219, 220, 221,+ 182, 183, 184, 185, 186, 187, 202, 203, 204, 205, 206, 207, 222, 223, 224, 225, 226, 227,+ 188, 189, 190, 191, 192, 193, 208, 209, 210, 211, 212, 213, 228, 229, 230, 231, 232, 233,+ 234, 235, 236, 237, 238, 239, 260, 261, 262, 263, 264, 265, 286, 287, 288, 289, 290, 291,+ 240, 241, 242, 243, 244, 245, 266, 267, 268, 269, 270, 271, 292, 293, 294, 295, 296, 297,+ 246, 247, 248, 249, 250, 251, 272, 273, 274, 275, 276, 277, 298, 299, 300, 301, 302, 303,+ 252, 253, 254, 255, 256, 257, 278, 279, 280, 281, 282, 283, 304, 305, 306, 307, 308, 309,+ 258, 259, 312, 313, 314, 315, 284, 285, 346, 347, 348, 349, 310, 311, 380, 381, 382, 383,+ 316, 317, 318, 319, 320, 321, 350, 351, 352, 353, 354, 355, 384, 385, 386, 387, 388, 389,+ 322, 323, 324, 325, 326, 327, 356, 357, 358, 359, 360, 361, 390, 391, 392, 393, 394, 395,+ 328, 329, 330, 331, 332, 333, 362, 363, 364, 365, 366, 367, 396, 397, 398, 399, 400, 401,+ 334, 335, 336, 337, 338, 339, 368, 369, 370, 371, 372, 373, 402, 403, 404, 405, 406, 407,+ 340, 341, 342, 343, 344, 345, 374, 375, 376, 377, 378, 379, 408, 409, 410, 411, 412, 413,+ 414, 415, 416, 417, 418, 419, 456, 457, 458, 459, 460, 461, 498, 499, 500, 501, 502, 503,+ 420, 421, 422, 423, 424, 425, 462, 463, 464, 465, 466, 467, 504, 505, 506, 507, 508, 509,+ 426, 427, 428, 429, 430, 431, 468, 469, 470, 471, 472, 473, 510, 511, 512, 513, 514, 515,+ 432, 433, 434, 435, 436, 437, 474, 475, 476, 477, 478, 479, 516, 517, 518, 519, 520, 521,+ 438, 439, 440, 441, 442, 443, 480, 481, 482, 483, 484, 485, 522, 523, 524, 525, 526, 527,+ 444, 445, 446, 447, 448, 449, 486, 487, 488, 489, 490, 491, 528, 529, 530, 531, 532, 533,+ 450, 451, 452, 453, 454, 455, 492, 493, 494, 495, 496, 497, 534, 535, 536, 537, 538, 539,+ 540, 541, 542, 543, 544, 545, 552, 553, 554, 555, 556, 557, 564, 565, 566, 567, 568, 569,+ 546, 547, 548, 549, 550, 551, 558, 559, 560, 561, 562, 563, 570, 571, 572, 573, 574, 575]++tableReorder _ = error "Wrong SR for Table."++--+-- tableReorder2+--+-- This table does only one reordering. If we do this, we have to+-- imdct 6 [f!!0,f!!3,f!!6,f!!9,f!!12,f!!15] (see Decoder.hs)+--+tableReorder2 :: Int -> [Int]+tableReorder2 44100 = tab1+tableReorder2 48000 = tab2+tableReorder2 32000 = tab3+tableReorder2 _ = error "Wrong SR for Table."++-- The scale factor bandwidth for the first band in a short 192-granule is 4,+-- so the first 12 samples are the first 4 samples, interleaved.+tab1 :: [Int]+tab1 = [0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11,+ 12, 16, 20, 13,+ 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26,+ 30, 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39,+ 43, 47, 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52,+ 58, 64, 53, 59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69,+ 77, 85, 70, 78, 86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90,+ 100, 110, 91, 101, 111, 92, 102, 112, 93, 103, 113, 94, 104, 114, 95,+ 105, 115, 96, 106, 116, 97, 107, 117, 98, 108, 118, 99, 109, 119, 120,+ 132, 144, 121, 133, 145, 122, 134, 146, 123, 135, 147, 124, 136, 148, 125,+ 137, 149, 126, 138, 150, 127, 139, 151, 128, 140, 152, 129, 141, 153, 130,+ 142, 154, 131, 143, 155, 156, 170, 184, 157, 171, 185, 158, 172, 186, 159,+ 173, 187, 160, 174, 188, 161, 175, 189, 162, 176, 190, 163, 177, 191, 164,+ 178, 192, 165, 179, 193, 166, 180, 194, 167, 181, 195, 168, 182, 196, 169,+ 183, 197, 198, 216, 234, 199, 217, 235, 200, 218, 236, 201, 219, 237, 202,+ 220, 238, 203, 221, 239, 204, 222, 240, 205, 223, 241, 206, 224, 242, 207,+ 225, 243, 208, 226, 244, 209, 227, 245, 210, 228, 246, 211, 229, 247, 212,+ 230, 248, 213, 231, 249, 214, 232, 250, 215, 233, 251, 252, 274, 296, 253,+ 275, 297, 254, 276, 298, 255, 277, 299, 256, 278, 300, 257, 279, 301, 258,+ 280, 302, 259, 281, 303, 260, 282, 304, 261, 283, 305, 262, 284, 306, 263,+ 285, 307, 264, 286, 308, 265, 287, 309, 266, 288, 310, 267, 289, 311, 268,+ 290, 312, 269, 291, 313, 270, 292, 314, 271, 293, 315, 272, 294, 316, 273,+ 295, 317, 318, 348, 378, 319, 349, 379, 320, 350, 380, 321, 351, 381, 322,+ 352, 382, 323, 353, 383, 324, 354, 384, 325, 355, 385, 326, 356, 386, 327,+ 357, 387, 328, 358, 388, 329, 359, 389, 330, 360, 390, 331, 361, 391, 332,+ 362, 392, 333, 363, 393, 334, 364, 394, 335, 365, 395, 336, 366, 396, 337,+ 367, 397, 338, 368, 398, 339, 369, 399, 340, 370, 400, 341, 371, 401, 342,+ 372, 402, 343, 373, 403, 344, 374, 404, 345, 375, 405, 346, 376, 406, 347,+ 377, 407, 408, 464, 520, 409, 465, 521, 410, 466, 522, 411, 467, 523, 412,+ 468, 524, 413, 469, 525, 414, 470, 526, 415, 471, 527, 416, 472, 528, 417,+ 473, 529, 418, 474, 530, 419, 475, 531, 420, 476, 532, 421, 477, 533, 422,+ 478, 534, 423, 479, 535, 424, 480, 536, 425, 481, 537, 426, 482, 538, 427,+ 483, 539, 428, 484, 540, 429, 485, 541, 430, 486, 542, 431, 487, 543, 432,+ 488, 544, 433, 489, 545, 434, 490, 546, 435, 491, 547, 436, 492, 548, 437,+ 493, 549, 438, 494, 550, 439, 495, 551, 440, 496, 552, 441, 497, 553, 442,+ 498, 554, 443, 499, 555, 444, 500, 556, 445, 501, 557, 446, 502, 558, 447,+ 503, 559, 448, 504, 560, 449, 505, 561, 450, 506, 562, 451, 507, 563, 452,+ 508, 564, 453, 509, 565, 454, 510, 566, 455, 511, 567, 456, 512, 568, 457,+ 513, 569, 458, 514, 570, 459, 515, 571, 460, 516, 572, 461, 517, 573, 462,+ 518, 574, 463, 519, 575]++tab2 :: [Int]+tab2 = [0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,+ 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26,+ 30, 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39,+ 43, 47, 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52,+ 58, 64, 53, 59, 65, 66, 72, 78, 67, 73, 79, 68, 74, 80, 69,+ 75, 81, 70, 76, 82, 71, 77, 83, 84, 94, 104, 85, 95, 105, 86,+ 96, 106, 87, 97, 107, 88, 98, 108, 89, 99, 109, 90, 100, 110, 91,+ 101, 111, 92, 102, 112, 93, 103, 113, 114, 126, 138, 115, 127, 139, 116,+ 128, 140, 117, 129, 141, 118, 130, 142, 119, 131, 143, 120, 132, 144, 121,+ 133, 145, 122, 134, 146, 123, 135, 147, 124, 136, 148, 125, 137, 149, 150,+ 164, 178, 151, 165, 179, 152, 166, 180, 153, 167, 181, 154, 168, 182, 155,+ 169, 183, 156, 170, 184, 157, 171, 185, 158, 172, 186, 159, 173, 187, 160,+ 174, 188, 161, 175, 189, 162, 176, 190, 163, 177, 191, 192, 208, 224, 193,+ 209, 225, 194, 210, 226, 195, 211, 227, 196, 212, 228, 197, 213, 229, 198,+ 214, 230, 199, 215, 231, 200, 216, 232, 201, 217, 233, 202, 218, 234, 203,+ 219, 235, 204, 220, 236, 205, 221, 237, 206, 222, 238, 207, 223, 239, 240,+ 260, 280, 241, 261, 281, 242, 262, 282, 243, 263, 283, 244, 264, 284, 245,+ 265, 285, 246, 266, 286, 247, 267, 287, 248, 268, 288, 249, 269, 289, 250,+ 270, 290, 251, 271, 291, 252, 272, 292, 253, 273, 293, 254, 274, 294, 255,+ 275, 295, 256, 276, 296, 257, 277, 297, 258, 278, 298, 259, 279, 299, 300,+ 326, 352, 301, 327, 353, 302, 328, 354, 303, 329, 355, 304, 330, 356, 305,+ 331, 357, 306, 332, 358, 307, 333, 359, 308, 334, 360, 309, 335, 361, 310,+ 336, 362, 311, 337, 363, 312, 338, 364, 313, 339, 365, 314, 340, 366, 315,+ 341, 367, 316, 342, 368, 317, 343, 369, 318, 344, 370, 319, 345, 371, 320,+ 346, 372, 321, 347, 373, 322, 348, 374, 323, 349, 375, 324, 350, 376, 325,+ 351, 377, 378, 444, 510, 379, 445, 511, 380, 446, 512, 381, 447, 513, 382,+ 448, 514, 383, 449, 515, 384, 450, 516, 385, 451, 517, 386, 452, 518, 387,+ 453, 519, 388, 454, 520, 389, 455, 521, 390, 456, 522, 391, 457, 523, 392,+ 458, 524, 393, 459, 525, 394, 460, 526, 395, 461, 527, 396, 462, 528, 397,+ 463, 529, 398, 464, 530, 399, 465, 531, 400, 466, 532, 401, 467, 533, 402,+ 468, 534, 403, 469, 535, 404, 470, 536, 405, 471, 537, 406, 472, 538, 407,+ 473, 539, 408, 474, 540, 409, 475, 541, 410, 476, 542, 411, 477, 543, 412,+ 478, 544, 413, 479, 545, 414, 480, 546, 415, 481, 547, 416, 482, 548, 417,+ 483, 549, 418, 484, 550, 419, 485, 551, 420, 486, 552, 421, 487, 553, 422,+ 488, 554, 423, 489, 555, 424, 490, 556, 425, 491, 557, 426, 492, 558, 427,+ 493, 559, 428, 494, 560, 429, 495, 561, 430, 496, 562, 431, 497, 563, 432,+ 498, 564, 433, 499, 565, 434, 500, 566, 435, 501, 567, 436, 502, 568, 437,+ 503, 569, 438, 504, 570, 439, 505, 571, 440, 506, 572, 441, 507, 573, 442,+ 508, 574, 443, 509, 575]++tab3 :: [Int]+tab3 = [0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,+ 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26,+ 30, 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39,+ 43, 47, 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52,+ 58, 64, 53, 59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69,+ 77, 85, 70, 78, 86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90,+ 102, 114, 91, 103, 115, 92, 104, 116, 93, 105, 117, 94, 106, 118, 95,+ 107, 119, 96, 108, 120, 97, 109, 121, 98, 110, 122, 99, 111, 123, 100,+ 112, 124, 101, 113, 125, 126, 142, 158, 127, 143, 159, 128, 144, 160, 129,+ 145, 161, 130, 146, 162, 131, 147, 163, 132, 148, 164, 133, 149, 165, 134,+ 150, 166, 135, 151, 167, 136, 152, 168, 137, 153, 169, 138, 154, 170, 139,+ 155, 171, 140, 156, 172, 141, 157, 173, 174, 194, 214, 175, 195, 215, 176,+ 196, 216, 177, 197, 217, 178, 198, 218, 179, 199, 219, 180, 200, 220, 181,+ 201, 221, 182, 202, 222, 183, 203, 223, 184, 204, 224, 185, 205, 225, 186,+ 206, 226, 187, 207, 227, 188, 208, 228, 189, 209, 229, 190, 210, 230, 191,+ 211, 231, 192, 212, 232, 193, 213, 233, 234, 260, 286, 235, 261, 287, 236,+ 262, 288, 237, 263, 289, 238, 264, 290, 239, 265, 291, 240, 266, 292, 241,+ 267, 293, 242, 268, 294, 243, 269, 295, 244, 270, 296, 245, 271, 297, 246,+ 272, 298, 247, 273, 299, 248, 274, 300, 249, 275, 301, 250, 276, 302, 251,+ 277, 303, 252, 278, 304, 253, 279, 305, 254, 280, 306, 255, 281, 307, 256,+ 282, 308, 257, 283, 309, 258, 284, 310, 259, 285, 311, 312, 346, 380, 313,+ 347, 381, 314, 348, 382, 315, 349, 383, 316, 350, 384, 317, 351, 385, 318,+ 352, 386, 319, 353, 387, 320, 354, 388, 321, 355, 389, 322, 356, 390, 323,+ 357, 391, 324, 358, 392, 325, 359, 393, 326, 360, 394, 327, 361, 395, 328,+ 362, 396, 329, 363, 397, 330, 364, 398, 331, 365, 399, 332, 366, 400, 333,+ 367, 401, 334, 368, 402, 335, 369, 403, 336, 370, 404, 337, 371, 405, 338,+ 372, 406, 339, 373, 407, 340, 374, 408, 341, 375, 409, 342, 376, 410, 343,+ 377, 411, 344, 378, 412, 345, 379, 413, 414, 456, 498, 415, 457, 499, 416,+ 458, 500, 417, 459, 501, 418, 460, 502, 419, 461, 503, 420, 462, 504, 421,+ 463, 505, 422, 464, 506, 423, 465, 507, 424, 466, 508, 425, 467, 509, 426,+ 468, 510, 427, 469, 511, 428, 470, 512, 429, 471, 513, 430, 472, 514, 431,+ 473, 515, 432, 474, 516, 433, 475, 517, 434, 476, 518, 435, 477, 519, 436,+ 478, 520, 437, 479, 521, 438, 480, 522, 439, 481, 523, 440, 482, 524, 441,+ 483, 525, 442, 484, 526, 443, 485, 527, 444, 486, 528, 445, 487, 529, 446,+ 488, 530, 447, 489, 531, 448, 490, 532, 449, 491, 533, 450, 492, 534, 451,+ 493, 535, 452, 494, 536, 453, 495, 537, 454, 496, 538, 455, 497, 539, 540,+ 552, 564, 541, 553, 565, 542, 554, 566, 543, 555, 567, 544, 556, 568, 545,+ 557, 569, 546, 558, 570, 547, 559, 571, 548, 560, 572, 549, 561, 573, 550,+ 562, 574, 551, 563, 575]+++-- +-- tableHuffmanQuad, tableHuffman+--+-- The Huffman tables and table pairs.+--+tableHuffmanQuad :: [[([Int], (Int, Int, Int, Int))]]+tableHuffmanQuad = [tableHuffRqa, -- 0 + tableHuffRqb] -- 1++tableHuffman :: [([([Int], (Int, Int))], Int)]+tableHuffman = [error "Huffman Table 0 does not exist.",+ (tableHuffR00, 0), -- 1+ (tableHuffR01, 0), -- 2 + (tableHuffR02, 0), -- 3+ error "Huffman Table 4 does not exist.",+ (tableHuffR03, 0), -- 5+ (tableHuffR04, 0), -- 6+ (tableHuffR05, 0), -- 7+ (tableHuffR06, 0), -- 8+ (tableHuffR07, 0), -- 9+ (tableHuffR08, 0), -- 10+ (tableHuffR09, 0), -- 11+ (tableHuffR10, 0), -- 12+ (tableHuffR11, 0), -- 13+ error "Huffman Table 14 does not exist.",+ (tableHuffR12, 0), -- 15+ (tableHuffR13, 1), -- 16+ (tableHuffR13, 2), -- 17+ (tableHuffR13, 3), -- 18 + (tableHuffR13, 4), -- 19+ (tableHuffR13, 6), -- 20+ (tableHuffR13, 8), -- 21+ (tableHuffR13, 10), -- 22+ (tableHuffR13, 13), -- 23+ (tableHuffR14, 4), -- 24+ (tableHuffR14, 5), -- 25+ (tableHuffR14, 6), -- 26+ (tableHuffR14, 7), -- 27+ (tableHuffR14, 8), -- 28+ (tableHuffR14, 9), -- 29+ (tableHuffR14, 11), -- 30+ (tableHuffR14, 13)] -- 31+++-- Not exported:+tableHuffRqa :: [([Int], (Int, Int, Int, Int))]+tableHuffRqa = [([1],(0,0,0,0)),+ ([0,1,0,1],(0,0,0,1)),+ ([0,1,0,0],(0,0,1,0)),+ ([0,0,1,0,1],(0,0,1,1)),+ ([0,1,1,0],(0,1,0,0)),+ ([0,0,0,1,0,1],(0,1,0,1)),+ ([0,0,1,0,0],(0,1,1,0)),+ ([0,0,0,1,0,0],(0,1,1,1)),+ ([0,1,1,1],(1,0,0,0)),+ ([0,0,0,1,1],(1,0,0,1)),+ ([0,0,1,1,0],(1,0,1,0)),+ ([0,0,0,0,0,0],(1,0,1,1)),+ ([0,0,1,1,1],(1,1,0,0)),+ ([0,0,0,0,1,0],(1,1,0,1)),+ ([0,0,0,0,1,1],(1,1,1,0)),+ ([0,0,0,0,0,1],(1,1,1,1))]++tableHuffRqb :: [([Int], (Int, Int, Int, Int))]+tableHuffRqb = [([1,1,1,1],(0,0,0,0)),+ ([1,1,1,0],(0,0,0,1)),+ ([1,1,0,1],(0,0,1,0)),+ ([1,1,0,0],(0,0,1,1)),+ ([1,0,1,1],(0,1,0,0)),+ ([1,0,1,0],(0,1,0,1)),+ ([1,0,0,1],(0,1,1,0)),+ ([1,0,0,0],(0,1,1,1)),+ ([0,1,1,1],(1,0,0,0)),+ ([0,1,1,0],(1,0,0,1)),+ ([0,1,0,1],(1,0,1,0)),+ ([0,1,0,0],(1,0,1,1)),+ ([0,0,1,1],(1,1,0,0)),+ ([0,0,1,0],(1,1,0,1)),+ ([0,0,0,1],(1,1,1,0)),+ ([0,0,0,0],(1,1,1,1))]++tableHuffR00 :: [([Int], (Int, Int))]+tableHuffR00 = [([1],(0,0)),+ ([0,0,1],(0,1)),+ ([0,1],(1,0)),+ ([0,0,0],(1,1))]++tableHuffR01 :: [([Int], (Int, Int))]+tableHuffR01 = [([1],(0,0)),+ ([0,1,0],(0,1)),+ ([0,0,0,0,0,1],(0,2)),+ ([0,1,1],(1,0)),+ ([0,0,1],(1,1)),+ ([0,0,0,0,1],(1,2)),+ ([0,0,0,1,1],(2,0)),+ ([0,0,0,1,0],(2,1)),+ ([0,0,0,0,0,0],(2,2))]++tableHuffR02 :: [([Int], (Int, Int))]+tableHuffR02 = [([1,1],(0,0)),+ ([1,0],(0,1)),+ ([0,0,0,0,0,1],(0,2)),+ ([0,0,1],(1,0)),+ ([0,1],(1,1)),+ ([0,0,0,0,1],(1,2)),+ ([0,0,0,1,1],(2,0)),+ ([0,0,0,1,0],(2,1)),+ ([0,0,0,0,0,0],(2,2))]++tableHuffR03 :: [([Int], (Int, Int))]+tableHuffR03 = [([1],(0,0)),+ ([0,1,0],(0,1)),+ ([0,0,0,1,1,0],(0,2)),+ ([0,0,0,0,1,0,1],(0,3)),+ ([0,1,1],(1,0)),+ ([0,0,1],(1,1)),+ ([0,0,0,1,0,0],(1,2)),+ ([0,0,0,0,1,0,0],(1,3)),+ ([0,0,0,1,1,1],(2,0)),+ ([0,0,0,1,0,1],(2,1)),+ ([0,0,0,0,1,1,1],(2,2)),+ ([0,0,0,0,0,0,0,1],(2,3)),+ ([0,0,0,0,1,1,0],(3,0)),+ ([0,0,0,0,0,1],(3,1)),+ ([0,0,0,0,0,0,1],(3,2)),+ ([0,0,0,0,0,0,0,0],(3,3))]++tableHuffR04 :: [([Int], (Int, Int))]+tableHuffR04 = [([1,1,1],(0,0)),+ ([0,1,1],(0,1)),+ ([0,0,1,0,1],(0,2)),+ ([0,0,0,0,0,0,1],(0,3)),+ ([1,1,0],(1,0)),+ ([1,0],(1,1)),+ ([0,0,1,1],(1,2)),+ ([0,0,0,1,0],(1,3)),+ ([0,1,0,1],(2,0)),+ ([0,1,0,0],(2,1)),+ ([0,0,1,0,0],(2,2)),+ ([0,0,0,0,0,1],(2,3)),+ ([0,0,0,0,1,1],(3,0)),+ ([0,0,0,1,1],(3,1)),+ ([0,0,0,0,1,0],(3,2)),+ ([0,0,0,0,0,0,0],(3,3))]++tableHuffR05 :: [([Int], (Int, Int))]+tableHuffR05 = [([1],(0,0)),+ ([0,1,0],(0,1)),+ ([0,0,1,0,1,0],(0,2)),+ ([0,0,0,1,0,0,1,1],(0,3)),+ ([0,0,0,1,0,0,0,0],(0,4)),+ ([0,0,0,0,0,1,0,1,0],(0,5)),+ ([0,1,1],(1,0)),+ ([0,0,1,1],(1,1)),+ ([0,0,0,1,1,1],(1,2)),+ ([0,0,0,1,0,1,0],(1,3)),+ ([0,0,0,0,1,0,1],(1,4)),+ ([0,0,0,0,0,0,1,1],(1,5)),+ ([0,0,1,0,1,1],(2,0)),+ ([0,0,1,0,0],(2,1)),+ ([0,0,0,1,1,0,1],(2,2)),+ ([0,0,0,1,0,0,0,1],(2,3)),+ ([0,0,0,0,1,0,0,0],(2,4)),+ ([0,0,0,0,0,0,1,0,0],(2,5)),+ ([0,0,0,1,1,0,0],(3,0)),+ ([0,0,0,1,0,1,1],(3,1)),+ ([0,0,0,1,0,0,1,0],(3,2)),+ ([0,0,0,0,0,1,1,1,1],(3,3)),+ ([0,0,0,0,0,1,0,1,1],(3,4)),+ ([0,0,0,0,0,0,0,1,0],(3,5)),+ ([0,0,0,0,1,1,1],(4,0)),+ ([0,0,0,0,1,1,0],(4,1)),+ ([0,0,0,0,1,0,0,1],(4,2)),+ ([0,0,0,0,0,1,1,1,0],(4,3)),+ ([0,0,0,0,0,0,0,1,1],(4,4)),+ ([0,0,0,0,0,0,0,0,0,1],(4,5)),+ ([0,0,0,0,0,1,1,0],(5,0)),+ ([0,0,0,0,0,1,0,0],(5,1)),+ ([0,0,0,0,0,0,1,0,1],(5,2)),+ ([0,0,0,0,0,0,0,0,1,1],(5,3)),+ ([0,0,0,0,0,0,0,0,1,0],(5,4)),+ ([0,0,0,0,0,0,0,0,0,0],(5,5))]++tableHuffR06 :: [([Int], (Int, Int))]+tableHuffR06 = [([1,1],(0,0)),+ ([1,0,0],(0,1)),+ ([0,0,0,1,1,0],(0,2)),+ ([0,0,0,1,0,0,1,0],(0,3)),+ ([0,0,0,0,1,1,0,0],(0,4)),+ ([0,0,0,0,0,0,1,0,1],(0,5)),+ ([1,0,1],(1,0)),+ ([0,1],(1,1)),+ ([0,0,1,0],(1,2)),+ ([0,0,0,1,0,0,0,0],(1,3)),+ ([0,0,0,0,1,0,0,1],(1,4)),+ ([0,0,0,0,0,0,1,1],(1,5)),+ ([0,0,0,1,1,1],(2,0)),+ ([0,0,1,1],(2,1)),+ ([0,0,0,1,0,1],(2,2)),+ ([0,0,0,0,1,1,1,0],(2,3)),+ ([0,0,0,0,0,1,1,1],(2,4)),+ ([0,0,0,0,0,0,0,1,1],(2,5)),+ ([0,0,0,1,0,0,1,1],(3,0)),+ ([0,0,0,1,0,0,0,1],(3,1)),+ ([0,0,0,0,1,1,1,1],(3,2)),+ ([0,0,0,0,0,1,1,0,1],(3,3)),+ ([0,0,0,0,0,1,0,1,0],(3,4)),+ ([0,0,0,0,0,0,0,1,0,0],(3,5)),+ ([0,0,0,0,1,1,0,1],(4,0)),+ ([0,0,0,0,1,0,1],(4,1)),+ ([0,0,0,0,1,0,0,0],(4,2)),+ ([0,0,0,0,0,1,0,1,1],(4,3)),+ ([0,0,0,0,0,0,0,1,0,1],(4,4)),+ ([0,0,0,0,0,0,0,0,0,1],(4,5)),+ ([0,0,0,0,0,1,1,0,0],(5,0)),+ ([0,0,0,0,0,1,0,0],(5,1)),+ ([0,0,0,0,0,0,1,0,0],(5,2)),+ ([0,0,0,0,0,0,0,0,1],(5,3)),+ ([0,0,0,0,0,0,0,0,0,0,1],(5,4)),+ ([0,0,0,0,0,0,0,0,0,0,0],(5,5))]++tableHuffR07 :: [([Int], (Int, Int))]+tableHuffR07 = [([1,1,1],(0,0)),+ ([1,0,1],(0,1)),+ ([0,1,0,0,1],(0,2)),+ ([0,0,1,1,1,0],(0,3)),+ ([0,0,0,0,1,1,1,1],(0,4)),+ ([0,0,0,0,0,0,1,1,1],(0,5)),+ ([1,1,0],(1,0)),+ ([1,0,0],(1,1)),+ ([0,1,0,1],(1,2)),+ ([0,0,1,0,1],(1,3)),+ ([0,0,0,1,1,0],(1,4)),+ ([0,0,0,0,0,1,1,1],(1,5)),+ ([0,1,1,1],(2,0)),+ ([0,1,1,0],(2,1)),+ ([0,1,0,0,0],(2,2)),+ ([0,0,1,0,0,0],(2,3)),+ ([0,0,0,1,0,0,0],(2,4)),+ ([0,0,0,0,0,1,0,1],(2,5)),+ ([0,0,1,1,1,1],(3,0)),+ ([0,0,1,1,0],(3,1)),+ ([0,0,1,0,0,1],(3,2)),+ ([0,0,0,1,0,1,0],(3,3)),+ ([0,0,0,0,1,0,1],(3,4)),+ ([0,0,0,0,0,0,0,1],(3,5)),+ ([0,0,0,1,0,1,1],(4,0)),+ ([0,0,0,1,1,1],(4,1)),+ ([0,0,0,1,0,0,1],(4,2)),+ ([0,0,0,0,1,1,0],(4,3)),+ ([0,0,0,0,0,1,0,0],(4,4)),+ ([0,0,0,0,0,0,0,0,1],(4,5)),+ ([0,0,0,0,1,1,1,0],(5,0)),+ ([0,0,0,0,1,0,0],(5,1)),+ ([0,0,0,0,0,1,1,0],(5,2)),+ ([0,0,0,0,0,0,1,0],(5,3)),+ ([0,0,0,0,0,0,1,1,0],(5,4)),+ ([0,0,0,0,0,0,0,0,0],(5,5))]++tableHuffR08 :: [([Int], (Int, Int))]+tableHuffR08 = [([1],(0,0)),+ ([0,1,0],(0,1)),+ ([0,0,1,0,1,0],(0,2)),+ ([0,0,0,1,0,1,1,1],(0,3)),+ ([0,0,0,1,0,0,0,1,1],(0,4)),+ ([0,0,0,0,1,1,1,1,0],(0,5)),+ ([0,0,0,0,0,1,1,0,0],(0,6)),+ ([0,0,0,0,0,1,0,0,0,1],(0,7)),+ ([0,1,1],(1,0)),+ ([0,0,1,1],(1,1)),+ ([0,0,1,0,0,0],(1,2)),+ ([0,0,0,1,1,0,0],(1,3)),+ ([0,0,0,1,0,0,1,0],(1,4)),+ ([0,0,0,0,1,0,1,0,1],(1,5)),+ ([0,0,0,0,1,1,0,0],(1,6)),+ ([0,0,0,0,0,1,1,1],(1,7)),+ ([0,0,1,0,1,1],(2,0)),+ ([0,0,1,0,0,1],(2,1)),+ ([0,0,0,1,1,1,1],(2,2)),+ ([0,0,0,1,0,1,0,1],(2,3)),+ ([0,0,0,1,0,0,0,0,0],(2,4)),+ ([0,0,0,0,1,0,1,0,0,0],(2,5)),+ ([0,0,0,0,1,0,0,1,1],(2,6)),+ ([0,0,0,0,0,0,1,1,0],(2,7)),+ ([0,0,0,1,1,1,0],(3,0)),+ ([0,0,0,1,1,0,1],(3,1)),+ ([0,0,0,1,0,1,1,0],(3,2)),+ ([0,0,0,1,0,0,0,1,0],(3,3)),+ ([0,0,0,0,1,0,1,1,1,0],(3,4)),+ ([0,0,0,0,0,1,0,1,1,1],(3,5)),+ ([0,0,0,0,1,0,0,1,0],(3,6)),+ ([0,0,0,0,0,0,0,1,1,1],(3,7)),+ ([0,0,0,1,0,1,0,0],(4,0)),+ ([0,0,0,1,0,0,1,1],(4,1)),+ ([0,0,0,1,0,0,0,0,1],(4,2)),+ ([0,0,0,0,1,0,1,1,1,1],(4,3)),+ ([0,0,0,0,0,1,1,0,1,1],(4,4)),+ ([0,0,0,0,0,1,0,1,1,0],(4,5)),+ ([0,0,0,0,0,0,1,0,0,1],(4,6)),+ ([0,0,0,0,0,0,0,0,1,1],(4,7)),+ ([0,0,0,0,1,1,1,1,1],(5,0)),+ ([0,0,0,0,1,0,1,1,0],(5,1)),+ ([0,0,0,0,1,0,1,0,0,1],(5,2)),+ ([0,0,0,0,0,1,1,0,1,0],(5,3)),+ ([0,0,0,0,0,0,1,0,1,0,1],(5,4)),+ ([0,0,0,0,0,0,1,0,1,0,0],(5,5)),+ ([0,0,0,0,0,0,0,1,0,1],(5,6)),+ ([0,0,0,0,0,0,0,0,0,1,1],(5,7)),+ ([0,0,0,0,1,1,1,0],(6,0)),+ ([0,0,0,0,1,1,0,1],(6,1)),+ ([0,0,0,0,0,1,0,1,0],(6,2)),+ ([0,0,0,0,0,0,1,0,1,1],(6,3)),+ ([0,0,0,0,0,1,0,0,0,0],(6,4)),+ ([0,0,0,0,0,0,0,1,1,0],(6,5)),+ ([0,0,0,0,0,0,0,0,1,0,1],(6,6)),+ ([0,0,0,0,0,0,0,0,0,0,1],(6,7)),+ ([0,0,0,0,0,1,0,0,1],(7,0)),+ ([0,0,0,0,1,0,0,0],(7,1)),+ ([0,0,0,0,0,0,1,1,1],(7,2)),+ ([0,0,0,0,0,0,1,0,0,0],(7,3)),+ ([0,0,0,0,0,0,0,1,0,0],(7,4)),+ ([0,0,0,0,0,0,0,0,1,0,0],(7,5)),+ ([0,0,0,0,0,0,0,0,0,1,0],(7,6)),+ ([0,0,0,0,0,0,0,0,0,0,0],(7,7))]++tableHuffR09 :: [([Int], (Int, Int))]+tableHuffR09 = [([1,1],(0,0)),+ ([1,0,0],(0,1)),+ ([0,1,0,1,0],(0,2)),+ ([0,0,1,1,0,0,0],(0,3)),+ ([0,0,1,0,0,0,1,0],(0,4)),+ ([0,0,0,1,0,0,0,0,1],(0,5)),+ ([0,0,0,1,0,1,0,1],(0,6)),+ ([0,0,0,0,0,1,1,1,1],(0,7)),+ ([1,0,1],(1,0)),+ ([0,1,1],(1,1)),+ ([0,1,0,0],(1,2)),+ ([0,0,1,0,1,0],(1,3)),+ ([0,0,1,0,0,0,0,0],(1,4)),+ ([0,0,0,1,0,0,0,1],(1,5)),+ ([0,0,0,1,0,1,1],(1,6)),+ ([0,0,0,0,1,0,1,0],(1,7)),+ ([0,1,0,1,1],(2,0)),+ ([0,0,1,1,1],(2,1)),+ ([0,0,1,1,0,1],(2,2)),+ ([0,0,1,0,0,1,0],(2,3)),+ ([0,0,0,1,1,1,1,0],(2,4)),+ ([0,0,0,0,1,1,1,1,1],(2,5)),+ ([0,0,0,1,0,1,0,0],(2,6)),+ ([0,0,0,0,0,1,0,1],(2,7)),+ ([0,0,1,1,0,0,1],(3,0)),+ ([0,0,1,0,1,1],(3,1)),+ ([0,0,1,0,0,1,1],(3,2)),+ ([0,0,0,1,1,1,0,1,1],(3,3)),+ ([0,0,0,1,1,0,1,1],(3,4)),+ ([0,0,0,0,0,1,0,0,1,0],(3,5)),+ ([0,0,0,0,1,1,0,0],(3,6)),+ ([0,0,0,0,0,0,1,0,1],(3,7)),+ ([0,0,1,0,0,0,1,1],(4,0)),+ ([0,0,1,0,0,0,0,1],(4,1)),+ ([0,0,0,1,1,1,1,1],(4,2)),+ ([0,0,0,1,1,1,0,1,0],(4,3)),+ ([0,0,0,0,1,1,1,1,0],(4,4)),+ ([0,0,0,0,0,1,0,0,0,0],(4,5)),+ ([0,0,0,0,0,0,1,1,1],(4,6)),+ ([0,0,0,0,0,0,0,1,0,1],(4,7)),+ ([0,0,0,1,1,1,0,0],(5,0)),+ ([0,0,0,1,1,0,1,0],(5,1)),+ ([0,0,0,1,0,0,0,0,0],(5,2)),+ ([0,0,0,0,0,1,0,0,1,1],(5,3)),+ ([0,0,0,0,0,1,0,0,0,1],(5,4)),+ ([0,0,0,0,0,0,0,1,1,1,1],(5,5)),+ ([0,0,0,0,0,0,1,0,0,0],(5,6)),+ ([0,0,0,0,0,0,0,1,1,1,0],(5,7)),+ ([0,0,0,0,1,1,1,0],(6,0)),+ ([0,0,0,1,1,0,0],(6,1)),+ ([0,0,0,1,0,0,1],(6,2)),+ ([0,0,0,0,1,1,0,1],(6,3)),+ ([0,0,0,0,0,1,1,1,0],(6,4)),+ ([0,0,0,0,0,0,1,0,0,1],(6,5)),+ ([0,0,0,0,0,0,0,1,0,0],(6,6)),+ ([0,0,0,0,0,0,0,0,0,1],(6,7)),+ ([0,0,0,0,1,0,1,1],(7,0)),+ ([0,0,0,0,1,0,0],(7,1)),+ ([0,0,0,0,0,1,1,0],(7,2)),+ ([0,0,0,0,0,0,1,1,0],(7,3)),+ ([0,0,0,0,0,0,0,1,1,0],(7,4)),+ ([0,0,0,0,0,0,0,0,1,1],(7,5)),+ ([0,0,0,0,0,0,0,0,1,0],(7,6)),+ ([0,0,0,0,0,0,0,0,0,0],(7,7))]++tableHuffR10 :: [([Int], (Int, Int))]+tableHuffR10 = [([1,0,0,1],(0,0)),+ ([1,1,0],(0,1)),+ ([1,0,0,0,0],(0,2)),+ ([0,1,0,0,0,0,1],(0,3)),+ ([0,0,1,0,1,0,0,1],(0,4)),+ ([0,0,0,1,0,0,1,1,1],(0,5)),+ ([0,0,0,1,0,0,1,1,0],(0,6)),+ ([0,0,0,0,1,1,0,1,0],(0,7)),+ ([1,1,1],(1,0)),+ ([1,0,1],(1,1)),+ ([0,1,1,0],(1,2)),+ ([0,1,0,0,1],(1,3)),+ ([0,0,1,0,1,1,1],(1,4)),+ ([0,0,1,0,0,0,0],(1,5)),+ ([0,0,0,1,1,0,1,0],(1,6)),+ ([0,0,0,0,1,0,1,1],(1,7)),+ ([1,0,0,0,1],(2,0)),+ ([0,1,1,1],(2,1)),+ ([0,1,0,1,1],(2,2)),+ ([0,0,1,1,1,0],(2,3)),+ ([0,0,1,0,1,0,1],(2,4)),+ ([0,0,0,1,1,1,1,0],(2,5)),+ ([0,0,0,1,0,1,0],(2,6)),+ ([0,0,0,0,0,1,1,1],(2,7)),+ ([0,1,0,0,0,1],(3,0)),+ ([0,1,0,1,0],(3,1)),+ ([0,0,1,1,1,1],(3,2)),+ ([0,0,1,1,0,0],(3,3)),+ ([0,0,1,0,0,1,0],(3,4)),+ ([0,0,0,1,1,1,0,0],(3,5)),+ ([0,0,0,0,1,1,1,0],(3,6)),+ ([0,0,0,0,0,1,0,1],(3,7)),+ ([0,1,0,0,0,0,0],(4,0)),+ ([0,0,1,1,0,1],(4,1)),+ ([0,0,1,0,1,1,0],(4,2)),+ ([0,0,1,0,0,1,1],(4,3)),+ ([0,0,0,1,0,0,1,0],(4,4)),+ ([0,0,0,1,0,0,0,0],(4,5)),+ ([0,0,0,0,1,0,0,1],(4,6)),+ ([0,0,0,0,0,0,1,0,1],(4,7)),+ ([0,0,1,0,1,0,0,0],(5,0)),+ ([0,0,1,0,0,0,1],(5,1)),+ ([0,0,0,1,1,1,1,1],(5,2)),+ ([0,0,0,1,1,1,0,1],(5,3)),+ ([0,0,0,1,0,0,0,1],(5,4)),+ ([0,0,0,0,0,1,1,0,1],(5,5)),+ ([0,0,0,0,0,1,0,0],(5,6)),+ ([0,0,0,0,0,0,0,1,0],(5,7)),+ ([0,0,0,1,1,0,1,1],(6,0)),+ ([0,0,0,1,1,0,0],(6,1)),+ ([0,0,0,1,0,1,1],(6,2)),+ ([0,0,0,0,1,1,1,1],(6,3)),+ ([0,0,0,0,1,0,1,0],(6,4)),+ ([0,0,0,0,0,0,1,1,1],(6,5)),+ ([0,0,0,0,0,0,1,0,0],(6,6)),+ ([0,0,0,0,0,0,0,0,0,1],(6,7)),+ ([0,0,0,0,1,1,0,1,1],(7,0)),+ ([0,0,0,0,1,1,0,0],(7,1)),+ ([0,0,0,0,1,0,0,0],(7,2)),+ ([0,0,0,0,0,1,1,0,0],(7,3)),+ ([0,0,0,0,0,0,1,1,0],(7,4)),+ ([0,0,0,0,0,0,0,1,1],(7,5)),+ ([0,0,0,0,0,0,0,0,1],(7,6)),+ ([0,0,0,0,0,0,0,0,0,0],(7,7))]++tableHuffR11 :: [([Int], (Int, Int))]+tableHuffR11 = [([1],(0,0)),+ ([0,1,0,1],(0,1)),+ ([0,0,1,1,1,0],(0,2)),+ ([0,0,1,0,1,0,1],(0,3)),+ ([0,0,1,0,0,0,1,0],(0,4)),+ ([0,0,0,1,1,0,0,1,1],(0,5)),+ ([0,0,0,1,0,1,1,1,0],(0,6)),+ ([0,0,0,1,0,0,0,1,1,1],(0,7)),+ ([0,0,0,1,0,1,0,1,0],(0,8)),+ ([0,0,0,0,1,1,0,1,0,0],(0,9)),+ ([0,0,0,0,1,0,0,0,1,0,0],(0,10)),+ ([0,0,0,0,0,1,1,0,1,0,0],(0,11)),+ ([0,0,0,0,0,1,0,0,0,0,1,1],(0,12)),+ ([0,0,0,0,0,0,1,0,1,1,0,0],(0,13)),+ ([0,0,0,0,0,0,0,1,0,1,0,1,1],(0,14)),+ ([0,0,0,0,0,0,0,0,1,0,0,1,1],(0,15)),+ ([0,1,1],(1,0)),+ ([0,1,0,0],(1,1)),+ ([0,0,1,1,0,0],(1,2)),+ ([0,0,1,0,0,1,1],(1,3)),+ ([0,0,0,1,1,1,1,1],(1,4)),+ ([0,0,0,1,1,0,1,0],(1,5)),+ ([0,0,0,1,0,1,1,0,0],(1,6)),+ ([0,0,0,1,0,0,0,0,1],(1,7)),+ ([0,0,0,0,1,1,1,1,1],(1,8)),+ ([0,0,0,0,1,1,0,0,0],(1,9)),+ ([0,0,0,0,1,0,0,0,0,0],(1,10)),+ ([0,0,0,0,0,1,1,0,0,0],(1,11)),+ ([0,0,0,0,0,0,1,1,1,1,1],(1,12)),+ ([0,0,0,0,0,0,1,0,0,0,1,1],(1,13)),+ ([0,0,0,0,0,0,0,1,0,1,1,0],(1,14)),+ ([0,0,0,0,0,0,0,0,1,1,1,0],(1,15)),+ ([0,0,1,1,1,1],(2,0)),+ ([0,0,1,1,0,1],(2,1)),+ ([0,0,1,0,1,1,1],(2,2)),+ ([0,0,1,0,0,1,0,0],(2,3)),+ ([0,0,0,1,1,1,0,1,1],(2,4)),+ ([0,0,0,1,1,0,0,0,1],(2,5)),+ ([0,0,0,1,0,0,1,1,0,1],(2,6)),+ ([0,0,0,1,0,0,0,0,0,1],(2,7)),+ ([0,0,0,0,1,1,1,0,1],(2,8)),+ ([0,0,0,0,1,0,1,0,0,0],(2,9)),+ ([0,0,0,0,0,1,1,1,1,0],(2,10)),+ ([0,0,0,0,0,1,0,1,0,0,0],(2,11)),+ ([0,0,0,0,0,0,1,1,0,1,1],(2,12)),+ ([0,0,0,0,0,0,1,0,0,0,0,1],(2,13)),+ ([0,0,0,0,0,0,0,1,0,1,0,1,0],(2,14)),+ ([0,0,0,0,0,0,0,0,1,0,0,0,0],(2,15)),+ ([0,0,1,0,1,1,0],(3,0)),+ ([0,0,1,0,1,0,0],(3,1)),+ ([0,0,1,0,0,1,0,1],(3,2)),+ ([0,0,0,1,1,1,1,0,1],(3,3)),+ ([0,0,0,1,1,1,0,0,0],(3,4)),+ ([0,0,0,1,0,0,1,1,1,1],(3,5)),+ ([0,0,0,1,0,0,1,0,0,1],(3,6)),+ ([0,0,0,1,0,0,0,0,0,0],(3,7)),+ ([0,0,0,0,1,0,1,0,1,1],(3,8)),+ ([0,0,0,0,1,0,0,1,1,0,0],(3,9)),+ ([0,0,0,0,0,1,1,1,0,0,0],(3,10)),+ ([0,0,0,0,0,1,0,0,1,0,1],(3,11)),+ ([0,0,0,0,0,0,1,1,0,1,0],(3,12)),+ ([0,0,0,0,0,0,0,1,1,1,1,1],(3,13)),+ ([0,0,0,0,0,0,0,0,1,1,0,0,1],(3,14)),+ ([0,0,0,0,0,0,0,0,0,1,1,1,0],(3,15)),+ ([0,0,1,0,0,0,1,1],(4,0)),+ ([0,0,1,0,0,0,0],(4,1)),+ ([0,0,0,1,1,1,1,0,0],(4,2)),+ ([0,0,0,1,1,1,0,0,1],(4,3)),+ ([0,0,0,1,1,0,0,0,0,1],(4,4)),+ ([0,0,0,1,0,0,1,0,1,1],(4,5)),+ ([0,0,0,0,1,1,1,0,0,1,0],(4,6)),+ ([0,0,0,0,1,0,1,1,0,1,1],(4,7)),+ ([0,0,0,0,1,1,0,1,1,0],(4,8)),+ ([0,0,0,0,1,0,0,1,0,0,1],(4,9)),+ ([0,0,0,0,0,1,1,0,1,1,1],(4,10)),+ ([0,0,0,0,0,0,1,0,1,0,0,1],(4,11)),+ ([0,0,0,0,0,0,1,1,0,0,0,0],(4,12)),+ ([0,0,0,0,0,0,0,1,1,0,1,0,1],(4,13)),+ ([0,0,0,0,0,0,0,0,1,0,1,1,1],(4,14)),+ ([0,0,0,0,0,0,0,0,0,1,1,0,0,0],(4,15)),+ ([0,0,0,1,1,1,0,1,0],(5,0)),+ ([0,0,0,1,1,0,1,1],(5,1)),+ ([0,0,0,1,1,0,0,1,0],(5,2)),+ ([0,0,0,1,1,0,0,0,0,0],(5,3)),+ ([0,0,0,1,0,0,1,1,0,0],(5,4)),+ ([0,0,0,1,0,0,0,1,1,0],(5,5)),+ ([0,0,0,0,1,0,1,1,1,0,1],(5,6)),+ ([0,0,0,0,1,0,1,0,1,0,0],(5,7)),+ ([0,0,0,0,1,0,0,1,1,0,1],(5,8)),+ ([0,0,0,0,0,1,1,1,0,1,0],(5,9)),+ ([0,0,0,0,0,1,0,0,1,1,1,1],(5,10)),+ ([0,0,0,0,0,0,1,1,1,0,1],(5,11)),+ ([0,0,0,0,0,0,1,0,0,1,0,1,0],(5,12)),+ ([0,0,0,0,0,0,0,1,1,0,0,0,1],(5,13)),+ ([0,0,0,0,0,0,0,0,1,0,1,0,0,1],(5,14)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,0,1],(5,15)),+ ([0,0,0,1,0,1,1,1,1],(6,0)),+ ([0,0,0,1,0,1,1,0,1],(6,1)),+ ([0,0,0,1,0,0,1,1,1,0],(6,2)),+ ([0,0,0,1,0,0,1,0,1,0],(6,3)),+ ([0,0,0,0,1,1,1,0,0,1,1],(6,4)),+ ([0,0,0,0,1,0,1,1,1,1,0],(6,5)),+ ([0,0,0,0,1,0,1,1,0,1,0],(6,6)),+ ([0,0,0,0,1,0,0,1,1,1,1],(6,7)),+ ([0,0,0,0,1,0,0,0,1,0,1],(6,8)),+ ([0,0,0,0,0,1,0,1,0,0,1,1],(6,9)),+ ([0,0,0,0,0,1,0,0,0,1,1,1],(6,10)),+ ([0,0,0,0,0,0,1,1,0,0,1,0],(6,11)),+ ([0,0,0,0,0,0,0,1,1,1,0,1,1],(6,12)),+ ([0,0,0,0,0,0,0,1,0,0,1,1,0],(6,13)),+ ([0,0,0,0,0,0,0,0,1,0,0,1,0,0],(6,14)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,1,1],(6,15)),+ ([0,0,0,1,0,0,1,0,0,0],(7,0)),+ ([0,0,0,1,0,0,0,1,0],(7,1)),+ ([0,0,0,0,1,1,1,0,0,0],(7,2)),+ ([0,0,0,0,1,0,1,1,1,1,1],(7,3)),+ ([0,0,0,0,1,0,1,1,1,0,0],(7,4)),+ ([0,0,0,0,1,0,1,0,1,0,1],(7,5)),+ ([0,0,0,0,0,1,0,1,1,0,1,1],(7,6)),+ ([0,0,0,0,0,1,0,1,1,0,1,0],(7,7)),+ ([0,0,0,0,0,1,0,1,0,1,1,0],(7,8)),+ ([0,0,0,0,0,1,0,0,1,0,0,1],(7,9)),+ ([0,0,0,0,0,0,1,0,0,1,1,0,1],(7,10)),+ ([0,0,0,0,0,0,1,0,0,0,0,0,1],(7,11)),+ ([0,0,0,0,0,0,0,1,1,0,0,1,1],(7,12)),+ ([0,0,0,0,0,0,0,0,1,0,1,1,0,0],(7,13)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1],(7,14)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0],(7,15)),+ ([0,0,0,1,0,1,0,1,1],(8,0)),+ ([0,0,0,1,0,1,0,0],(8,1)),+ ([0,0,0,0,1,1,1,1,0],(8,2)),+ ([0,0,0,0,1,0,1,1,0,0],(8,3)),+ ([0,0,0,0,1,1,0,1,1,1],(8,4)),+ ([0,0,0,0,1,0,0,1,1,1,0],(8,5)),+ ([0,0,0,0,1,0,0,1,0,0,0],(8,6)),+ ([0,0,0,0,0,1,0,1,0,1,1,1],(8,7)),+ ([0,0,0,0,0,1,0,0,1,1,1,0],(8,8)),+ ([0,0,0,0,0,0,1,1,1,1,0,1],(8,9)),+ ([0,0,0,0,0,0,1,0,1,1,1,0],(8,10)),+ ([0,0,0,0,0,0,0,1,1,0,1,1,0],(8,11)),+ ([0,0,0,0,0,0,0,1,0,0,1,0,1],(8,12)),+ ([0,0,0,0,0,0,0,0,0,1,1,1,1,0],(8,13)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,1,0,0],(8,14)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],(8,15)),+ ([0,0,0,0,1,1,0,1,0,1],(9,0)),+ ([0,0,0,0,1,1,0,0,1],(9,1)),+ ([0,0,0,0,1,0,1,0,0,1],(9,2)),+ ([0,0,0,0,1,0,0,1,0,1],(9,3)),+ ([0,0,0,0,0,1,0,1,1,0,0],(9,4)),+ ([0,0,0,0,0,1,1,1,0,1,1],(9,5)),+ ([0,0,0,0,0,1,1,0,1,1,0],(9,6)),+ ([0,0,0,0,0,0,1,0,1,0,0,0,1],(9,7)),+ ([0,0,0,0,0,1,0,0,0,0,1,0],(9,8)),+ ([0,0,0,0,0,0,1,0,0,1,1,0,0],(9,9)),+ ([0,0,0,0,0,0,0,1,1,1,0,0,1],(9,10)),+ ([0,0,0,0,0,0,0,0,1,1,0,1,1,0],(9,11)),+ ([0,0,0,0,0,0,0,0,1,0,0,1,0,1],(9,12)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,1,0],(9,13)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1],(9,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0,1,1],(9,15)),+ ([0,0,0,0,1,0,0,0,1,1],(10,0)),+ ([0,0,0,0,1,0,0,0,0,1],(10,1)),+ ([0,0,0,0,0,1,1,1,1,1],(10,2)),+ ([0,0,0,0,0,1,1,1,0,0,1],(10,3)),+ ([0,0,0,0,0,1,0,1,0,1,0],(10,4)),+ ([0,0,0,0,0,1,0,1,0,0,1,0],(10,5)),+ ([0,0,0,0,0,1,0,0,1,0,0,0],(10,6)),+ ([0,0,0,0,0,0,1,0,1,0,0,0,0],(10,7)),+ ([0,0,0,0,0,0,1,0,1,1,1,1],(10,8)),+ ([0,0,0,0,0,0,0,1,1,1,0,1,0],(10,9)),+ ([0,0,0,0,0,0,0,0,1,1,0,1,1,1],(10,10)),+ ([0,0,0,0,0,0,0,0,1,0,1,0,1],(10,11)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,1,0],(10,12)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,0,1,0],(10,13)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0],(10,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0],(10,15)),+ ([0,0,0,0,0,1,1,0,1,0,1],(11,0)),+ ([0,0,0,0,0,1,1,0,0,1],(11,1)),+ ([0,0,0,0,0,1,0,1,1,1],(11,2)),+ ([0,0,0,0,0,1,0,0,1,1,0],(11,3)),+ ([0,0,0,0,0,1,0,0,0,1,1,0],(11,4)),+ ([0,0,0,0,0,0,1,1,1,1,0,0],(11,5)),+ ([0,0,0,0,0,0,1,1,0,0,1,1],(11,6)),+ ([0,0,0,0,0,0,1,0,0,1,0,0],(11,7)),+ ([0,0,0,0,0,0,0,1,1,0,1,1,1],(11,8)),+ ([0,0,0,0,0,0,0,0,1,1,0,1,0],(11,9)),+ ([0,0,0,0,0,0,0,1,0,0,0,1,0],(11,10)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,1,1],(11,11)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,0,1,1],(11,12)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],(11,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0,0,1],(11,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1],(11,15)),+ ([0,0,0,0,0,1,0,0,0,1,0],(12,0)),+ ([0,0,0,0,0,1,0,0,0,0,0],(12,1)),+ ([0,0,0,0,0,0,1,1,1,0,0],(12,2)),+ ([0,0,0,0,0,0,1,0,0,1,1,1],(12,3)),+ ([0,0,0,0,0,0,1,1,0,0,0,1],(12,4)),+ ([0,0,0,0,0,0,1,0,0,1,0,1,1],(12,5)),+ ([0,0,0,0,0,0,0,1,1,1,1,0],(12,6)),+ ([0,0,0,0,0,0,0,1,1,0,1,0,0],(12,7)),+ ([0,0,0,0,0,0,0,0,1,1,0,0,0,0],(12,8)),+ ([0,0,0,0,0,0,0,0,1,0,1,0,0,0],(12,9)),+ ([0,0,0,0,0,0,0,0,0,1,1,0,1,0,0],(12,10)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],(12,11)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,0,1,0],(12,12)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],(12,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1],(12,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1],(12,15)),+ ([0,0,0,0,0,0,1,0,1,1,0,1],(13,0)),+ ([0,0,0,0,0,0,1,0,1,0,1],(13,1)),+ ([0,0,0,0,0,0,1,0,0,0,1,0],(13,2)),+ ([0,0,0,0,0,0,1,0,0,0,0,0,0],(13,3)),+ ([0,0,0,0,0,0,0,1,1,1,0,0,0],(13,4)),+ ([0,0,0,0,0,0,0,1,1,0,0,1,0],(13,5)),+ ([0,0,0,0,0,0,0,0,1,1,0,0,0,1],(13,6)),+ ([0,0,0,0,0,0,0,0,1,0,1,1,0,1],(13,7)),+ ([0,0,0,0,0,0,0,0,0,1,1,1,1,1],(13,8)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,1,1],(13,9)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,0,0],(13,10)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],(13,11)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0],(13,12)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,1,1],(13,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0],(13,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],(13,15)),+ ([0,0,0,0,0,0,0,1,1,0,0,0,0],(14,0)),+ ([0,0,0,0,0,0,0,1,0,1,1,1],(14,1)),+ ([0,0,0,0,0,0,0,1,0,1,0,0],(14,2)),+ ([0,0,0,0,0,0,0,1,0,0,1,1,1],(14,3)),+ ([0,0,0,0,0,0,0,1,0,0,1,0,0],(14,4)),+ ([0,0,0,0,0,0,0,1,0,0,0,1,1],(14,5)),+ ([0,0,0,0,0,0,0,0,0,1,1,0,1,0,1],(14,6)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,0,1],(14,7)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,0,0],(14,8)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1],(14,9)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,1,0,1],(14,10)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0,1,0],(14,11)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,1,0],(14,12)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],(14,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],(14,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],(14,15)),+ ([0,0,0,0,0,0,0,1,0,0,0,0],(15,0)),+ ([0,0,0,0,0,0,0,0,1,1,1,1],(15,1)),+ ([0,0,0,0,0,0,0,0,1,0,0,0,1],(15,2)),+ ([0,0,0,0,0,0,0,0,0,1,1,0,1,1],(15,3)),+ ([0,0,0,0,0,0,0,0,0,1,1,0,0,1],(15,4)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,0,0],(15,5)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,1,0,1],(15,6)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,1,1],(15,7)),+ ([0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],(15,8)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,1,0,0],(15,9)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],(15,10)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],(15,11)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],(15,12)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],(15,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],(15,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],(15,15))]++tableHuffR12 :: [([Int], (Int, Int))]+tableHuffR12 = [([1,1,1],(0,0)),+ ([1,1,0,0],(0,1)),+ ([1,0,0,1,0],(0,2)),+ ([0,1,1,0,1,0,1],(0,3)),+ ([0,1,0,1,1,1,1],(0,4)),+ ([0,1,0,0,1,1,0,0],(0,5)),+ ([0,0,1,1,1,1,1,0,0],(0,6)),+ ([0,0,1,1,0,1,1,0,0],(0,7)),+ ([0,0,1,0,1,1,0,0,1],(0,8)),+ ([0,0,0,1,1,1,1,0,1,1],(0,9)),+ ([0,0,0,1,1,0,1,1,0,0],(0,10)),+ ([0,0,0,0,1,1,1,0,1,1,1],(0,11)),+ ([0,0,0,0,1,1,0,1,0,1,1],(0,12)),+ ([0,0,0,0,1,0,1,0,0,0,1],(0,13)),+ ([0,0,0,0,0,1,1,1,1,0,1,0],(0,14)),+ ([0,0,0,0,0,0,0,1,1,1,1,1,1],(0,15)),+ ([1,1,0,1],(1,0)),+ ([1,0,1],(1,1)),+ ([1,0,0,0,0],(1,2)),+ ([0,1,1,0,1,1],(1,3)),+ ([0,1,0,1,1,1,0],(1,4)),+ ([0,1,0,0,1,0,0],(1,5)),+ ([0,0,1,1,1,1,0,1],(1,6)),+ ([0,0,1,1,0,0,1,1],(1,7)),+ ([0,0,1,0,1,0,1,0],(1,8)),+ ([0,0,1,0,0,0,1,1,0],(1,9)),+ ([0,0,0,1,1,0,1,0,0],(1,10)),+ ([0,0,0,1,0,1,0,0,1,1],(1,11)),+ ([0,0,0,1,0,0,0,0,0,1],(1,12)),+ ([0,0,0,0,1,0,1,0,0,1],(1,13)),+ ([0,0,0,0,0,1,1,1,0,1,1],(1,14)),+ ([0,0,0,0,0,1,0,0,1,0,0],(1,15)),+ ([1,0,0,1,1],(2,0)),+ ([1,0,0,0,1],(2,1)),+ ([0,1,1,1,1],(2,2)),+ ([0,1,1,0,0,0],(2,3)),+ ([0,1,0,1,0,0,1],(2,4)),+ ([0,1,0,0,0,1,0],(2,5)),+ ([0,0,1,1,1,0,1,1],(2,6)),+ ([0,0,1,1,0,0,0,0],(2,7)),+ ([0,0,1,0,1,0,0,0],(2,8)),+ ([0,0,1,0,0,0,0,0,0],(2,9)),+ ([0,0,0,1,1,0,0,1,0],(2,10)),+ ([0,0,0,1,0,0,1,1,1,0],(2,11)),+ ([0,0,0,0,1,1,1,1,1,0],(2,12)),+ ([0,0,0,0,1,0,1,0,0,0,0],(2,13)),+ ([0,0,0,0,0,1,1,1,0,0,0],(2,14)),+ ([0,0,0,0,0,1,0,0,0,0,1],(2,15)),+ ([0,1,1,1,0,1],(3,0)),+ ([0,1,1,1,0,0],(3,1)),+ ([0,1,1,0,0,1],(3,2)),+ ([0,1,0,1,0,1,1],(3,3)),+ ([0,1,0,0,1,1,1],(3,4)),+ ([0,0,1,1,1,1,1,1],(3,5)),+ ([0,0,1,1,0,1,1,1],(3,6)),+ ([0,0,1,0,1,1,1,0,1],(3,7)),+ ([0,0,1,0,0,1,1,0,0],(3,8)),+ ([0,0,0,1,1,1,0,1,1],(3,9)),+ ([0,0,0,1,0,1,1,1,0,1],(3,10)),+ ([0,0,0,1,0,0,1,0,0,0],(3,11)),+ ([0,0,0,0,1,1,0,1,1,0],(3,12)),+ ([0,0,0,0,1,0,0,1,0,1,1],(3,13)),+ ([0,0,0,0,0,1,1,0,0,1,0],(3,14)),+ ([0,0,0,0,0,0,1,1,1,0,1],(3,15)),+ ([0,1,1,0,1,0,0],(4,0)),+ ([0,1,0,1,1,0],(4,1)),+ ([0,1,0,1,0,1,0],(4,2)),+ ([0,1,0,1,0,0,0],(4,3)),+ ([0,1,0,0,0,0,1,1],(4,4)),+ ([0,0,1,1,1,0,0,1],(4,5)),+ ([0,0,1,0,1,1,1,1,1],(4,6)),+ ([0,0,1,0,0,1,1,1,1],(4,7)),+ ([0,0,1,0,0,1,0,0,0],(4,8)),+ ([0,0,0,1,1,1,0,0,1],(4,9)),+ ([0,0,0,1,0,1,1,0,0,1],(4,10)),+ ([0,0,0,1,0,0,0,1,0,1],(4,11)),+ ([0,0,0,0,1,1,0,0,0,1],(4,12)),+ ([0,0,0,0,1,0,0,0,0,1,0],(4,13)),+ ([0,0,0,0,0,1,0,1,1,1,0],(4,14)),+ ([0,0,0,0,0,0,1,1,0,1,1],(4,15)),+ ([0,1,0,0,1,1,0,1],(5,0)),+ ([0,1,0,0,1,0,1],(5,1)),+ ([0,1,0,0,0,1,1],(5,2)),+ ([0,1,0,0,0,0,1,0],(5,3)),+ ([0,0,1,1,1,0,1,0],(5,4)),+ ([0,0,1,1,0,1,0,0],(5,5)),+ ([0,0,1,0,1,1,0,1,1],(5,6)),+ ([0,0,1,0,0,1,0,1,0],(5,7)),+ ([0,0,0,1,1,1,1,1,0],(5,8)),+ ([0,0,0,1,1,0,0,0,0],(5,9)),+ ([0,0,0,1,0,0,1,1,1,1],(5,10)),+ ([0,0,0,0,1,1,1,1,1,1],(5,11)),+ ([0,0,0,0,1,0,1,1,0,1,0],(5,12)),+ ([0,0,0,0,0,1,1,1,1,1,0],(5,13)),+ ([0,0,0,0,0,1,0,1,0,0,0],(5,14)),+ ([0,0,0,0,0,0,1,0,0,1,1,0],(5,15)),+ ([0,0,1,1,1,1,1,0,1],(6,0)),+ ([0,1,0,0,0,0,0],(6,1)),+ ([0,0,1,1,1,1,0,0],(6,2)),+ ([0,0,1,1,1,0,0,0],(6,3)),+ ([0,0,1,1,0,0,1,0],(6,4)),+ ([0,0,1,0,1,1,1,0,0],(6,5)),+ ([0,0,1,0,0,1,1,1,0],(6,6)),+ ([0,0,1,0,0,0,0,0,1],(6,7)),+ ([0,0,0,1,1,0,1,1,1],(6,8)),+ ([0,0,0,1,0,1,0,1,1,1],(6,9)),+ ([0,0,0,1,0,0,0,1,1,1],(6,10)),+ ([0,0,0,0,1,1,0,0,1,1],(6,11)),+ ([0,0,0,0,1,0,0,1,0,0,1],(6,12)),+ ([0,0,0,0,0,1,1,0,0,1,1],(6,13)),+ ([0,0,0,0,0,1,0,0,0,1,1,0],(6,14)),+ ([0,0,0,0,0,0,0,1,1,1,1,0],(6,15)),+ ([0,0,1,1,0,1,1,0,1],(7,0)),+ ([0,0,1,1,0,1,0,1],(7,1)),+ ([0,0,1,1,0,0,0,1],(7,2)),+ ([0,0,1,0,1,1,1,1,0],(7,3)),+ ([0,0,1,0,1,1,0,0,0],(7,4)),+ ([0,0,1,0,0,1,0,1,1],(7,5)),+ ([0,0,1,0,0,0,0,1,0],(7,6)),+ ([0,0,0,1,1,1,1,0,1,0],(7,7)),+ ([0,0,0,1,0,1,1,0,1,1],(7,8)),+ ([0,0,0,1,0,0,1,0,0,1],(7,9)),+ ([0,0,0,0,1,1,1,0,0,0],(7,10)),+ ([0,0,0,0,1,0,1,0,1,0],(7,11)),+ ([0,0,0,0,1,0,0,0,0,0,0],(7,12)),+ ([0,0,0,0,0,1,0,1,1,0,0],(7,13)),+ ([0,0,0,0,0,0,1,0,1,0,1],(7,14)),+ ([0,0,0,0,0,0,0,1,1,0,0,1],(7,15)),+ ([0,0,1,0,1,1,0,1,0],(8,0)),+ ([0,0,1,0,1,0,1,1],(8,1)),+ ([0,0,1,0,1,0,0,1],(8,2)),+ ([0,0,1,0,0,1,1,0,1],(8,3)),+ ([0,0,1,0,0,1,0,0,1],(8,4)),+ ([0,0,0,1,1,1,1,1,1],(8,5)),+ ([0,0,0,1,1,1,0,0,0],(8,6)),+ ([0,0,0,1,0,1,1,1,0,0],(8,7)),+ ([0,0,0,1,0,0,1,1,0,1],(8,8)),+ ([0,0,0,1,0,0,0,0,1,0],(8,9)),+ ([0,0,0,0,1,0,1,1,1,1],(8,10)),+ ([0,0,0,0,1,0,0,0,0,1,1],(8,11)),+ ([0,0,0,0,0,1,1,0,0,0,0],(8,12)),+ ([0,0,0,0,0,0,1,1,0,1,0,1],(8,13)),+ ([0,0,0,0,0,0,1,0,0,1,0,0],(8,14)),+ ([0,0,0,0,0,0,0,1,0,1,0,0],(8,15)),+ ([0,0,1,0,0,0,1,1,1],(9,0)),+ ([0,0,1,0,0,0,1,0],(9,1)),+ ([0,0,1,0,0,0,0,1,1],(9,2)),+ ([0,0,0,1,1,1,1,0,0],(9,3)),+ ([0,0,0,1,1,1,0,1,0],(9,4)),+ ([0,0,0,1,1,0,0,0,1],(9,5)),+ ([0,0,0,1,0,1,1,0,0,0],(9,6)),+ ([0,0,0,1,0,0,1,1,0,0],(9,7)),+ ([0,0,0,1,0,0,0,0,1,1],(9,8)),+ ([0,0,0,0,1,1,0,1,0,1,0],(9,9)),+ ([0,0,0,0,1,0,0,0,1,1,1],(9,10)),+ ([0,0,0,0,0,1,1,0,1,1,0],(9,11)),+ ([0,0,0,0,0,1,0,0,1,1,0],(9,12)),+ ([0,0,0,0,0,0,1,0,0,1,1,1],(9,13)),+ ([0,0,0,0,0,0,0,1,0,1,1,1],(9,14)),+ ([0,0,0,0,0,0,0,0,1,1,1,1],(9,15)),+ ([0,0,0,1,1,0,1,1,0,1],(10,0)),+ ([0,0,0,1,1,0,1,0,1],(10,1)),+ ([0,0,0,1,1,0,0,1,1],(10,2)),+ ([0,0,0,1,0,1,1,1,1],(10,3)),+ ([0,0,0,1,0,1,1,0,1,0],(10,4)),+ ([0,0,0,1,0,1,0,0,1,0],(10,5)),+ ([0,0,0,0,1,1,1,0,1,0],(10,6)),+ ([0,0,0,0,1,1,1,0,0,1],(10,7)),+ ([0,0,0,0,1,1,0,0,0,0],(10,8)),+ ([0,0,0,0,1,0,0,1,0,0,0],(10,9)),+ ([0,0,0,0,0,1,1,1,0,0,1],(10,10)),+ ([0,0,0,0,0,1,0,1,0,0,1],(10,11)),+ ([0,0,0,0,0,0,1,0,1,1,1],(10,12)),+ ([0,0,0,0,0,0,0,1,1,0,1,1],(10,13)),+ ([0,0,0,0,0,0,0,1,1,1,1,1,0],(10,14)),+ ([0,0,0,0,0,0,0,0,1,0,0,1],(10,15)),+ ([0,0,0,1,0,1,0,1,1,0],(11,0)),+ ([0,0,0,1,0,1,0,1,0],(11,1)),+ ([0,0,0,1,0,1,0,0,0],(11,2)),+ ([0,0,0,1,0,0,1,0,1],(11,3)),+ ([0,0,0,1,0,0,0,1,1,0],(11,4)),+ ([0,0,0,1,0,0,0,0,0,0],(11,5)),+ ([0,0,0,0,1,1,0,1,0,0],(11,6)),+ ([0,0,0,0,1,0,1,0,1,1],(11,7)),+ ([0,0,0,0,1,0,0,0,1,1,0],(11,8)),+ ([0,0,0,0,0,1,1,0,1,1,1],(11,9)),+ ([0,0,0,0,0,1,0,1,0,1,0],(11,10)),+ ([0,0,0,0,0,0,1,1,0,0,1],(11,11)),+ ([0,0,0,0,0,0,0,1,1,1,0,1],(11,12)),+ ([0,0,0,0,0,0,0,1,0,0,1,0],(11,13)),+ ([0,0,0,0,0,0,0,0,1,0,1,1],(11,14)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,1],(11,15)),+ ([0,0,0,0,1,1,1,0,1,1,0],(12,0)),+ ([0,0,0,1,0,0,0,1,0,0],(12,1)),+ ([0,0,0,0,1,1,1,1,0],(12,2)),+ ([0,0,0,0,1,1,0,1,1,1],(12,3)),+ ([0,0,0,0,1,1,0,0,1,0],(12,4)),+ ([0,0,0,0,1,0,1,1,1,0],(12,5)),+ ([0,0,0,0,1,0,0,1,0,1,0],(12,6)),+ ([0,0,0,0,1,0,0,0,0,0,1],(12,7)),+ ([0,0,0,0,0,1,1,0,0,0,1],(12,8)),+ ([0,0,0,0,0,1,0,0,1,1,1],(12,9)),+ ([0,0,0,0,0,0,1,1,0,0,0],(12,10)),+ ([0,0,0,0,0,0,1,0,0,0,0],(12,11)),+ ([0,0,0,0,0,0,0,1,0,1,1,0],(12,12)),+ ([0,0,0,0,0,0,0,0,1,1,0,1],(12,13)),+ ([0,0,0,0,0,0,0,0,0,1,1,1,0],(12,14)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,1],(12,15)),+ ([0,0,0,0,1,0,1,1,0,1,1],(13,0)),+ ([0,0,0,0,1,0,1,1,0,0],(13,1)),+ ([0,0,0,0,1,0,0,1,1,1],(13,2)),+ ([0,0,0,0,1,0,0,1,1,0],(13,3)),+ ([0,0,0,0,1,0,0,0,1,0],(13,4)),+ ([0,0,0,0,0,1,1,1,1,1,1],(13,5)),+ ([0,0,0,0,0,1,1,0,1,0,0],(13,6)),+ ([0,0,0,0,0,1,0,1,1,0,1],(13,7)),+ ([0,0,0,0,0,0,1,1,1,1,1],(13,8)),+ ([0,0,0,0,0,0,1,1,0,1,0,0],(13,9)),+ ([0,0,0,0,0,0,0,1,1,1,0,0],(13,10)),+ ([0,0,0,0,0,0,0,1,0,0,1,1],(13,11)),+ ([0,0,0,0,0,0,0,0,1,1,1,0],(13,12)),+ ([0,0,0,0,0,0,0,0,1,0,0,0],(13,13)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,1],(13,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,1],(13,15)),+ ([0,0,0,0,0,1,1,1,1,0,1,1],(14,0)),+ ([0,0,0,0,0,1,1,1,1,0,0],(14,1)),+ ([0,0,0,0,0,1,1,1,0,1,0],(14,2)),+ ([0,0,0,0,0,1,1,0,1,0,1],(14,3)),+ ([0,0,0,0,0,1,0,1,1,1,1],(14,4)),+ ([0,0,0,0,0,1,0,1,0,1,1],(14,5)),+ ([0,0,0,0,0,1,0,0,0,0,0],(14,6)),+ ([0,0,0,0,0,0,1,0,1,1,0],(14,7)),+ ([0,0,0,0,0,0,1,0,0,1,0,1],(14,8)),+ ([0,0,0,0,0,0,0,1,1,0,0,0],(14,9)),+ ([0,0,0,0,0,0,0,1,0,0,0,1],(14,10)),+ ([0,0,0,0,0,0,0,0,1,1,0,0],(14,11)),+ ([0,0,0,0,0,0,0,0,0,1,1,1,1],(14,12)),+ ([0,0,0,0,0,0,0,0,0,1,0,1,0],(14,13)),+ ([0,0,0,0,0,0,0,0,0,0,1,0],(14,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,1],(14,15)),+ ([0,0,0,0,0,1,0,0,0,1,1,1],(15,0)),+ ([0,0,0,0,0,1,0,0,1,0,1],(15,1)),+ ([0,0,0,0,0,1,0,0,0,1,0],(15,2)),+ ([0,0,0,0,0,0,1,1,1,1,0],(15,3)),+ ([0,0,0,0,0,0,1,1,1,0,0],(15,4)),+ ([0,0,0,0,0,0,1,0,1,0,0],(15,5)),+ ([0,0,0,0,0,0,1,0,0,0,1],(15,6)),+ ([0,0,0,0,0,0,0,1,1,0,1,0],(15,7)),+ ([0,0,0,0,0,0,0,1,0,1,0,1],(15,8)),+ ([0,0,0,0,0,0,0,1,0,0,0,0],(15,9)),+ ([0,0,0,0,0,0,0,0,1,0,1,0],(15,10)),+ ([0,0,0,0,0,0,0,0,0,1,1,0],(15,11)),+ ([0,0,0,0,0,0,0,0,0,1,0,0,0],(15,12)),+ ([0,0,0,0,0,0,0,0,0,0,1,1,0],(15,13)),+ ([0,0,0,0,0,0,0,0,0,0,0,1,0],(15,14)),+ ([0,0,0,0,0,0,0,0,0,0,0,0,0],(15,15))]++tableHuffR13 :: [([Int], (Int, Int))]+tableHuffR13 = [([1],(0,0)),+ ([0,1,0,1],(0,1)),+ ([0,0,1,1,1,0],(0,2)),+ ([0,0,1,0,1,1,0,0],(0,3)),+ ([0,0,1,0,0,1,0,1,0],(0,4)),+ ([0,0,0,1,1,1,1,1,1],(0,5)),+ ([0,0,0,1,1,0,1,1,1,0],(0,6)),+ ([0,0,0,1,0,1,1,1,0,1],(0,7)),+ ([0,0,0,1,0,1,0,1,1,0,0],(0,8)),+ ([0,0,0,1,0,0,1,0,1,0,1],(0,9)),+ ([0,0,0,1,0,0,0,1,0,1,0],(0,10)),+ ([0,0,0,0,1,1,1,1,0,0,1,0],(0,11)),+ ([0,0,0,0,1,1,1,0,0,0,0,1],(0,12)),+ ([0,0,0,0,1,1,0,0,0,0,1,1],(0,13)),+ ([0,0,0,0,1,0,1,1,1,1,0,0,0],(0,14)),+ ([0,0,0,0,1,0,0,0,1],(0,15)),+ ([0,1,1],(1,0)),+ ([0,1,0,0],(1,1)),+ ([0,0,1,1,0,0],(1,2)),+ ([0,0,1,0,1,0,0],(1,3)),+ ([0,0,1,0,0,0,1,1],(1,4)),+ ([0,0,0,1,1,1,1,1,0],(1,5)),+ ([0,0,0,1,1,0,1,0,1],(1,6)),+ ([0,0,0,1,0,1,1,1,1],(1,7)),+ ([0,0,0,1,0,1,0,0,1,1],(1,8)),+ ([0,0,0,1,0,0,1,0,1,1],(1,9)),+ ([0,0,0,1,0,0,0,1,0,0],(1,10)),+ ([0,0,0,0,1,1,1,0,1,1,1],(1,11)),+ ([0,0,0,0,1,1,0,0,1,0,0,1],(1,12)),+ ([0,0,0,0,1,1,0,1,0,1,1],(1,13)),+ ([0,0,0,0,1,1,0,0,1,1,1,1],(1,14)),+ ([0,0,0,0,1,0,0,1],(1,15)),+ ([0,0,1,1,1,1],(2,0)),+ ([0,0,1,1,0,1],(2,1)),+ ([0,0,1,0,1,1,1],(2,2)),+ ([0,0,1,0,0,1,1,0],(2,3)),+ ([0,0,1,0,0,0,0,1,1],(2,4)),+ ([0,0,0,1,1,1,0,1,0],(2,5)),+ ([0,0,0,1,1,0,0,1,1,1],(2,6)),+ ([0,0,0,1,0,1,1,0,1,0],(2,7)),+ ([0,0,0,1,0,1,0,0,0,0,1],(2,8)),+ ([0,0,0,1,0,0,1,0,0,0],(2,9)),+ ([0,0,0,0,1,1,1,1,1,1,1],(2,10)),+ ([0,0,0,0,1,1,1,0,1,0,1],(2,11)),+ ([0,0,0,0,1,1,0,1,1,1,0],(2,12)),+ ([0,0,0,0,1,1,0,1,0,0,0,1],(2,13)),+ ([0,0,0,0,1,1,0,0,1,1,1,0],(2,14)),+ ([0,0,0,0,1,0,0,0,0],(2,15)),+ ([0,0,1,0,1,1,0,1],(3,0)),+ ([0,0,1,0,1,0,1],(3,1)),+ ([0,0,1,0,0,1,1,1],(3,2)),+ ([0,0,1,0,0,0,1,0,1],(3,3)),+ ([0,0,1,0,0,0,0,0,0],(3,4)),+ ([0,0,0,1,1,1,0,0,1,0],(3,5)),+ ([0,0,0,1,1,0,0,0,1,1],(3,6)),+ ([0,0,0,1,0,1,0,1,1,1],(3,7)),+ ([0,0,0,1,0,0,1,1,1,1,0],(3,8)),+ ([0,0,0,1,0,0,0,1,1,0,0],(3,9)),+ ([0,0,0,0,1,1,1,1,1,1,0,0],(3,10)),+ ([0,0,0,0,1,1,0,1,0,1,0,0],(3,11)),+ ([0,0,0,0,1,1,0,0,0,1,1,1],(3,12)),+ ([0,0,0,0,1,1,0,0,0,0,0,1,1],(3,13)),+ ([0,0,0,0,1,0,1,1,0,1,1,0,1],(3,14)),+ ([0,0,0,0,0,1,1,0,1,0],(3,15)),+ ([0,0,1,0,0,1,0,1,1],(4,0)),+ ([0,0,1,0,0,1,0,0],(4,1)),+ ([0,0,1,0,0,0,1,0,0],(4,2)),+ ([0,0,1,0,0,0,0,0,1],(4,3)),+ ([0,0,0,1,1,1,0,0,1,1],(4,4)),+ ([0,0,0,1,1,0,0,1,0,1],(4,5)),+ ([0,0,0,1,0,1,1,0,0,1,1],(4,6)),+ ([0,0,0,1,0,1,0,0,1,0,0],(4,7)),+ ([0,0,0,1,0,0,1,1,0,1,1],(4,8)),+ ([0,0,0,1,0,0,0,0,1,0,0,0],(4,9)),+ ([0,0,0,0,1,1,1,1,0,1,1,0],(4,10)),+ ([0,0,0,0,1,1,1,0,0,0,1,0],(4,11)),+ ([0,0,0,0,1,1,0,0,0,1,0,1,1],(4,12)),+ ([0,0,0,0,1,0,1,1,1,1,1,1,0],(4,13)),+ ([0,0,0,0,1,0,1,1,0,1,0,1,0],(4,14)),+ ([0,0,0,0,0,1,0,0,1],(4,15)),+ ([0,0,1,0,0,0,0,1,0],(5,0)),+ ([0,0,0,1,1,1,1,0],(5,1)),+ ([0,0,0,1,1,1,0,1,1],(5,2)),+ ([0,0,0,1,1,1,0,0,0],(5,3)),+ ([0,0,0,1,1,0,0,1,1,0],(5,4)),+ ([0,0,0,1,0,1,1,1,0,0,1],(5,5)),+ ([0,0,0,1,0,1,0,1,1,0,1],(5,6)),+ ([0,0,0,1,0,0,0,0,1,0,0,1],(5,7)),+ ([0,0,0,1,0,0,0,1,1,1,0],(5,8)),+ ([0,0,0,0,1,1,1,1,1,1,0,1],(5,9)),+ ([0,0,0,0,1,1,1,0,1,0,0,0],(5,10)),+ ([0,0,0,0,1,1,0,0,1,0,0,0,0],(5,11)),+ ([0,0,0,0,1,1,0,0,0,0,1,0,0],(5,12)),+ ([0,0,0,0,1,0,1,1,1,1,0,1,0],(5,13)),+ ([0,0,0,0,0,1,1,0,1,1,1,1,0,1],(5,14)),+ ([0,0,0,0,0,1,0,0,0,0],(5,15)),+ ([0,0,0,1,1,0,1,1,1,1],(6,0)),+ ([0,0,0,1,1,0,1,1,0],(6,1)),+ ([0,0,0,1,1,0,1,0,0],(6,2)),+ ([0,0,0,1,1,0,0,1,0,0],(6,3)),+ ([0,0,0,1,0,1,1,1,0,0,0],(6,4)),+ ([0,0,0,1,0,1,1,0,0,1,0],(6,5)),+ ([0,0,0,1,0,1,0,0,0,0,0],(6,6)),+ ([0,0,0,1,0,0,0,0,1,0,1],(6,7)),+ ([0,0,0,1,0,0,0,0,0,0,0,1],(6,8)),+ ([0,0,0,0,1,1,1,1,0,1,0,0],(6,9)),+ ([0,0,0,0,1,1,1,0,0,1,0,0],(6,10)),+ ([0,0,0,0,1,1,0,1,1,0,0,1],(6,11)),+ ([0,0,0,0,1,1,0,0,0,0,0,0,1],(6,12)),+ ([0,0,0,0,1,0,1,1,0,1,1,1,0],(6,13)),+ ([0,0,0,0,1,0,1,1,0,0,1,0,1,1],(6,14)),+ ([0,0,0,0,0,0,1,0,1,0],(6,15)),+ ([0,0,0,1,1,0,0,0,1,0],(7,0)),+ ([0,0,0,1,1,0,0,0,0],(7,1)),+ ([0,0,0,1,0,1,1,0,1,1],(7,2)),+ ([0,0,0,1,0,1,1,0,0,0],(7,3)),+ ([0,0,0,1,0,1,0,0,1,0,1],(7,4)),+ ([0,0,0,1,0,0,1,1,1,0,1],(7,5)),+ ([0,0,0,1,0,0,1,0,1,0,0],(7,6)),+ ([0,0,0,1,0,0,0,0,0,1,0,1],(7,7)),+ ([0,0,0,0,1,1,1,1,1,0,0,0],(7,8)),+ ([0,0,0,0,1,1,0,0,1,0,1,1,1],(7,9)),+ ([0,0,0,0,1,1,0,0,0,1,1,0,1],(7,10)),+ ([0,0,0,0,1,0,1,1,1,0,1,0,0],(7,11)),+ ([0,0,0,0,1,0,1,1,1,1,1,0,0],(7,12)),+ ([0,0,0,0,0,1,1,0,1,1,1,1,0,0,1],(7,13)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,1,0,0],(7,14)),+ ([0,0,0,0,0,0,1,0,0,0],(7,15)),+ ([0,0,0,1,0,1,0,1,0,1],(8,0)),+ ([0,0,0,1,0,1,0,1,0,0],(8,1)),+ ([0,0,0,1,0,1,0,0,0,1],(8,2)),+ ([0,0,0,1,0,0,1,1,1,1,1],(8,3)),+ ([0,0,0,1,0,0,1,1,1,0,0],(8,4)),+ ([0,0,0,1,0,0,0,1,1,1,1],(8,5)),+ ([0,0,0,1,0,0,0,0,0,1,0,0],(8,6)),+ ([0,0,0,0,1,1,1,1,1,0,0,1],(8,7)),+ ([0,0,0,0,1,1,0,1,0,1,0,1,1],(8,8)),+ ([0,0,0,0,1,1,0,0,1,0,0,0,1],(8,9)),+ ([0,0,0,0,1,1,0,0,0,1,0,0,0],(8,10)),+ ([0,0,0,0,1,0,1,1,1,1,1,1,1],(8,11)),+ ([0,0,0,0,1,0,1,1,0,1,0,1,1,1],(8,12)),+ ([0,0,0,0,1,0,1,1,0,0,1,0,0,1],(8,13)),+ ([0,0,0,0,1,0,1,1,0,0,0,1,0,0],(8,14)),+ ([0,0,0,0,0,0,0,1,1,1],(8,15)),+ ([0,0,0,1,0,0,1,1,0,1,0],(9,0)),+ ([0,0,0,1,0,0,1,1,0,0],(9,1)),+ ([0,0,0,1,0,0,1,0,0,1],(9,2)),+ ([0,0,0,1,0,0,0,1,1,0,1],(9,3)),+ ([0,0,0,1,0,0,0,0,0,1,1],(9,4)),+ ([0,0,0,1,0,0,0,0,0,0,0,0],(9,5)),+ ([0,0,0,0,1,1,1,1,0,1,0,1],(9,6)),+ ([0,0,0,0,1,1,0,1,0,1,0,1,0],(9,7)),+ ([0,0,0,0,1,1,0,0,1,0,1,1,0],(9,8)),+ ([0,0,0,0,1,1,0,0,0,1,0,1,0],(9,9)),+ ([0,0,0,0,1,1,0,0,0,0,0,0,0],(9,10)),+ ([0,0,0,0,1,0,1,1,0,1,1,1,1,1],(9,11)),+ ([0,0,0,0,1,0,1,1,0,0,1,1,1],(9,12)),+ ([0,0,0,0,1,0,1,1,0,0,0,1,1,0],(9,13)),+ ([0,0,0,0,1,0,1,1,0,0,0,0,0],(9,14)),+ ([0,0,0,0,0,0,0,1,0,1,1],(9,15)),+ ([0,0,0,1,0,0,0,1,0,1,1],(10,0)),+ ([0,0,0,1,0,0,0,0,0,0,1],(10,1)),+ ([0,0,0,1,0,0,0,0,1,1],(10,2)),+ ([0,0,0,0,1,1,1,1,1,0,1],(10,3)),+ ([0,0,0,0,1,1,1,1,0,1,1,1],(10,4)),+ ([0,0,0,0,1,1,1,0,1,0,0,1],(10,5)),+ ([0,0,0,0,1,1,1,0,0,1,0,1],(10,6)),+ ([0,0,0,0,1,1,0,1,1,0,1,1],(10,7)),+ ([0,0,0,0,1,1,0,0,0,1,0,0,1],(10,8)),+ ([0,0,0,0,1,0,1,1,1,0,0,1,1,1],(10,9)),+ ([0,0,0,0,1,0,1,1,1,0,0,0,0,1],(10,10)),+ ([0,0,0,0,1,0,1,1,0,1,0,0,0,0],(10,11)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,1,0,1],(10,12)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,0,1,0],(10,13)),+ ([0,0,0,0,0,1,1,0,1,1,0,1,1,1],(10,14)),+ ([0,0,0,0,0,0,0,1,0,0],(10,15)),+ ([0,0,0,0,1,1,1,1,0,0,1,1],(11,0)),+ ([0,0,0,0,1,1,1,1,0,0,0],(11,1)),+ ([0,0,0,0,1,1,1,0,1,1,0],(11,2)),+ ([0,0,0,0,1,1,1,0,0,1,1],(11,3)),+ ([0,0,0,0,1,1,1,0,0,0,1,1],(11,4)),+ ([0,0,0,0,1,1,0,1,1,1,1,1],(11,5)),+ ([0,0,0,0,1,1,0,0,0,1,1,0,0],(11,6)),+ ([0,0,0,0,1,0,1,1,1,0,1,0,1,0],(11,7)),+ ([0,0,0,0,1,0,1,1,1,0,0,1,1,0],(11,8)),+ ([0,0,0,0,1,0,1,1,1,0,0,0,0,0],(11,9)),+ ([0,0,0,0,1,0,1,1,0,1,0,0,0,1],(11,10)),+ ([0,0,0,0,1,0,1,1,0,0,1,0,0,0],(11,11)),+ ([0,0,0,0,1,0,1,1,0,0,0,0,1,0],(11,12)),+ ([0,0,0,0,0,1,1,0,1,1,1,1,1],(11,13)),+ ([0,0,0,0,0,1,1,0,1,1,0,1,0,0],(11,14)),+ ([0,0,0,0,0,0,0,0,1,1,0],(11,15)),+ ([0,0,0,0,1,1,0,0,1,0,1,0],(12,0)),+ ([0,0,0,0,1,1,1,0,0,0,0,0],(12,1)),+ ([0,0,0,0,1,1,0,1,1,1,1,0],(12,2)),+ ([0,0,0,0,1,1,0,1,1,0,1,0],(12,3)),+ ([0,0,0,0,1,1,0,1,1,0,0,0],(12,4)),+ ([0,0,0,0,1,1,0,0,0,0,1,0,1],(12,5)),+ ([0,0,0,0,1,1,0,0,0,0,0,1,0],(12,6)),+ ([0,0,0,0,1,0,1,1,1,1,1,0,1],(12,7)),+ ([0,0,0,0,1,0,1,1,0,1,1,0,0],(12,8)),+ ([0,0,0,0,0,1,1,0,1,1,1,1,0,0,0],(12,9)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,1,1],(12,10)),+ ([0,0,0,0,1,0,1,1,0,0,0,0,1,1],(12,11)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,0,0],(12,12)),+ ([0,0,0,0,0,1,1,0,1,1,0,1,0,1],(12,13)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0],(12,14)),+ ([0,0,0,0,0,0,0,0,1,0,0],(12,15)),+ ([0,0,0,0,1,0,1,1,1,0,1,0,1,1],(13,0)),+ ([0,0,0,0,1,1,0,1,0,0,1,1],(13,1)),+ ([0,0,0,0,1,1,0,1,0,0,1,0],(13,2)),+ ([0,0,0,0,1,1,0,1,0,0,0,0],(13,3)),+ ([0,0,0,0,1,0,1,1,1,0,0,1,0],(13,4)),+ ([0,0,0,0,1,0,1,1,1,1,0,1,1],(13,5)),+ ([0,0,0,0,1,0,1,1,0,1,1,1,1,0],(13,6)),+ ([0,0,0,0,1,0,1,1,0,1,0,0,1,1],(13,7)),+ ([0,0,0,0,1,0,1,1,0,0,1,0,1,0],(13,8)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1],(13,9)),+ ([0,0,0,0,0,1,1,0,1,1,1,0,0,1,1],(13,10)),+ ([0,0,0,0,0,1,1,0,1,1,0,1,1,0,1],(13,11)),+ ([0,0,0,0,0,1,1,0,1,1,0,1,1,0,0],(13,12)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1],(13,13)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,0,1],(13,14)),+ ([0,0,0,0,0,0,0,0,0,1,0],(13,15)),+ ([0,0,0,0,1,0,1,1,1,1,0,0,1],(14,0)),+ ([0,0,0,0,1,0,1,1,1,0,0,0,1],(14,1)),+ ([0,0,0,0,1,1,0,0,1,1,0],(14,2)),+ ([0,0,0,0,1,0,1,1,1,0,1,1],(14,3)),+ ([0,0,0,0,1,0,1,1,0,1,0,1,1,0],(14,4)),+ ([0,0,0,0,1,0,1,1,0,1,0,0,1,0],(14,5)),+ ([0,0,0,0,1,0,1,1,0,0,1,1,0],(14,6)),+ ([0,0,0,0,1,0,1,1,0,0,0,1,1,1],(14,7)),+ ([0,0,0,0,1,0,1,1,0,0,0,1,0,1],(14,8)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,1,0],(14,9)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,0],(14,10)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,1,1,1],(14,11)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0],(14,12)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,1,1,0],(14,13)),+ ([0,0,0,0,0,1,1,0,1,1,0,0,1,0],(14,14)),+ ([0,0,0,0,0,0,0,0,0,0,0],(14,15)),+ ([0,0,0,0,0,1,1,0,0],(15,0)),+ ([0,0,0,0,1,0,1,0],(15,1)),+ ([0,0,0,0,0,1,1,1],(15,2)),+ ([0,0,0,0,0,1,0,1,1],(15,3)),+ ([0,0,0,0,0,1,0,1,0],(15,4)),+ ([0,0,0,0,0,1,0,0,0,1],(15,5)),+ ([0,0,0,0,0,0,1,0,1,1],(15,6)),+ ([0,0,0,0,0,0,1,0,0,1],(15,7)),+ ([0,0,0,0,0,0,0,1,1,0,1],(15,8)),+ ([0,0,0,0,0,0,0,1,1,0,0],(15,9)),+ ([0,0,0,0,0,0,0,1,0,1,0],(15,10)),+ ([0,0,0,0,0,0,0,0,1,1,1],(15,11)),+ ([0,0,0,0,0,0,0,0,1,0,1],(15,12)),+ ([0,0,0,0,0,0,0,0,0,1,1],(15,13)),+ ([0,0,0,0,0,0,0,0,0,0,1],(15,14)),+ ([0,0,0,0,0,0,1,1],(15,15))]++tableHuffR14 :: [([Int], (Int, Int))]+tableHuffR14 = [([1,1,1,1],(0,0)),+ ([1,1,0,1],(0,1)),+ ([1,0,1,1,1,0],(0,2)),+ ([1,0,1,0,0,0,0],(0,3)),+ ([1,0,0,1,0,0,1,0],(0,4)),+ ([1,0,0,0,0,0,1,1,0],(0,5)),+ ([0,1,1,1,1,1,0,0,0],(0,6)),+ ([0,1,1,0,1,1,0,0,1,0],(0,7)),+ ([0,1,1,0,1,0,1,0,1,0],(0,8)),+ ([0,1,0,1,0,0,1,1,1,0,1],(0,9)),+ ([0,1,0,1,0,0,0,1,1,0,1],(0,10)),+ ([0,1,0,1,0,0,0,1,0,0,1],(0,11)),+ ([0,1,0,0,1,1,0,1,1,0,1],(0,12)),+ ([0,1,0,0,0,0,0,0,1,0,1],(0,13)),+ ([0,1,0,0,0,0,0,0,1,0,0,0],(0,14)),+ ([0,0,1,0,1,1,0,0,0],(0,15)),+ ([1,1,1,0],(1,0)),+ ([1,1,0,0],(1,1)),+ ([1,0,1,0,1],(1,2)),+ ([1,0,0,1,1,0],(1,3)),+ ([1,0,0,0,1,1,1],(1,4)),+ ([1,0,0,0,0,0,1,0],(1,5)),+ ([0,1,1,1,1,0,1,0],(1,6)),+ ([0,1,1,0,1,1,0,0,0],(1,7)),+ ([0,1,1,0,1,0,0,0,1],(1,8)),+ ([0,1,1,0,0,0,1,1,0],(1,9)),+ ([0,1,0,1,0,0,0,1,1,1],(1,10)),+ ([0,1,0,1,0,1,1,0,0,1],(1,11)),+ ([0,1,0,0,1,1,1,1,1,1],(1,12)),+ ([0,1,0,0,1,0,1,0,0,1],(1,13)),+ ([0,1,0,0,0,1,0,1,1,1],(1,14)),+ ([0,0,1,0,1,0,1,0],(1,15)),+ ([1,0,1,1,1,1],(2,0)),+ ([1,0,1,1,0],(2,1)),+ ([1,0,1,0,0,1],(2,2)),+ ([1,0,0,1,0,1,0],(2,3)),+ ([1,0,0,0,1,0,0],(2,4)),+ ([1,0,0,0,0,0,0,0],(2,5)),+ ([0,1,1,1,1,0,0,0],(2,6)),+ ([0,1,1,0,1,1,1,0,1],(2,7)),+ ([0,1,1,0,0,1,1,1,1],(2,8)),+ ([0,1,1,0,0,0,0,1,0],(2,9)),+ ([0,1,0,1,1,0,1,1,0],(2,10)),+ ([0,1,0,1,0,1,0,1,0,0],(2,11)),+ ([0,1,0,0,1,1,1,0,1,1],(2,12)),+ ([0,1,0,0,1,0,0,1,1,1],(2,13)),+ ([0,1,0,0,0,0,1,1,1,0,1],(2,14)),+ ([0,0,1,0,0,1,0],(2,15)),+ ([1,0,1,0,0,0,1],(3,0)),+ ([1,0,0,1,1,1],(3,1)),+ ([1,0,0,1,0,1,1],(3,2)),+ ([1,0,0,0,1,1,0],(3,3)),+ ([1,0,0,0,0,1,1,0],(3,4)),+ ([0,1,1,1,1,1,0,1],(3,5)),+ ([0,1,1,1,0,1,0,0],(3,6)),+ ([0,1,1,0,1,1,1,0,0],(3,7)),+ ([0,1,1,0,0,1,1,0,0],(3,8)),+ ([0,1,0,1,1,1,1,1,0],(3,9)),+ ([0,1,0,1,1,0,0,1,0],(3,10)),+ ([0,1,0,1,0,0,0,1,0,1],(3,11)),+ ([0,1,0,0,1,1,0,1,1,1],(3,12)),+ ([0,1,0,0,1,0,0,1,0,1],(3,13)),+ ([0,1,0,0,0,0,1,1,1,1],(3,14)),+ ([0,0,1,0,0,0,0],(3,15)),+ ([1,0,0,1,0,0,1,1],(4,0)),+ ([1,0,0,1,0,0,0],(4,1)),+ ([1,0,0,0,1,0,1],(4,2)),+ ([1,0,0,0,0,1,1,1],(4,3)),+ ([0,1,1,1,1,1,1,1],(4,4)),+ ([0,1,1,1,0,1,1,0],(4,5)),+ ([0,1,1,1,0,0,0,0],(4,6)),+ ([0,1,1,0,1,0,0,1,0],(4,7)),+ ([0,1,1,0,0,1,0,0,0],(4,8)),+ ([0,1,0,1,1,1,1,0,0],(4,9)),+ ([0,1,0,1,1,0,0,0,0,0],(4,10)),+ ([0,1,0,1,0,0,0,0,1,1],(4,11)),+ ([0,1,0,0,1,1,0,0,1,0],(4,12)),+ ([0,1,0,0,0,1,1,1,0,1],(4,13)),+ ([0,1,0,0,0,0,1,1,1,0,0],(4,14)),+ ([0,0,0,1,1,1,0],(4,15)),+ ([1,0,0,0,0,0,1,1,1],(5,0)),+ ([1,0,0,0,0,1,0],(5,1)),+ ([1,0,0,0,0,0,0,1],(5,2)),+ ([0,1,1,1,1,1,1,0],(5,3)),+ ([0,1,1,1,0,1,1,1],(5,4)),+ ([0,1,1,1,0,0,1,0],(5,5)),+ ([0,1,1,0,1,0,1,1,0],(5,6)),+ ([0,1,1,0,0,1,0,1,0],(5,7)),+ ([0,1,1,0,0,0,0,0,0],(5,8)),+ ([0,1,0,1,1,0,1,0,0],(5,9)),+ ([0,1,0,1,0,1,0,1,0,1],(5,10)),+ ([0,1,0,0,1,1,1,1,0,1],(5,11)),+ ([0,1,0,0,1,0,1,1,0,1],(5,12)),+ ([0,1,0,0,0,1,1,0,0,1],(5,13)),+ ([0,1,0,0,0,0,0,1,1,0],(5,14)),+ ([0,0,0,1,1,0,0],(5,15)),+ ([0,1,1,1,1,1,0,0,1],(6,0)),+ ([0,1,1,1,1,0,1,1],(6,1)),+ ([0,1,1,1,1,0,0,1],(6,2)),+ ([0,1,1,1,0,1,0,1],(6,3)),+ ([0,1,1,1,0,0,0,1],(6,4)),+ ([0,1,1,0,1,0,1,1,1],(6,5)),+ ([0,1,1,0,0,1,1,1,0],(6,6)),+ ([0,1,1,0,0,0,0,1,1],(6,7)),+ ([0,1,0,1,1,1,0,0,1],(6,8)),+ ([0,1,0,1,0,1,1,0,1,1],(6,9)),+ ([0,1,0,1,0,0,1,0,1,0],(6,10)),+ ([0,1,0,0,1,1,0,1,0,0],(6,11)),+ ([0,1,0,0,1,0,0,0,1,1],(6,12)),+ ([0,1,0,0,0,1,0,0,0,0],(6,13)),+ ([0,1,0,0,0,0,0,1,0,0,0],(6,14)),+ ([0,0,0,1,0,1,0],(6,15)),+ ([0,1,1,0,1,1,0,0,1,1],(7,0)),+ ([0,1,1,1,0,0,1,1],(7,1)),+ ([0,1,1,0,1,1,1,1],(7,2)),+ ([0,1,1,0,1,1,0,1],(7,3)),+ ([0,1,1,0,1,0,0,1,1],(7,4)),+ ([0,1,1,0,0,1,0,1,1],(7,5)),+ ([0,1,1,0,0,0,1,0,0],(7,6)),+ ([0,1,0,1,1,1,0,1,1],(7,7)),+ ([0,1,0,1,1,0,0,0,0,1],(7,8)),+ ([0,1,0,1,0,0,1,1,0,0],(7,9)),+ ([0,1,0,0,1,1,1,0,0,1],(7,10)),+ ([0,1,0,0,1,0,1,0,1,0],(7,11)),+ ([0,1,0,0,0,1,1,0,1,1],(7,12)),+ ([0,1,0,0,0,0,1,0,0,1,1],(7,13)),+ ([0,0,1,0,1,1,1,1,1,0,1],(7,14)),+ ([0,0,0,1,0,0,0,1],(7,15)),+ ([0,1,1,0,1,0,1,0,1,1],(8,0)),+ ([0,1,1,0,1,0,1,0,0],(8,1)),+ ([0,1,1,0,1,0,0,0,0],(8,2)),+ ([0,1,1,0,0,1,1,0,1],(8,3)),+ ([0,1,1,0,0,1,0,0,1],(8,4)),+ ([0,1,1,0,0,0,0,0,1],(8,5)),+ ([0,1,0,1,1,1,0,1,0],(8,6)),+ ([0,1,0,1,1,0,0,0,1],(8,7)),+ ([0,1,0,1,0,1,0,0,1],(8,8)),+ ([0,1,0,1,0,0,0,0,0,0],(8,9)),+ ([0,1,0,0,1,0,1,1,1,1],(8,10)),+ ([0,1,0,0,0,1,1,1,1,0],(8,11)),+ ([0,1,0,0,0,0,1,1,0,0],(8,12)),+ ([0,1,0,0,0,0,0,0,0,1,0],(8,13)),+ ([0,0,1,0,1,1,1,1,0,0,1],(8,14)),+ ([0,0,0,1,0,0,0,0],(8,15)),+ ([0,1,0,1,0,0,1,1,1,1],(9,0)),+ ([0,1,1,0,0,0,1,1,1],(9,1)),+ ([0,1,1,0,0,0,1,0,1],(9,2)),+ ([0,1,0,1,1,1,1,1,1],(9,3)),+ ([0,1,0,1,1,1,1,0,1],(9,4)),+ ([0,1,0,1,1,0,1,0,1],(9,5)),+ ([0,1,0,1,0,1,1,1,0],(9,6)),+ ([0,1,0,1,0,0,1,1,0,1],(9,7)),+ ([0,1,0,1,0,0,0,0,0,1],(9,8)),+ ([0,1,0,0,1,1,0,0,0,1],(9,9)),+ ([0,1,0,0,1,0,0,0,0,1],(9,10)),+ ([0,1,0,0,0,1,0,0,1,1],(9,11)),+ ([0,1,0,0,0,0,0,1,0,0,1],(9,12)),+ ([0,0,1,0,1,1,1,1,0,1,1],(9,13)),+ ([0,0,1,0,1,1,1,0,0,1,1],(9,14)),+ ([0,0,0,0,1,0,1,1],(9,15)),+ ([0,1,0,1,0,0,1,1,1,0,0],(10,0)),+ ([0,1,0,1,1,1,0,0,0],(10,1)),+ ([0,1,0,1,1,0,1,1,1],(10,2)),+ ([0,1,0,1,1,0,0,1,1],(10,3)),+ ([0,1,0,1,0,1,1,1,1],(10,4)),+ ([0,1,0,1,0,1,1,0,0,0],(10,5)),+ ([0,1,0,1,0,0,1,0,1,1],(10,6)),+ ([0,1,0,0,1,1,1,0,1,0],(10,7)),+ ([0,1,0,0,1,1,0,0,0,0],(10,8)),+ ([0,1,0,0,1,0,0,0,1,0],(10,9)),+ ([0,1,0,0,0,1,0,1,0,1],(10,10)),+ ([0,1,0,0,0,0,1,0,0,1,0],(10,11)),+ ([0,0,1,0,1,1,1,1,1,1,1],(10,12)),+ ([0,0,1,0,1,1,1,0,1,0,1],(10,13)),+ ([0,0,1,0,1,1,0,1,1,1,0],(10,14)),+ ([0,0,0,0,1,0,1,0],(10,15)),+ ([0,1,0,1,0,0,0,1,1,0,0],(11,0)),+ ([0,1,0,1,0,1,1,0,1,0],(11,1)),+ ([0,1,0,1,0,1,0,1,1],(11,2)),+ ([0,1,0,1,0,1,0,0,0],(11,3)),+ ([0,1,0,1,0,0,1,0,0],(11,4)),+ ([0,1,0,0,1,1,1,1,1,0],(11,5)),+ ([0,1,0,0,1,1,0,1,0,1],(11,6)),+ ([0,1,0,0,1,0,1,0,1,1],(11,7)),+ ([0,1,0,0,0,1,1,1,1,1],(11,8)),+ ([0,1,0,0,0,1,0,1,0,0],(11,9)),+ ([0,1,0,0,0,0,0,1,1,1],(11,10)),+ ([0,1,0,0,0,0,0,0,0,0,1],(11,11)),+ ([0,0,1,0,1,1,1,0,1,1,1],(11,12)),+ ([0,0,1,0,1,1,1,0,0,0,0],(11,13)),+ ([0,0,1,0,1,1,0,1,0,1,0],(11,14)),+ ([0,0,0,0,0,1,1,0],(11,15)),+ ([0,1,0,1,0,0,0,1,0,0,0],(12,0)),+ ([0,1,0,1,0,0,0,0,1,0],(12,1)),+ ([0,1,0,0,1,1,1,1,0,0],(12,2)),+ ([0,1,0,0,1,1,1,0,0,0],(12,3)),+ ([0,1,0,0,1,1,0,0,1,1],(12,4)),+ ([0,1,0,0,1,0,1,1,1,0],(12,5)),+ ([0,1,0,0,1,0,0,1,0,0],(12,6)),+ ([0,1,0,0,0,1,1,1,0,0],(12,7)),+ ([0,1,0,0,0,0,1,1,0,1],(12,8)),+ ([0,1,0,0,0,0,0,1,0,1],(12,9)),+ ([0,1,0,0,0,0,0,0,0,0,0],(12,10)),+ ([0,0,1,0,1,1,1,1,0,0,0],(12,11)),+ ([0,0,1,0,1,1,1,0,0,1,0],(12,12)),+ ([0,0,1,0,1,1,0,1,1,0,0],(12,13)),+ ([0,0,1,0,1,1,0,0,1,1,1],(12,14)),+ ([0,0,0,0,0,1,0,0],(12,15)),+ ([0,1,0,0,1,1,0,1,1,0,0],(13,0)),+ ([0,1,0,0,1,0,1,1,0,0],(13,1)),+ ([0,1,0,0,1,0,1,0,0,0],(13,2)),+ ([0,1,0,0,1,0,0,1,1,0],(13,3)),+ ([0,1,0,0,1,0,0,0,0,0],(13,4)),+ ([0,1,0,0,0,1,1,0,1,0],(13,5)),+ ([0,1,0,0,0,1,0,0,0,1],(13,6)),+ ([0,1,0,0,0,0,1,0,1,0],(13,7)),+ ([0,1,0,0,0,0,0,0,0,1,1],(13,8)),+ ([0,0,1,0,1,1,1,1,1,0,0],(13,9)),+ ([0,0,1,0,1,1,1,0,1,1,0],(13,10)),+ ([0,0,1,0,1,1,1,0,0,0,1],(13,11)),+ ([0,0,1,0,1,1,0,1,1,0,1],(13,12)),+ ([0,0,1,0,1,1,0,1,0,0,1],(13,13)),+ ([0,0,1,0,1,1,0,0,1,0,1],(13,14)),+ ([0,0,0,0,0,0,1,0],(13,15)),+ ([0,1,0,0,0,0,0,0,1,0,0,1],(14,0)),+ ([0,1,0,0,0,1,1,0,0,0],(14,1)),+ ([0,1,0,0,0,1,0,1,1,0],(14,2)),+ ([0,1,0,0,0,1,0,0,1,0],(14,3)),+ ([0,1,0,0,0,0,1,0,1,1],(14,4)),+ ([0,1,0,0,0,0,1,0,0,0],(14,5)),+ ([0,1,0,0,0,0,0,0,1,1],(14,6)),+ ([0,0,1,0,1,1,1,1,1,1,0],(14,7)),+ ([0,0,1,0,1,1,1,1,0,1,0],(14,8)),+ ([0,0,1,0,1,1,1,0,1,0,0],(14,9)),+ ([0,0,1,0,1,1,0,1,1,1,1],(14,10)),+ ([0,0,1,0,1,1,0,1,0,1,1],(14,11)),+ ([0,0,1,0,1,1,0,1,0,0,0],(14,12)),+ ([0,0,1,0,1,1,0,0,1,1,0],(14,13)),+ ([0,0,1,0,1,1,0,0,1,0,0],(14,14)),+ ([0,0,0,0,0,0,0,0],(14,15)),+ ([0,0,1,0,1,0,1,1],(15,0)),+ ([0,0,1,0,1,0,0],(15,1)),+ ([0,0,1,0,0,1,1],(15,2)),+ ([0,0,1,0,0,0,1],(15,3)),+ ([0,0,0,1,1,1,1],(15,4)),+ ([0,0,0,1,1,0,1],(15,5)),+ ([0,0,0,1,0,1,1],(15,6)),+ ([0,0,0,1,0,0,1],(15,7)),+ ([0,0,0,0,1,1,1],(15,8)),+ ([0,0,0,0,1,1,0],(15,9)),+ ([0,0,0,0,1,0,0],(15,10)),+ ([0,0,0,0,0,1,1,1],(15,11)),+ ([0,0,0,0,0,1,0,1],(15,12)),+ ([0,0,0,0,0,0,1,1],(15,13)),+ ([0,0,0,0,0,0,0,1],(15,14)),+ ([0,0,1,1],(15,15))]+
+ Codec/Audio/MP3/Types.hs view
@@ -0,0 +1,125 @@+--+-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--++module Codec.Audio.MP3.Types where++-- +-- Simple types.+--+type Sample = Double+type Frequency = Double++type SampleRate = Int++data ChannelMode = Mono + | Stereo + | DualChannel + | JointStereo + deriving (Eq)++instance Show ChannelMode where+ show Mono = "Mono"+ show Stereo = "Stereo"+ show DualChannel = "DualChannel"+ show JointStereo = "JointStereo"++data BlockFlag = LongBlocks + | ShortBlocks + | MixedBlocks + deriving (Eq)++instance Show BlockFlag where+ show LongBlocks = "LongBlocks"+ show ShortBlocks = "ShortBlocks"+ show MixedBlocks = "MixedBlocks"++-- +-- For decoding.+--+data MP3FrameHeader = MP3FrameHeader {+ headBitrate :: Int,+ headSampleRate :: SampleRate,+ headChannels :: ChannelMode,+ -- details+ headCRC :: Bool,+ headPadding :: Int,+ headStereoMS :: Bool,+ headStereoIS :: Bool+} deriving (Show)++-- Layer between MP3 and MP3Unpack+data MP3Data = MP3Data1Channels SampleRate ChannelMode (Bool, Bool) + MP3DataChunk MP3DataChunk+ | MP3Data2Channels SampleRate ChannelMode (Bool, Bool) + MP3DataChunk MP3DataChunk + MP3DataChunk MP3DataChunk+ deriving (Show)++mp3dataChunk00 (MP3Data1Channels _ _ _ chunk _) = chunk+mp3dataChunk00 (MP3Data2Channels _ _ _ chunk _ _ _) = chunk++mp3dataSampleRate (MP3Data1Channels sr _ _ _ _) = sr+mp3dataSampleRate (MP3Data2Channels sr _ _ _ _ _ _) = sr++data MP3DataChunk = MP3DataChunk {+ chunkBlockType :: !Int,+ chunkBlockFlag :: !BlockFlag,+ chunkScaleGain :: !Double,+ chunkScaleSubGain :: !(Double, Double, Double),+ chunkScaleLong :: ![Double],+ chunkScaleShort :: ![[Double]],+ chunkISParam :: !([Int], [[Int]]),+ chunkData :: ![Int]+} deriving (Show)+++-- Pretty print.++prettyData (MP3Data1Channels sr ch (ms, is) c00 c10) =+ show sr ++ "Hz" +++ " " ++ printCh ch (ms, is) ++ + " Chunks: [" ++ printDC c00 ++ + "," ++ printDC c10 ++ "]"++prettyData (MP3Data2Channels sr ch (ms, is) c00 c01 c10 c11) = + show sr ++ "Hz" +++ " " ++ printCh ch (ms, is) ++ + " Chunks: [" ++ printDC c00 ++ + "," ++ printDC c01 +++ "," ++ printDC c10 +++ "," ++ printDC c11 ++ "]"++printDC (MP3DataChunk bt bf _ _ _ _ _ _) = printBF bf ++ "(" ++ show bt ++ ")"++printBF LongBlocks = "L"+printBF ShortBlocks = "S"+printBF MixedBlocks = "M"++printCh JointStereo (True, True) = "JointStereo (MS, IS)"+printCh JointStereo (True, False) = "JointStereo (MS)"+printCh JointStereo (False, True) = "JointStereo (IS)"+printCh JointStereo _ = "JointStereo"+printCh ch _ = show ch++
+ Codec/Audio/MP3/Unpack.hs view
@@ -0,0 +1,893 @@+-- +-- module Unpack - Unpacks an MP3 bitstream into parts.+--+-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--+-- Small Warning: Unpacking the bitstream is the messiest part of+-- MP3-decoding, so this code is not the prettiest ever written.+--+-- We unpack the bitstream in two steps.+--+-- 1) The bytes in an MP3 are grouped in blocks known as frames.+-- A frame consists of a header, side data, and main data.+-- The header has some information about the properties of the+-- audio. The side data contains some information about how+-- the audio should be decoded, but most bits describe+-- how to unpack the main data.+--+-- The main data within a frame do not necessarily+-- correspond to the header and side data. The first step is to+-- take the "physical" frames and group them into "logical+-- frames", consisting of one header, side data, and+-- bytes of main data.+--+-- 2) We then take the logical frame and unpack the main data,+-- according to the parameters saved in the side data.+-- The main data consists of two "granules", containing one+-- or two channels each. Each of these channel granules are+-- later decoded (more or less) separately.+--+-- Each channel granule consists of scale information, and+-- huffman coded audio.+--++module Codec.Audio.MP3.Unpack (+ mp3Seek+ ,mp3Unpack+ ,MP3Bitstream(..)+) where+++-- binary-strict from Hackage.+import qualified Data.Binary.Strict.BitGet as BG+import Data.Binary.Strict.Get++import qualified Data.ByteString as B+import Data.Word+import Data.Bits+import Control.Monad (replicateM)++import Codec.Audio.MP3.Huffman+import Codec.Audio.MP3.Types+import Codec.Audio.MP3.Tables++import Debug.Trace++-- +-- Exported types.+--++data MP3Bitstream = MP3Bitstream {+ bitstreamStream :: B.ByteString,+ bitstreamBuffer :: [Word8]+} deriving (Show)++-- +-- The types below are only used in this module during unpacking.+-- Important information needed elsewhere is copied to another+-- data structure described in Types.hs+--++data MP3LogicalFrame = MP3LogicalFrame {+ logicalHeader :: MP3FrameHeader,+ logicalSide :: MP3SideInfo,+ logicalData :: [Word8]+} deriving (Show)++data MP3HuffmanData = MP3HuffmanData {+ huffmanBigValues :: Int,+ huffmanRegionLengths :: (Int, Int, Int),+ huffmanTable :: (Int, Int, Int),+ huffmanCount1Table :: Int+} deriving (Show)++data MP3ScaleData = MP3ScaleData {+ scaleGlobalGain :: Double,+ scaleLengths :: (Int, Int),+ scaleSubblockGain :: (Double, Double, Double),+ scaleScalefacScale :: Int,+ scalePreflag :: Int +} deriving (Show)++data MP3SideData = MP3SideData {+ sideHuffman :: MP3HuffmanData,+ sideScalefactor :: MP3ScaleData,+ sidePart23Length :: Int,+ sideBlocktype :: Int,+ sideBlockflag :: BlockFlag+} deriving (Show)+ +data MP3SideInfo = MP3SideInfo1Ch { sideMaindata :: Int, + sideScfsi :: Int, + sideGranule0ch0 :: MP3SideData, + sideGranule1ch0 :: MP3SideData }+ | MP3SideInfo2Ch { sideMaindata :: Int,+ sideScfsi :: Int,+ sideGranule0ch0 :: MP3SideData,+ sideGranule0ch1 :: MP3SideData,+ sideGranule1ch0 :: MP3SideData,+ sideGranule1ch1 :: MP3SideData } + deriving (Show)+++-- +-- Generic utilities.+--++flattenTuple :: [(a, a)] -> [a]+flattenTuple [] = []+flattenTuple ((x0,x1):xs) = x0 : x1 : flattenTuple xs++applyTuple :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)+applyTuple f1 f2 (x, y) = (f1 x, f2 y)++toBool 0 = False+toBool _ = True++padWith :: Int -> a -> [a] -> [a]+padWith n padding xs = xs ++ replicate (n - length xs) padding++--+-- Utilities for dealing with bits.+--++-- binery-strict is broken on some some setups so we use the safe but slow+-- method of constructing integers from individual bits. BG.getBit works.+getBitsFixed 0 = return 0+getBitsFixed n = do bit0 <- BG.getBit >>= return . fromEnum+ rest <- getBitsFixed (n-1)+ return $ bit0 `shiftL` (n-1) .|. rest+++toWord32 :: [Word8] -> Word32+toWord32 (b0:b1:b2:b3:[]) = (fromIntegral b3)+ + (fromIntegral b2) * 0x100+ + (fromIntegral b1) * 0x10000+ + (fromIntegral b0) * 0x1000000+toWord32 _ = 0++bsGetWord32 :: B.ByteString -> Word32+bsGetWord32 = toWord32 . B.unpack . (B.take 4)++-- Extract an interval of bits from a larger integer.+-- bitInterval '11111111 11100000 00000000 00000000' 21 11 = '11111111 111'+bitInterval :: (Bits a) => a -> Int -> Int -> a+bitInterval word start size = (word `shiftR` start) .&. + ((1 `shiftL` size)-1)+++--+-- mp3ParseFrameHeader+--+-- Get the important (needed for decoding) stuff out of a frame header.+--+-- Return values:+--+-- The function will return Nothing if the frame is malformed,+-- or if it's a valid header but a format not supported by this+-- decoder, such as MP2.+--+-- Info:+--+-- The first 11 bits of a correct header is the sync word, 0x7ff.+-- IS and MS are two stereo processing modes used to reduce+-- the size of a Joint Stereo MP3. Info in Decoder.hs.+--+mp3ParseFrameHeader :: Word32 -> Maybe MP3FrameHeader+mp3ParseFrameHeader bits+ | bitsSync /= 0x7ff = Nothing+ | bitsMpeg /= 3 = Nothing -- We only support MPEG1 (bits=3)+ | bitsLayer /= 1 = Nothing -- We only support Layer3 (bits=1)+ | bitsBitrate == 0 || + bitsBitrate == 15 = Nothing+ | bitsSR == 3 = Nothing+ | otherwise = Just $ MP3FrameHeader bitrate samplerate + channels crc padding ms is+ where+ bitrate = [ 0, 32, 40, 48, 56, 64, + 80, 96, 112, 128, 160, 192, + 224, 256, 320, 0] !! (fromIntegral bitsBitrate)+ samplerate = [44100, 48000, 32000] !! (fromIntegral bitsSR)+ channels = [Stereo, JointStereo, + DualChannel, Mono] !! (fromIntegral bitsCh)+ crc = [True, False] !! (fromIntegral bitsCRC)+ padding = fromIntegral bitsPadding+ (is, ms) = [(False, False), (True, False), + (False, True), (True, True)] !! (fromIntegral bitsMode)+ bitsSync = bitInterval bits 21 11+ bitsMpeg = bitInterval bits 19 2+ bitsLayer = bitInterval bits 17 2+ bitsCRC = bitInterval bits 16 1+ bitsBitrate = bitInterval bits 12 4+ bitsSR = bitInterval bits 10 2+ bitsPadding = bitInterval bits 9 1+ bitsCh = bitInterval bits 6 2+ bitsMode = bitInterval bits 4 2+ --getbits = bitInterval bits+++-- +-- mp3FrameLength+--+-- How long a physical frame is, in bytes.+--+-- This simplified expression takes the frame length, side info length+-- and main data into account.+--+mp3FrameLength :: MP3FrameHeader -> Int+mp3FrameLength header = let br = headBitrate header+ sr = headSampleRate header+ padding = headPadding header+ in (144 * 1000 * br) `div` sr + padding+++--+-- mp3ParseSideInfo+--+-- Parse the (32 for stereo, 17 for mono) side data bytes.+--+-- Return values:+--+-- The function will return Nothing if+-- The input buffer is too short.+-- The input buffer is of the correct size, but contains invalid data.+-- The function will return a Just MP3SideInfo otherwise.+--+-- Info:+--+-- Many of the bits in the side info are indices to tables defined+-- in the MP3 standard, and are thus not interesting in themselves.+-- In this MP3 decoder, the design choice is to parse these bits+-- as early as possible.+--+mp3ParseSideInfo :: MP3FrameHeader -> [Word8] -> Maybe MP3SideInfo+mp3ParseSideInfo header buffer = + case BG.runBitGet stream (if mono then getMono + else getStereo) of+ Right ret -> ret+ otherwise -> Nothing+ where+ stream = B.pack buffer+ mono = Mono == headChannels header+ samplerate = headSampleRate header++ getMono = do dataptr <- getBitsFixed 9+ private <- getBitsFixed 5 + scfsi <- getBitsFixed 4 + granule0ch0 <- bitSideData+ granule1ch0 <- bitSideData+ return $ constr (fromIntegral dataptr) + scfsi + granule0ch0 + granule1ch0+ where+ constr dataptr scfsi (Just g00) (Just g01) = + Just $ MP3SideInfo1Ch dataptr scfsi g00 g01+ constr _ _ _ _ = Nothing++ getStereo = do dataptr <- getBitsFixed 9+ private <- getBitsFixed 3+ scfsi <- getBitsFixed 8 -- 4 bits per channel+ granule0ch0 <- bitSideData+ granule0ch1 <- bitSideData+ granule1ch0 <- bitSideData+ granule1ch1 <- bitSideData+ return $ constr (fromIntegral dataptr)+ scfsi + granule0ch0 + granule0ch1 + granule1ch0 + granule1ch1+ where+ constr dataptr scfsi (Just g00) (Just g01) + (Just g10) (Just g11) = + Just $ MP3SideInfo2Ch dataptr scfsi g00 g01 g10 g11+ constr _ _ _ _ _ _ = Nothing++ validateTable n+ | n == 4 || n == 14 = False+ | otherwise = True++ toBlockflag mixedflag blocktype+ | mixedflag == True = MixedBlocks+ | mixedflag == False && blocktype == 2 = ShortBlocks+ | otherwise = LongBlocks++ bitSideData = do + -- To parse side data (this): flag.+ -- To parse main data: part23.+ -- To parse main data (huffman): bigvalues, table0-2.+ -- To parse main data (scales): scalelengths.+ -- For decoding the audio in Decoder.hs: globalgain, + -- blocktype, blockflag subgain0-2.+ part23 <- getBitsFixed 12+ bigvalues <- getBitsFixed 9+ globalgainb <- getBitsFixed 8+ let globalgain = mp3FloatRep1 globalgainb+ scalelengths <- getBitsFixed 4 >>= return . (tableSlen !!)+ flag <- BG.getBit+ blocktype <- getBitsFixed (if flag then 2 else 0)+ mixed <- getBitsFixed (if flag then 1 else 0) >>= + return . toEnum+ let blockflag = toBlockflag mixed blocktype+ table0 <- getBitsFixed 5+ table1 <- getBitsFixed 5+ table2 <- getBitsFixed (if flag then 0 else 5)+ subgain0b <- getBitsFixed (if flag then 3 else 0)+ subgain1b <- getBitsFixed (if flag then 3 else 0)+ subgain2b <- getBitsFixed (if flag then 3 else 0)+ let subgain0 = mp3FloatRep2 subgain0b+ subgain1 = mp3FloatRep2 subgain1b+ subgain2 = mp3FloatRep2 subgain2b++ -- To parse main data (huffman): r0len, r1len, r2len.+ -- This computation is slightly involved.+ regionabits <- getBitsFixed (if flag then 0 else 4)+ regionbbits <- getBitsFixed (if flag then 0 else 3)+ let racnt = if flag then (if blocktype == 2 then 8 else 7)+ else regionabits+ rbcnt = if flag then 20 - racnt+ else regionbbits+ sbTable = tableScaleBandBoundary samplerate+ r1bound = sbTable $ racnt + 1+ r2bound = sbTable $ racnt + 1 + rbcnt + 1+ bv2 = bigvalues*2+ r0len = if blocktype == 2 + then min bv2 36+ else min bv2 r1bound+ r1len = if blocktype == 2 + then min (bv2-r0len) 540 + else min (bv2-r0len) (r2bound - r0len) + r2len = if blocktype == 2 + then 0 + else bv2 - (r0len + r1len)++ -- To parse main data (huffman): count1table.+ -- To parse the main data (scales): scalefacscale, preflag.+ preflag <- BG.getBit >>= return . fromEnum+ scalefacbit <- BG.getBit+ let scalefacscale = if scalefacbit then 1 else 0 + count1table <- BG.getBit >>= return . fromEnum++ -- huffdata has data needed by the Huffman decoder.+ -- scaledata has data needed for parsing the scale data,+ -- and it also has a few parameters needed by the decoder+ -- in Decoder.hs.+ let huffdata = MP3HuffmanData bigvalues (r0len, r1len, r2len)+ (table0, table1, table2) count1table+ scaledata = MP3ScaleData globalgain scalelengths+ (subgain0, subgain1, subgain2)+ scalefacscale preflag+ valid = if (validateTable table0) && + (validateTable table1) &&+ (if flag then True else validateTable table2) + then True else False+ return $ if valid then Just (MP3SideData huffdata scaledata part23 + blocktype blockflag)+ else Nothing+++-- mp3PeekDataPtr takes an unparsed ByteString and returns the dataptr+-- (see mp3ParseSideInfo).+mp3PeekDataPtr :: B.ByteString -> Maybe Int+mp3PeekDataPtr bs =+ case mp3ParseFrameHeader (toWord32 (B.unpack (B.take 4 bs))) of+ Nothing -> Nothing+ Just header -> let len = 4 + if headCRC header then 2 else 0+ in case BG.runBitGet (B.drop len bs) bitGetter of+ Right ret -> Just ret+ otherwise -> Nothing+ where+ bitGetter = do getBitsFixed 9++-- +-- Warning: This decoder treats some bits as floatings points.+-- The specification instead treats them as integers. Se discussion+-- at www.bjrn.se/mp3dec+--+-- The side info has two floating point representations+--+-- Representation 1 maps an 8 bit value to the range 0.0 - 2435.5.+--+-- Representation 2 maps a 3 bit value to the range +-- [1, 0.25, 0.0625, 0.01563, 0.00391, 0.00098, 0.00024, 0.00006]+--+mp3FloatRep1 :: Int -> Double+mp3FloatRep1 n = 2.0 ** (0.25 * (fromIntegral n - 210))++mp3FloatRep2 :: Int -> Double+mp3FloatRep2 n = 2.0 ** (0.25 * (fromIntegral (-n * 8)))++-- +-- mp3DecodeHuffman+--+-- Decodes the Huffman data to audio (in the frequency domain).+--+-- The huffman coded bits are grouped in five regions, in+-- the 576 frequency bands:+--+-- | region 0 | region 1 | region 2 | count1 region | zero |+--+-- region0-2 are collectively known as the "big values" regions, as+-- the decoded bits are large (-8206 - 8206). These regions represent the+-- lower frequency bands.+--+-- The count 1 region represent the higher frequencies, and can only take+-- on small values (-1 to 1). As the ear is insensitive in these+-- regions, not as much information is required to represent these+-- frequencies.+--+-- The zero region are the frequencies so high they have been removed+-- by the encoder. These frequencies have magnitude 0.+--+-- Different Huffman tables are used by the different regions for better+-- compression. (table1, table2, table3) correspond to the big values+-- regions, while tableC1 is for the count1 region. We call the three first+-- tables the "normal" tables. A normal table outputs two frequency samples.+-- We call the count1 table the quad table, as it outputs four frequency+-- samples.+--+-- The normal tables are decoded as follows:+--+-- 1) Consume input bits until we get a hit in the right Huffman tree. +-- We now have a tuple of two values (x,y), and also the linbits value +-- described further below.+-- 2) If x == 15, read linbits bits and add to x. This makes sure the+-- frequency sample can be large, if necessary.+-- 3) If x /= 0, get one bit. If this bit is one, x is negative, otherwise+-- positive.+-- 4) Do step 2 and 3 for y.+--+-- The quad table is decoded as follows:+--+-- 1) Consume input bits until we get a hit in the right Huffman tree.+-- We now have a 4-tuple (x,w,x,y).+-- 2) If v /= 0, get one bit. If this bit is one, v is negative, otherwise+-- positive.+-- 3) Do step 2 for w, x, y.+--+-- The length, in number of output samples, for region0-2 is r0len to +-- r2len respectively.+-- The length, in number of output samples, for the quad region is not +-- known explicitly, but is calculated from bitlength of the main data +-- and the number of bits read when decoding the big values regions.+--+-- TODO:+--+-- This code can be optimized significantly, without hurting readability+-- too much. Instead of walking the tree, consuming one bit at a time+-- until we find a hit in the tree, a large lookup table can be used. +-- Consider a Huffman tree where the longest code word is N bits. We+-- create a lookup table of 2^N elements, where all code words shorter+-- than N bits are padded with all bitstrings until they are of length+-- N. To use the table, we peek N bits in the bitstream, and use these+-- bits as an index to the lookup table. There we find the length of the+-- code word (so we can throw away the correct number of bits), and the +-- value.+--+-- Say we have the following Huffman table:+--+-- code word value+-- 0 a+-- 10 b+-- 111 c+--+-- The corresponding lookup-table will look like this:+--+-- table[000] = (a, 1)+-- table[001] = (a, 1)+-- table[010] = (a, 1)+-- table[011] = (a, 1)+-- table[100] = (b, 2)+-- table[101] = (b, 2)+-- table[110] = Null+-- table[111] = (c, 3)+--+-- To use the table, we peek 3 bits, checks the table. If the result is+-- (b, 2), we throw away 2 bits, and start over.+--+-- For tables where the longest code word is large, real world +-- decoders use a technique where the lookup table contains "pointers"+-- to other parts of the table, to handle the rare cases where the+-- code words are very long.+--++--mp3DecodeHuffman huffdata part23len part2len = +mp3DecodeHuffman huffdata huffbitlength =+ do (reg0, bitcount0) <- decodeRegion r0len table1 + (reg1, bitcount1) <- decodeRegion r1len table2 + (reg2, bitcount2) <- decodeRegion r2len table3 + let bitsread = bitcount0 + bitcount1 + bitcount2+ rqlen = huffbitlength - bitsread - 1+ regQ <- decodeRegionQ tableC1 rqlen [] + return $ reg0 ++ reg1 ++ reg2 ++ regQ+ where+ (r0len, r1len, r2len) = huffmanRegionLengths huffdata+ (table1, table2, table3) = huffmanTable huffdata+ tableC1 = huffmanCount1Table huffdata++ -- We divide reglen by 2 as each normal Huffman tree has 2 output+ -- samples. The stuff after >>= takes the list of+ -- ((sample0,sample1),bitsread) and constructs a new list+ -- [sample0,sample1,...] as well as a sum of the bits read.+ decodeRegion reglen tablen = + replicateM (reglen `div` 2) (decodeOne tablen) + >>= return . (applyTuple flattenTuple sum) . unzip++ signBits x = if x > 0 then 1 else 0+ linBits x linbits = if x == 15 && linbits > 0 then linbits else 0++ decodeOne 0 = return $ ((0, 0), 0)+ decodeOne tablen = + do let (table, linbits) = huffmanDecodeTable tablen+ mval <- huffmanLookupM BG.getBit table+ case mval of+ Nothing -> error "mp3DecodeHuffman"+ Just ((x, y), bitn) -> do+ let bxlin = linBits x linbits+ bylin = linBits y linbits+ bxsgn = signBits x+ bysgn = signBits y+ xlin <- getBitsFixed bxlin+ xsgn <- getBitsFixed bxsgn >>= return . signMul+ ylin <- getBitsFixed bylin+ ysgn <- getBitsFixed bysgn >>= return . signMul+ let x' = (x + xlin) * xsgn + y' = (y + ylin) * ysgn + bitn2 = bxlin + bylin + bxsgn + bysgn+ return $ ((x', y'), bitn+bitn2)++ signMul 1 = (-1)+ signMul 0 = 1++ decodeOneQuad tablen = + do let table = huffmanDecodeTableQuad tablen+ mval <- huffmanLookupM BG.getBit table+ case mval of+ Nothing -> return ((0,0,0,0),0)+ Just ((v, w, x, y), bitn) -> do+ vsgn <- getBitsFixed (signBits v) >>= return . signMul+ wsgn <- getBitsFixed (signBits w) >>= return . signMul+ xsgn <- getBitsFixed (signBits x) >>= return . signMul+ ysgn <- getBitsFixed (signBits y) >>= return . signMul+ let v' = v * vsgn + w' = w * wsgn + x' = x * xsgn + y' = y * ysgn + bitn2 = (signBits v) + (signBits w) + + (signBits x) + (signBits y)+ return $ ((v', w', x', y'), bitn+bitn2)++ decodeRegionQ tablen bitsrem accum+ | bitsrem <= 0 = if bitsrem == -1 + then do return $ accum+ -- Some old encoders give incorrect length of+ -- the quad region. Most decoders handle this,+ -- but we won't (as of 0.0.1).+ else error "Malformed MP3, aborting. See Unpack.hs"+ | otherwise = + do ((v,w,x,y), bitn) <- decodeOneQuad tablen+ r <- decodeRegionQ tablen (bitsrem - bitn) + (accum ++ [v,w,x,y])+ return $ r+++-- Get regular huffman table from index. This function is safe, since+-- mp3ParseSideInfo ensures the table index is valid.+huffmanDecodeTable :: Int -> (HuffmanTree (Int, Int), Int)+huffmanDecodeTable n = (huffmanFromList table, linbits)+ where+ (table, linbits) = tableHuffman !! n++-- Get quad huffman table from index. This function is safe, as the+-- input is only 1 bit and can only take two values.+huffmanDecodeTableQuad :: Int -> HuffmanTree (Int, Int, Int, Int)+huffmanDecodeTableQuad 0 = huffmanFromList (tableHuffmanQuad !! 0)+huffmanDecodeTableQuad 1 = huffmanFromList (tableHuffmanQuad !! 1)++-- +-- mp3ParseRawScalefactors+-- +-- More information about the scale factors can be found in Decoder.hs.+-- Here a short description is sufficient: This function takes+-- bits as input and outputs two list of integers. These integers+-- are often parsed from the bits. Sometimes they are copied from a+-- previously parsed list, if the encoder notices regions of lists+-- are identical.+--+-- We have to count the number of bits read to successfully decode+-- the Huffman data.+--+mp3ParseRawScalefactors blocktype blockflag preflag slen1 slen2 scfsi gran0+ | blocktype == 2 && blockflag == MixedBlocks =+ do scaleL0 <- replicateM 8 (getBitsFixed slen1)+ scaleS0 <- replicateM 3 (replicateM 3 (getBitsFixed slen1))+ scaleS1 <- replicateM 7 (replicateM 3 (getBitsFixed slen2))+ let bitsread = 8*slen1 + 3*3*slen1 + 7*3*slen2+ scaleS = [[0,0,0],[0,0,0],[0,0,0]]++scaleS0++scaleS1+ return $ (padWith 22 0 scaleL0, + padWith 22 [0,0,0] scaleS, bitsread)+ | blocktype == 2 =+ do scaleS0 <- replicateM 6 (replicateM 3 (getBitsFixed slen1))+ scaleS1 <- replicateM 6 (replicateM 3 (getBitsFixed slen2))+ let bitsread = 6*3*slen1 + 6*3*slen2+ return $ ([], padWith 22 [0,0,0] (scaleS0++scaleS1), bitsread)+ | otherwise =+ do band0 <- if copyband0 then return $ take 6 gran0 + else replicateM 6 (getBitsFixed slen1)+ band1 <- if copyband1 then return $ take 5 (drop 6 gran0) + else replicateM 5 (getBitsFixed slen1)+ band2 <- if copyband2 then return $ take 5 (drop 11 gran0) + else replicateM 5 (getBitsFixed slen2)+ band3 <- if copyband3 then return $ take 5 (drop 16 gran0) + else replicateM 5 (getBitsFixed slen2)+ let bitsread = 6*(if copyband0 then 0 else slen1) ++ 5*(if copyband1 then 0 else slen1) ++ 5*(if copyband2 then 0 else slen2) ++ 5*(if copyband3 then 0 else slen2)+ scalefac = band0++band1++band2++band3++[0] --Padding+ return $ (scalefac,[[]],bitsread)+ where+ + copyband0 = not (null gran0) && toBool (scfsi .&. 8)+ copyband1 = not (null gran0) && toBool (scfsi .&. 4)+ copyband2 = not (null gran0) && toBool (scfsi .&. 2)+ copyband3 = not (null gran0) && toBool (scfsi .&. 1)+++-- Above parses the scale factors to bits. This functions takes the bits+-- and converts them to doubles according to the correct floating point+-- representation. (See discussion at mp3FloatRep1 above).+--+-- Preflag is simply a predefined table that may be set to give the +-- higher scale factors a larger range than 4 bits.+mp3UnpackScaleFactors large small preflag scalefacbit =+ let large' = if preflag == 0 then large+ else zipWith (+) large tablePretab+ large'' = map floatFunc large'+ small' = map (map floatFunc) small+ in (large'', small')+ where+ floatFunc = mp3FloatRep3 scalefacbit++-- Two different floating point representations can be used for the scale+-- factors. (See discussion at mp3FloatRep1).+mp3FloatRep3 :: Int -> Int -> Double+mp3FloatRep3 0 n = 2.0 ** ((-0.5) * (fromIntegral n))+mp3FloatRep3 1 n = 2.0 ** ((-1) * (fromIntegral n))+++-- +-- mp3ParseMainData+--+-- For stereo, the main data is grouped as follows:+--+-- scale, granule 0 channel 0+-- huffman, granule 0 channel 0+-- scale, granule 0 channel 1+-- huffman, granule 0 channel 1+-- scale, granule 1 channel 0+-- huffman, granule 1 channel 0+-- scale, granule 1 channel 1+-- huffman, granule 1 channel 1+--+-- For mono, the main data is grouped as follows.+--+-- scale, granule 0 channel 0+-- huffman, granule 0 channel 0+-- scale, granule 1 channel 0+-- huffman, granule 1 channel 0+--+-- scale is parsed by mp3ParseRawScaleFactors+-- huffman is parsed by mp3DecodeHuffman+--+-- Return values:+--+-- If the logical frame is too short or invalid, the function returns Nothing.+-- Otherwise it returns Just MP3Data.+--++mp3ParseMainData :: MP3LogicalFrame -> Maybe MP3Data+mp3ParseMainData (MP3LogicalFrame header side maindata) = parse+ where+ parse = + case BG.runBitGet (B.pack maindata)+ (if mono then doAllMono else doAllStereo) of+ Right ret -> Just ret+ Left err -> Nothing++ mono = Mono == headChannels header+ scfsi = sideScfsi side+ scfsi0 = scfsi `shiftR` 4+ scfsi1 = scfsi .&. 0xf++ doOne (MP3SideData huffdata scaledata part23 bt bf) scfsi gran0 =+ do let (slen1, slen2) = scaleLengths scaledata+ pre = scalePreflag scaledata+ scalefacbit = scaleScalefacScale scaledata++ (scaleL, scaleS, bitsread) <- + mp3ParseRawScalefactors bt bf pre slen1 slen2 scfsi gran0++ let (scaleFacLarge, scaleFacSmall) =+ mp3UnpackScaleFactors scaleL scaleS pre scalefacbit+ -- Parameters to the IS Stereo decoder are saved in the + -- higher unused scale factors.+ (isLarge, isSmall) = (scaleL, scaleS)++ maindata <- mp3DecodeHuffman huffdata (part23-bitsread)++ return $ (scaleL,MP3DataChunk bt bf + (scaleGlobalGain scaledata)+ (scaleSubblockGain scaledata)+ scaleFacLarge+ scaleFacSmall+ (isLarge, isSmall)+ maindata)++ doAllMono = do (s0s, s0m) <- doOne (sideGranule0ch0 side) scfsi []+ (s1s, s1m) <- doOne (sideGranule1ch0 side) scfsi s0s+ return $ MP3Data1Channels (headSampleRate header)+ (headChannels header)+ ((headStereoMS header, + headStereoIS header))+ s0m s1m++ doAllStereo = + do (s00s, s00m) <- doOne (sideGranule0ch0 side) scfsi0 []+ (s01s, s01m) <- doOne (sideGranule0ch1 side) scfsi1 []+ (s10s, s10m) <- doOne (sideGranule1ch0 side) scfsi0 s00s+ (s11s, s11m) <- doOne (sideGranule1ch1 side) scfsi1 s01s+ return $ MP3Data2Channels (headSampleRate header)+ (headChannels header)+ ((headStereoMS header, + headStereoIS header))+ s00m s01m s10m s11m++--+-- mp3Seek+--+-- Throw away bytes in the bitstream until the first byte is a frame +-- header. This should be used to initialize the decoder before+-- calling mp3Unpack, and to reset the decoder whenever mp3Unpack+-- has found a broken frame.+--+-- Return value:+--+-- If the the bitstream is empty, or not an MP3, or really broken,+-- the function returns Nothing+-- If the bitstream is healthy, it returns a new bitstream that can+-- be used by mp3Unpack.+-- +mp3Seek :: MP3Bitstream -> Maybe MP3Bitstream+mp3Seek (MP3Bitstream bs _) = helper bs 8192+ where+ helper bs 0 = Nothing -- Nothing interesting in 8 KB = broken.+ helper bs read = + case (mp3ParseFrameHeader . bsGetWord32) bs of+ Just header -> Just $ MP3Bitstream bs []+ otherwise -> helper (B.drop 1 bs) (read - 1)++--+-- mp3UnpackFrame+--+-- Read a physical frame, and maybe return a logical frame.+--+-- A logical frame consists of a header, side data, and main data, where+-- the main data contains the scale factors and huffman data for the granules+-- as explained in mp3ParseMainData.+--+-- A physical frame looks like this: [H][C][S][data]+-- Where H is the 4 byte header, C is an optional 2 byte CRC+-- we ignore, S is the 17 (mono) or 32 (stereo) side informataion,+-- and data is a kind of buffer, that may or may not contain parts+-- of the main data we need to construct a logical frame.+--+-- In "data" in the current frame, and possibly preceding frames, are+-- the main data bits that correspond to the header/sideinfo, containing+-- the scale factors and huffman coded audio. It may look like this, +--+-- [...][data1][data2][data3][hcs1][data3][hcs2][data3][data4][hcs3][...]+-- Where hcs1 is [H1][C1][S1].+--+-- In this example, these are physical frames:+--+-- [hcs1][data3]+-- [hcs2][data3][data4]+-- [hcs3][...] (until hcs4, not shown)+--+-- And these are the logical frames:+--+-- [hcs1][data1]+-- [hcs2][data2]+-- [hcs3][data3][data3][data3]+--+-- In the side information for a physical frame is a value known as the+-- dataptr (in the MP3 specification, this is known under a different name+-- but this name is very confusing so It's not mentioned here). +-- If we are currently reading physical frame n, then the dataptr in physical+-- frame n+1 tells us when we have enough main data.+--+-- In the MP3Bitstream we maintain state what we've read so far. When we're+-- at the physical frame [hcs1][data3], the buffer contains+-- [data1][data2][data3]+-- We peek at the side data in [hcs2] to find out where data1 ends, +-- copies it to the logical frame, and deletes data1 from the buffer.+-- Note that the dataptr value in [hcs2] is a negative offset from the end+-- of the buffer, not the length of data1 itself.+--+mp3UnpackFrame :: MP3Bitstream -> (MP3Bitstream, Maybe MP3LogicalFrame)+mp3UnpackFrame (MP3Bitstream bs buffer) = + case (mp3ParseFrameHeader . bsGetWord32) bs of+ Just header -> unpack1 header+ otherwise -> error "Unsupported or broken header."+ where+ unpack1 header = + case runGet byteGetter bs of+ (Right (side, buffer', dataptr), remaining) -> + unpack2 header side buffer' dataptr remaining+ (otherwise, remaining) -> + (MP3Bitstream remaining [], Nothing)+ where+ byteGetter = do + let lengthcrc = if headCRC header then 2 else 0+ lengthside = if Mono == headChannels header then 17 else 32+ lengthframe = mp3FrameLength header+ head_ <- getByteString 4+ crc_ <- getByteString lengthcrc+ side <- getByteString lengthside+ main <- getByteString (lengthframe - 4 - lengthcrc - lengthside)+ peek <- lookAhead $ getByteString 8+ let buffer' = buffer ++ B.unpack main+ lbuffer' = length buffer'+ return $ (mp3ParseSideInfo header (B.unpack side), + buffer', + mp3PeekDataPtr peek)++ unpack2 header (Just sidedata) newbuf (Just dataptr) bs' =+ let lnewbuf = length newbuf+ (logicalbuf, buf') = splitAt (lnewbuf - dataptr) newbuf+ -- If the state buffer is empty, the current logical frame is+ -- broken (main data that should precede the frame is missing.)+ logical = if buffer == []+ then Nothing+ else Just $ MP3LogicalFrame header sidedata logicalbuf+ in (MP3Bitstream bs' buf', logical)+ unpack2 _ _ _ _ rem = (MP3Bitstream rem [], Nothing)++-- +-- mp3Unpack+--+-- A helper function that takes a bitstream, unpacks it into a logical+-- frame, then parses the main data to return an MP3Data, used by the+-- decoder.+--+mp3Unpack :: MP3Bitstream -> (MP3Bitstream, Maybe MP3Data)+mp3Unpack bitstream = helper (mp3UnpackFrame bitstream)+ where+ helper (bitstream', Nothing) = (bitstream', Nothing)+ helper (bitstream', Just logical) =+ case mp3ParseMainData logical of+ Just mdata -> (bitstream', Just mdata)+ otherwise -> (bitstream', Nothing)+
+ Codec/Audio/MP3/c_imdct.c view
@@ -0,0 +1,77 @@+/*+ * imdct.c - naive IDMCT implementation. This can be made O(n log n),+ * but as is the rest of the decoder is too slow for this to matter+ * we ignore it.+ *+ * This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+ * Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+ *+ * This software is provided 'as-is', without any express or implied+ * warranty. In no event will the authors be held liable for any damages+ * arising from the use of this software.+ *+ * Permission is granted to anyone to use this software for any purpose,+ * including commercial applications, and to alter it and redistribute it+ * freely, subject to the following restrictions:+ *+ * 1. The origin of this software must not be misrepresented; you must not+ * claim that you wrote the original software. If you use this software+ * in a product, an acknowledgment in the product documentation would be+ * appreciated but is not required.+ *+ * 2. Altered source versions must be plainly marked as such, and must not be+ * misrepresented as being the original software.+ *+ * 3. This notice may not be removed or altered from any source+ * distribution.+ */++#include <math.h>++#define PI 3.1415926535897931++void imdct18(double *in, double *out)+{+ int k, n;+ double sum;+ static double lookup[36][18];+ static int lookup_init = 0;++ if (lookup_init == 0) {+ + for (n = 0; n < 36; n++)+ for (k = 0; k < 18; k++)+ lookup[n][k] = cos((PI/18) * (n + 0.5 + 18/2.0) * (k + 0.5));++ lookup_init = 1;+ }++ for (n = 0; n < 36; n++) {+ sum = 0.0;+ for (k = 0; k < 18; k+=3) {+ sum += in[k+0] * lookup[n][k+0];+ sum += in[k+1] * lookup[n][k+1];+ sum += in[k+2] * lookup[n][k+2];+ }+ out[n] = sum;+ }+}++void imdct(int points, double *in, double *out)+{+ int k, n;+ double sum;++ if (points == 18) {+ imdct18(in, out);+ return;+ }++ for (n = 0; n < points*2; n++) {+ sum = 0.0;+ for (k = 0; k < points; k++) + sum += in[k] * cos((PI/points) * (n + 0.5 + points/2.0) * (k + 0.5));+ out[n] = sum;+ }+}+
+ Codec/Audio/MP3/c_imdct.h view
@@ -0,0 +1,15 @@+#ifndef IMDCT_H+#define IMDCT_H 1++#ifdef __cplusplus+extern "C" {+#endif++void imdct(int points, double *in, double *out);++#ifdef __cplusplus+}+#endif++#endif+
+ Codec/Audio/MP3/c_synth.c view
@@ -0,0 +1,198 @@+/*+ * synth.c - The MPEG1 filter bank, algorithm straight from the + * specification.+ *+ * This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+ * Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+ *+ */++#include <math.h>++#define PI 3.1415926535897931++static double synth_window[512] = { + 0.000000000, -0.000015259, -0.000015259, -0.000015259, + -0.000015259, -0.000015259, -0.000015259, -0.000030518, + -0.000030518, -0.000030518, -0.000030518, -0.000045776, + -0.000045776, -0.000061035, -0.000061035, -0.000076294, + -0.000076294, -0.000091553, -0.000106812, -0.000106812, + -0.000122070, -0.000137329, -0.000152588, -0.000167847, + -0.000198364, -0.000213623, -0.000244141, -0.000259399, + -0.000289917, -0.000320435, -0.000366211, -0.000396729, + -0.000442505, -0.000473022, -0.000534058, -0.000579834, + -0.000625610, -0.000686646, -0.000747681, -0.000808716, + -0.000885010, -0.000961304, -0.001037598, -0.001113892, + -0.001205444, -0.001296997, -0.001388550, -0.001480103, + -0.001586914, -0.001693726, -0.001785278, -0.001907349, + -0.002014160, -0.002120972, -0.002243042, -0.002349854, + -0.002456665, -0.002578735, -0.002685547, -0.002792358, + -0.002899170, -0.002990723, -0.003082275, -0.003173828, + 0.003250122, 0.003326416, 0.003387451, 0.003433228, + 0.003463745, 0.003479004, 0.003479004, 0.003463745, + 0.003417969, 0.003372192, 0.003280640, 0.003173828, + 0.003051758, 0.002883911, 0.002700806, 0.002487183, + 0.002227783, 0.001937866, 0.001617432, 0.001266479, + 0.000869751, 0.000442505, -0.000030518, -0.000549316, + -0.001098633, -0.001693726, -0.002334595, -0.003005981, + -0.003723145, -0.004486084, -0.005294800, -0.006118774, + -0.007003784, -0.007919312, -0.008865356, -0.009841919, + -0.010848999, -0.011886597, -0.012939453, -0.014022827, + -0.015121460, -0.016235352, -0.017349243, -0.018463135, + -0.019577026, -0.020690918, -0.021789551, -0.022857666, + -0.023910522, -0.024932861, -0.025909424, -0.026840210, + -0.027725220, -0.028533936, -0.029281616, -0.029937744, + -0.030532837, -0.031005859, -0.031387329, -0.031661987, + -0.031814575, -0.031845093, -0.031738281, -0.031478882, + 0.031082153, 0.030517578, 0.029785156, 0.028884888, + 0.027801514, 0.026535034, 0.025085449, 0.023422241, + 0.021575928, 0.019531250, 0.017257690, 0.014801025, + 0.012115479, 0.009231567, 0.006134033, 0.002822876, + -0.000686646, -0.004394531, -0.008316040, -0.012420654, + -0.016708374, -0.021179199, -0.025817871, -0.030609131, + -0.035552979, -0.040634155, -0.045837402, -0.051132202, + -0.056533813, -0.061996460, -0.067520142, -0.073059082, + -0.078628540, -0.084182739, -0.089706421, -0.095169067, + -0.100540161, -0.105819702, -0.110946655, -0.115921021, + -0.120697021, -0.125259399, -0.129562378, -0.133590698, + -0.137298584, -0.140670776, -0.143676758, -0.146255493, + -0.148422241, -0.150115967, -0.151306152, -0.151962280, + -0.152069092, -0.151596069, -0.150497437, -0.148773193, + -0.146362305, -0.143264771, -0.139450073, -0.134887695, + -0.129577637, -0.123474121, -0.116577148, -0.108856201, + 0.100311279, 0.090927124, 0.080688477, 0.069595337, + 0.057617188, 0.044784546, 0.031082153, 0.016510010, + 0.001068115, -0.015228271, -0.032379150, -0.050354004, + -0.069168091, -0.088775635, -0.109161377, -0.130310059, + -0.152206421, -0.174789429, -0.198059082, -0.221984863, + -0.246505737, -0.271591187, -0.297210693, -0.323318481, + -0.349868774, -0.376800537, -0.404083252, -0.431655884, + -0.459472656, -0.487472534, -0.515609741, -0.543823242, + -0.572036743, -0.600219727, -0.628295898, -0.656219482, + -0.683914185, -0.711318970, -0.738372803, -0.765029907, + -0.791213989, -0.816864014, -0.841949463, -0.866363525, + -0.890090942, -0.913055420, -0.935195923, -0.956481934, + -0.976852417, -0.996246338, -1.014617920, -1.031936646, + -1.048156738, -1.063217163, -1.077117920, -1.089782715, + -1.101211548, -1.111373901, -1.120223999, -1.127746582, + -1.133926392, -1.138763428, -1.142211914, -1.144287109, + 1.144989014, 1.144287109, 1.142211914, 1.138763428, + 1.133926392, 1.127746582, 1.120223999, 1.111373901, + 1.101211548, 1.089782715, 1.077117920, 1.063217163, + 1.048156738, 1.031936646, 1.014617920, 0.996246338, + 0.976852417, 0.956481934, 0.935195923, 0.913055420, + 0.890090942, 0.866363525, 0.841949463, 0.816864014, + 0.791213989, 0.765029907, 0.738372803, 0.711318970, + 0.683914185, 0.656219482, 0.628295898, 0.600219727, + 0.572036743, 0.543823242, 0.515609741, 0.487472534, + 0.459472656, 0.431655884, 0.404083252, 0.376800537, + 0.349868774, 0.323318481, 0.297210693, 0.271591187, + 0.246505737, 0.221984863, 0.198059082, 0.174789429, + 0.152206421, 0.130310059, 0.109161377, 0.088775635, + 0.069168091, 0.050354004, 0.032379150, 0.015228271, + -0.001068115, -0.016510010, -0.031082153, -0.044784546, + -0.057617188, -0.069595337, -0.080688477, -0.090927124, + 0.100311279, 0.108856201, 0.116577148, 0.123474121, + 0.129577637, 0.134887695, 0.139450073, 0.143264771, + 0.146362305, 0.148773193, 0.150497437, 0.151596069, + 0.152069092, 0.151962280, 0.151306152, 0.150115967, + 0.148422241, 0.146255493, 0.143676758, 0.140670776, + 0.137298584, 0.133590698, 0.129562378, 0.125259399, + 0.120697021, 0.115921021, 0.110946655, 0.105819702, + 0.100540161, 0.095169067, 0.089706421, 0.084182739, + 0.078628540, 0.073059082, 0.067520142, 0.061996460, + 0.056533813, 0.051132202, 0.045837402, 0.040634155, + 0.035552979, 0.030609131, 0.025817871, 0.021179199, + 0.016708374, 0.012420654, 0.008316040, 0.004394531, + 0.000686646, -0.002822876, -0.006134033, -0.009231567, + -0.012115479, -0.014801025, -0.017257690, -0.019531250, + -0.021575928, -0.023422241, -0.025085449, -0.026535034, + -0.027801514, -0.028884888, -0.029785156, -0.030517578, + 0.031082153, 0.031478882, 0.031738281, 0.031845093, + 0.031814575, 0.031661987, 0.031387329, 0.031005859, + 0.030532837, 0.029937744, 0.029281616, 0.028533936, + 0.027725220, 0.026840210, 0.025909424, 0.024932861, + 0.023910522, 0.022857666, 0.021789551, 0.020690918, + 0.019577026, 0.018463135, 0.017349243, 0.016235352, + 0.015121460, 0.014022827, 0.012939453, 0.011886597, + 0.010848999, 0.009841919, 0.008865356, 0.007919312, + 0.007003784, 0.006118774, 0.005294800, 0.004486084, + 0.003723145, 0.003005981, 0.002334595, 0.001693726, + 0.001098633, 0.000549316, 0.000030518, -0.000442505, + -0.000869751, -0.001266479, -0.001617432, -0.001937866, + -0.002227783, -0.002487183, -0.002700806, -0.002883911, + -0.003051758, -0.003173828, -0.003280640, -0.003372192, + -0.003417969, -0.003463745, -0.003479004, -0.003479004, + -0.003463745, -0.003433228, -0.003387451, -0.003326416, + 0.003250122, 0.003173828, 0.003082275, 0.002990723, + 0.002899170, 0.002792358, 0.002685547, 0.002578735, + 0.002456665, 0.002349854, 0.002243042, 0.002120972, + 0.002014160, 0.001907349, 0.001785278, 0.001693726, + 0.001586914, 0.001480103, 0.001388550, 0.001296997, + 0.001205444, 0.001113892, 0.001037598, 0.000961304, + 0.000885010, 0.000808716, 0.000747681, 0.000686646, + 0.000625610, 0.000579834, 0.000534058, 0.000473022, + 0.000442505, 0.000396729, 0.000366211, 0.000320435, + 0.000289917, 0.000259399, 0.000244141, 0.000213623, + 0.000198364, 0.000167847, 0.000152588, 0.000137329, + 0.000122070, 0.000106812, 0.000106812, 0.000091553, + 0.000076294, 0.000076294, 0.000061035, 0.000061035, + 0.000045776, 0.000045776, 0.000030518, 0.000030518, + 0.000030518, 0.000030518, 0.000015259, 0.000015259, + 0.000015259, 0.000015259, 0.000015259, 0.000015259, +};++void synth(double state[1024], double samples[576],+ double newstate[1024], double output[576])+{+ int s, i, j;+ double S[32], U[512], sum;+ static double lookup[64][32];+ static int lookup_init = 0;++ if (lookup_init == 0) {+ for (i = 0; i < 64; i++)+ for (j = 0; j < 32; j++)+ lookup[i][j] = cos((16.0 + i) * (2.0*j + 1) * (PI/64.0));+ lookup_init = 1;+ }++ for (i = 0; i < 1024; i++)+ newstate[i] = state[i];++ for (s = 0; s < 18; s++) {+ for (i = 0; i < 32; i++)+ S[i] = samples[i*18 + s];++ /* V.. */+ for (i = 1023; i > 63; i--)+ newstate[i] = newstate[i - 64];++ for (i = 0; i < 64; i++) {+ sum = 0.0;+ for (j = 0; j < 32; j++)+ sum += S[j] * lookup[i][j];+ newstate[i] = sum;+ }++ for (i = 0; i < 8; i++) {+ for (j = 0; j < 32; j++) {+ U[i*64 + j] = newstate[i*128 + j];+ U[i*64 + j + 32] = newstate[i*128 + j + 96];+ }+ }++ for (i = 0; i < 512; i++)+ U[i] *= synth_window[i];++ for (i = 0; i < 32; i++) {+ sum = 0.0;+ for (j = 0; j < 16; j++)+ sum += U[j*32 + i];+ output[32*s + i] = sum;+ }+ }++ return;+}+
+ Codec/Audio/MP3/c_synth.h view
@@ -0,0 +1,17 @@++#ifndef MP3SYNTH_H+#define MP3SYNTH_H 1++#ifdef __cplusplus+extern "C" {+#endif++void synth(double state[1024], double samples[576],+ double newstate[1024], double output[576]);++#ifdef __cplusplus+}+#endif++#endif+
+ LICENSE view
@@ -0,0 +1,22 @@++Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>++This software is provided 'as-is', without any express or implied+warranty. In no event will the authors be held liable for any damages+arising from the use of this software.++Permission is granted to anyone to use this software for any purpose,+including commercial applications, and to alter it and redistribute it+freely, subject to the following restrictions:++ 1. The origin of this software must not be misrepresented; you must not+ claim that you wrote the original software. If you use this software+ in a product, an acknowledgment in the product documentation would be+ appreciated but is not required.++ 2. Altered source versions must be plainly marked as such, and must not be+ misrepresented as being the original software.++ 3. This notice may not be removed or altered from any source+ distribution.+
+ README view
@@ -0,0 +1,59 @@++=== Prereq. ===++Using this code requires:++*) A Haskell compiler, such as GHC.++*) binary-strict, from here: + http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary-strict+ If you've never used Haskell before, install binary-strict by + downloading and unpacking the source, cd to the directory where the+ Setup file is, and do++ $ runhaskell Setup.lhs configure+ $ runhaskell Setup.lhs build+ $ runhaskell Setup.lhs install++That's it.++++=== Building the decoder ===++Building the decoder works almost the same as building binary-strict. +From the directory where this file is, do:++$ runhaskell Setup.lhs configure+$ runhaskell Setup.lhs build++Do not install it (if you're familiar with Haskell and for some reason+want to install this decoder as a library, you'll have to edit the +cabal file).++When done, there will be an executable file in dist/build/mp3driver.+Pass an MP3 file to it++$ mp3driver test.mp3++And it will write a file, "out.wav", to the current directory.++The actual decoder is in Codec/Audio/MP3. Change parts of it, run+the build command again, and see what happens. :-)++++=== Trouble? ===++If, for some reason, the above doesn't work, there's a manual method+of building the mp3driver program. Copy all *.hs, *.h and *.c files+to the same directory. Build the two C files:++$ gcc -O2 -c c_imdct.c+$ gcc -O2 -c c_synth.c++Change all "import Codec.Audio.MP3.XXX" in the Haskell source files+to "import XXX". Then:++$ ghc c_imdct.o c_synth.o --make Driver.hs+
+ Setup.lhs view
@@ -0,0 +1,4 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain+
+ example/Driver.hs view
@@ -0,0 +1,50 @@+-- +-- Example program using the decoder.+--+module Main where++import qualified Data.ByteString as B+import System.IO+import System++import qualified PCMWriter++import Codec.Audio.MP3.Decoder+import Codec.Audio.MP3.Types+++mainLoopX :: B.ByteString -> Handle -> IO ()+mainLoopX contents outf = do loopInit (MP3Bitstream contents []) + emptyMP3DecodeState+ where+ loopInit bitstream decstate = helper (mp3Seek bitstream)+ where+ helper Nothing = error "Not an MP3."+ helper (Just bitstream') = doUnpack bitstream' decstate 0++ doUnpack bitstream decstate cnt = helper (mp3Unpack bitstream)+ where+ helper (bitstream', Nothing) = + do putStrLn $ "Skipped broken frame " ++ (show cnt)+ doUnpack bitstream' emptyMP3DecodeState (cnt+1)++ helper (bitstream', Just mp3data) = + do let (decstate', ch0, ch1) = mp3Decode decstate mp3data+ sr = mp3dataSampleRate mp3data+ + putStrLn $ "Decoded frame " ++ (show cnt) ++ ": " ++ prettyData mp3data+ + -- To the reader, that is, you: For fun, change mp3HybridFilterBank+ -- so it doesn't do the synthesis step, and only returns the 18+ -- first samples. Then change the sr to sr/32.+ PCMWriter.writeSamplerate outf sr -- (sr `div` 32)+ PCMWriter.writeSamples outf ch0 ch1+ doUnpack bitstream' decstate' (cnt+1)+ +main :: IO ()+main = do args <- getArgs+ contents <- B.readFile (head args)+ outh <- openBinaryFile "out.wav" WriteMode+ PCMWriter.writeHeader outh+ mainLoopX contents outh+
+ example/PCMWriter.hs view
@@ -0,0 +1,127 @@+-- +-- module PCMWriter - For writing PCM WAV files.+-- This is a small simple (and very SLOW) library for demonstrating+-- the decoder. For more powerful manipulations of PCM+-- WAV, see HSoundFile at Hackage.+--+-- This code is part of the Experimental Haskell MP3 Decoder, version 0.0.1.+-- Copyright (c) 2008 Bjorn Edstrom <be@bjrn.se>+--+-- This software is provided 'as-is', without any express or implied+-- warranty. In no event will the authors be held liable for any damages+-- arising from the use of this software.+--+-- Permission is granted to anyone to use this software for any purpose,+-- including commercial applications, and to alter it and redistribute it+-- freely, subject to the following restrictions:+--+-- 1. The origin of this software must not be misrepresented; you must not+-- claim that you wrote the original software. If you use this software+-- in a product, an acknowledgment in the product documentation would be+-- appreciated but is not required.+--+-- 2. Altered source versions must be plainly marked as such, and must not be+-- misrepresented as being the original software.+--+-- 3. This notice may not be removed or altered from any source+-- distribution.+--++module PCMWriter (+ writeHeader+ ,writeSamplerate+ ,writeSamples+) where++import Data.Word+import Data.Bits+import System.IO+import Char+import Control.Monad+import Control.Monad.State++type PCMSample = Word16++fracToPCM :: RealFrac a => a -> PCMSample+fracToPCM x+ | y <= (-32767) = fromIntegral (-32767)+ | y >= 32767 = fromIntegral 32767+ | otherwise = fromIntegral y+ where+ y = round (x * 32767.0)++class AudioSampleRepr a where+ toPcmRepr :: a -> PCMSample++instance AudioSampleRepr Double where+ toPcmRepr = fracToPCM++instance AudioSampleRepr Float where+ toPcmRepr = fracToPCM++-- Add other instances here.++from16bit n = [chr . fromIntegral $ n .&. 0xff, + chr . fromIntegral $ n `shiftR` 8]+from32bit n = [chr . fromIntegral $ n .&. 0xff,+ chr . fromIntegral $ (n `shiftR` 8) .&. 0xff,+ chr . fromIntegral $ (n `shiftR` 16) .&. 0xff,+ chr . fromIntegral $ (n `shiftR` 24) .&. 0xff]++hWrite16 :: Handle -> Word16 -> IO ()+hWrite16 handle n = do hPutStr handle (from16bit n)++hWrite32 :: Handle -> Word32 -> IO ()+hWrite32 handle n = do hPutStr handle (from32bit n)++writeSamplerate :: Handle -> Int -> IO ()+writeSamplerate handle sr = + do cur <- hTell handle+ hSeek handle AbsoluteSeek 24+ hWrite32 handle (fromIntegral sr)+ hWrite32 handle (fromIntegral sr * 2 * 2)+ hSeek handle AbsoluteSeek cur++writeNumSamples :: Handle -> Int -> IO ()+writeNumSamples handle num =+ do cur <- hTell handle+ let count1 = (num * 2 * 2) + count2 = 36 + count1+ hSeek handle AbsoluteSeek 4+ hWrite32 handle (fromIntegral count2)+ hSeek handle AbsoluteSeek 40+ hWrite32 handle (fromIntegral count1)+ hSeek handle AbsoluteSeek cur++writeHeader :: Handle -> IO ()+writeHeader handle = + do write "RIFF"+ write "\xff\xff\xff\xff"+ write "WAVEfmt "+ write32 16+ write16 1+ write16 2 -- Num. channels+ write32 44100 -- Sample rate+ write32 (44100 * 2 * 2) -- Derived from sample rate.+ write16 4+ write16 16+ write "data"+ write "\xff\xff\xff\xff" -- num samples+ where+ write = do hPutStr handle+ write16 = do hWrite16 handle+ write32 = do hWrite32 handle++writeSamples :: AudioSampleRepr a => Handle -> [a] -> [a] -> IO ()+writeSamples handle ch0 ch1 =+ do zipWithM_ writeInterleaved ch0 ch1+ cur <- hTell handle+ let totalsamples = fromIntegral $ (cur - 44) `div` (2*2)+ writeNumSamples handle totalsamples+ --hFlush handle+ where+ writeInterleaved ch0sample ch1sample = + do hWrite16 handle (toPcmRepr ch0sample)+ hWrite16 handle (toPcmRepr ch1sample)++
+ mp3decoder.cabal view
@@ -0,0 +1,63 @@+Name: mp3decoder+Version: 0.0.1+Synopsis: MP3 decoder for teaching.+Description:+ This is an MP3 decoder written (almost) completely in Haskell. + The current version is experimental software, written for + teaching purposes, and is currently too slow to be usable in + practice. For the accompanying article, se www.bjrn.se/mp3dec++Copyright: Bjorn Edstrom, 2008+Author: Bjorn Edstrom+Maintainer: be@bjrn.se+Homepage: http://www.bjrn.se/mp3dec+License: OtherLicense+License-file: LICENSE++Category: Codec+Stability: experimental+Build-type: Simple+Cabal-version: >= 1.2++Extra-source-files: README,+ Codec/Audio/MP3/c_synth.h,+ Codec/Audio/MP3/c_imdct.h++-- Comment out for library.++--Library+-- Build-depends: base, bytestring, mtl, binary-strict+-- Exposed-modules: Codec.Audio.MP3.Decoder+-- Other-modules: Codec.Audio.MP3.Types,+-- Codec.Audio.MP3.Huffman,+-- Codec.Audio.MP3.SynthesisFilterBank,+-- Codec.Audio.MP3.Tables,+-- Codec.Audio.MP3.Unpack,+-- Codec.Audio.MP3.IMDCT,+-- Codec.Audio.MP3.HybridFilterBank+-- +-- hs-source-dirs: .+-- c-sources: Codec/Audio/MP3/c_synth.c,+-- Codec/Audio/MP3/c_imdct.c+-- cc-options: -O2+-- ghc-options: -O2++Executable mp3driver+ build-depends: base, bytestring, mtl, binary-strict, haskell98+ Main-Is: Driver.hs+ hs-source-dirs: example, .+ Other-Modules: Codec.Audio.MP3.Decoder+ Codec.Audio.MP3.Types,+ Codec.Audio.MP3.Huffman,+ Codec.Audio.MP3.SynthesisFilterBank,+ Codec.Audio.MP3.Tables,+ Codec.Audio.MP3.Unpack,+ Codec.Audio.MP3.IMDCT,+ Codec.Audio.MP3.HybridFilterBank+ PCMWriter+ c-sources: Codec/Audio/MP3/c_synth.c,+ Codec/Audio/MP3/c_imdct.c+ cc-options: -O2+ ghc-options: -O2++