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 +14/−2
- src/Bindings/Codec2.hsc +7/−0
- src/Demo.hs +66/−0
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