import System(getArgs) import System.CPUTime import Control.Monad import Data.Char import Data.Array.IO import Data.Array.Base import Data.Bits import Data.Word import System import System.CPUTime import System.IO import System.IO.Unsafe import Text.Printf iter :: Int iter = 10000 main = do f <- getArgs >>= return . head (arr,l) <- slurp f t0 <- getCPUTime res <- replicateM iter (decode_all arr) >>= return . head t1 <- getCPUTime printf "%.3f" $ (fromInteger (t1 - t0) :: Float) / (fromInteger 10 ^ 12 :: Float) writeFile (f++".haskell") (show res) ------------------------------------------------------------------------------------- decode_all arr = --1 decode_packets arr (unsafePerformIO (get_16_bit_int arr 0)) 2 [] --2 decode_packets :: Buffer -> Int -> Int -> [[Int]] -> IO Int decode_packets arr 0 _ acc = return (sum (map sum (reverse acc))) --3 decode_packets arr n index acc --4 | arr `seq` n `seq` index `seq` acc `seq` False = undefined --5 | otherwise = do --6 nof_channels <- get_5_bit_int arr index --7 nextp <- decode_packet arr ((index*8)+5) nof_channels [] --8 decode_packets arr (n-1) (index+(tot_bytes nof_channels)) (nextp:acc) --9 decode_packet :: Buffer -> Int -> Int -> [Int] -> IO [Int] decode_packet arr bitindex 0 acc = return (reverse acc) --10 decode_packet arr bitindex n acc --11 | arr `seq` n `seq` bitindex `seq` acc `seq` False = undefined --12 | otherwise = do --13 nextc <- get_11_bit_int arr bitindex --14 decode_packet arr (bitindex+11) (n-1) (nextc:acc) --15 tot_bytes::Int -> Int tot_bytes nof_channels = --16 let tot_bits = (nof_channels*11+5) --17 bytes = (shiftR tot_bits 3) --18 in if (tot_bits .&. 7) > 0 --19 then (bytes+1) --20 else bytes --21 get_11_bit_int :: Buffer -> Int -> IO Int get_11_bit_int arr bitindex = do --22 b0 <- arr `unsafeRead` sindex >>= return . fromIntegral --23 b1 <- arr `unsafeRead` (sindex+1) >>= return . fromIntegral --24 b2 <- arr `unsafeRead` (sindex+2) >>= return . fromIntegral --25 return $! ((shift b0 (11-ioffset)) .|. --26 (shift b1 (3-ioffset)) .|. --27 (shift b2 (-5-ioffset))) .&. ((shift 1 11)-1) --28 where sindex = (shiftR bitindex 3) --30 ioffset = (8-(bitindex .&. 7)) --31 get_5_bit_int :: Buffer -> Int -> IO Int get_5_bit_int arr index = do --32 b0 <- arr `unsafeRead` index >>= return . fromIntegral --33 return ((shift b0 3) .&. 31) --34 get_16_bit_int :: Buffer -> Int -> IO Int get_16_bit_int arr index = do --35 b0 <- arr `unsafeRead` index >>= return . fromIntegral --36 b1 <- arr `unsafeRead` index >>= return . fromIntegral --37 return ((shift b0 8) .|. b1) --38 ------------------------------------------------------------------------ type Buffer = IOUArray Int Word8 slurp :: FilePath -> IO (Buffer, Int) slurp f = do h <- openBinaryFile f ReadMode l <- hFileSize h arr <- newArray_ (0,fromIntegral l-1) :: IO Buffer hGetArray h arr (fromIntegral l) hClose h return (arr,fromIntegral l)