packages feed

bindings-codec2 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+87/−2 lines, 3 filesdep +binarydep +bindings-codec2dep +bytestringnew-component:exe:bindings-codec2-demo

Dependencies added: binary, bindings-codec2, bytestring, split

Files

bindings-codec2.cabal view
@@ -1,5 +1,5 @@ name:                bindings-codec2-version:             0.1.0.0+version:             0.1.1.0 synopsis:            Very low-level FFI bindings for Codec2 description:         Bindings for Codec2 generated by jwiegley's c2hsc/bindings-dsl homepage:            https://github.com/relrod/Codec2-hs@@ -18,7 +18,7 @@   branch: master  library-  exposed-modules:     +  exposed-modules:     Bindings.Codec2   default-extensions:  ForeignFunctionInterface   build-depends:       base >= 4 && < 5@@ -27,3 +27,15 @@   hs-source-dirs: src   default-language: Haskell2010   cc-options: -fPIC++executable bindings-codec2-demo+  main-is:             Demo.hs+  hs-source-dirs:      src+  build-depends:       base >= 4 && < 5+                     , binary+                     , bindings-codec2+                     , bytestring+                     , split >= 0.2 && < 0.3++  default-language:    Haskell2010+  ghc-options:         -Wall -O2
src/Bindings/Codec2.hsc view
@@ -16,3 +16,10 @@ #ccall codec2_set_lpc_post_filter , Ptr <struct CODEC2> -> CInt -> CInt -> CFloat -> CFloat -> IO () #ccall codec2_get_spare_bit_index , Ptr <struct CODEC2> -> IO CInt #ccall codec2_rebuild_spare_bit , Ptr <struct CODEC2> -> Ptr CInt -> IO CInt++#num CODEC2_MODE_3200+#num CODEC2_MODE_2400+#num CODEC2_MODE_1600+#num CODEC2_MODE_1400+#num CODEC2_MODE_1300+#num CODEC2_MODE_1200
+ src/Demo.hs view
@@ -0,0 +1,66 @@+module Main where++import Data.Binary+import Data.Binary.Get+import Data.Binary.Put+import qualified Data.ByteString.Lazy.Char8 as L+import Data.List.Split (chunksOf)+import Foreign.C.Types+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array+import Foreign.Ptr+import Foreign.Storable+import Bindings.Codec2+import System.Environment++main :: IO ()+main = do+  (fin:fout:_) <- getArgs+  let mode = c'CODEC2_MODE_3200+  codec2 <- c'codec2_create mode+  nsam <- c'codec2_samples_per_frame codec2+  nbit <- c'codec2_bits_per_frame codec2+  buf <- mallocBytes $ sizeOf (0 :: CShort) * fromIntegral nsam :: IO (Ptr CShort)+  let nbyte = floor $ (fromIntegral (nbit + 7) / 8 :: Float) :: Int+  bits <- mallocBytes $ sizeOf (0 :: CUChar) * fromIntegral nbyte :: IO (Ptr CUChar)+  input <- L.readFile fin+  let samps = runGet getSamples input+  mapM_ (\x -> c2encode codec2 x buf bits nbyte fout) (chunksOf (fromIntegral nsam) samps)++getSample :: Get CShort+getSample = do+  s <- getWord16le+  return $! CShort (fromIntegral s)++getSamples :: Get [CShort]+getSamples = do+  empty <- isEmpty+  if empty+    then return []+    else do+      samp <- getSample+      remaining' <- getSamples+      return (samp:remaining')++-- | TODO: Is there a better way to do this?+putCUChar :: [CUChar] -> Put+putCUChar input = do+  mapM_ (put . inner) input+  return ()+  where+    inner (CUChar i) = i++c2encode :: Ptr C'CODEC2+         -> [CShort]     -- ^ A list that is @nsam@ elements in length.+         -> Ptr CShort   -- ^ The pointer that the ['Word8'] above gets poked to.+         -> Ptr CUChar   -- ^ The pointer that codec2_encode should store in.+         -> Int          -- ^ How big the result is+         -> String       -- ^ Output filename+         -> IO ()+c2encode codec2 frame poke' store nbyte fout = do+  pokeArray poke' frame+  c'codec2_encode codec2 store poke'+  -- And, for testing:+  written <- peekArray nbyte store+  let bs = runPut $ putCUChar written+  L.appendFile fout bs