packages feed

osc (empty) → 1.0.0.2

raw patch · 6 files changed

+250/−0 lines, 6 filesdep +attoparsecdep +basedep +binarysetup-changed

Dependencies added: attoparsec, base, binary, bytestring, data-binary-ieee754, network

Files

+ LICENSE view
@@ -0,0 +1,24 @@+Copyright 2010, Simon Marlow+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+this list of conditions and the following disclaimer.+ +- Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.+ +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
+ osc.cabal view
@@ -0,0 +1,41 @@+name: osc+version: 1.0.0.2+cabal-version: >=1.6+build-type: Simple+license: BSD3+license-file: LICENSE+copyright: (c) Gabriel Pickl+maintainer: Gabriel Pickl <peacemotion@gmail.com>+stability: unstable+homepage: https://github.com/peacememories/haskell-osc+bug-reports: mailto:peacemotion@gmail.com+synopsis: A library to handle messages in the OSC protocol+description: This library allows users to parse and write OSC (Open Sound Control) messages.+             It uses the parsing library attoparsec to read binary data.+category: Sound+author: Gabriel Pickl+data-dir: ""+ +source-repository head+    type: git+    location: https://github.com/peacememories/haskell-osc.git+ +flag threaded+    Default: False+ +library+    build-depends: base >=4.2 && <5, attoparsec ==0.12.*,+                   binary ==0.7.*, bytestring ==0.10.*, data-binary-ieee754 ==0.4.*,+                   network ==2.6.*+     +    if flag(threaded)+        exposed: True+        buildable: True+        ghc-options: -threaded+    exposed-modules: Sound.OSC Sound.OSC.Parser+    exposed: True+    buildable: True+    hs-source-dirs: src+    other-modules: Sound.OSC.Printer+ + 
+ src/Sound/OSC.hs view
@@ -0,0 +1,44 @@+-----------------------------------------------------------------------------
+--
+-- Module      :  Sound.OSC
+-- Copyright   :  (c) Gabriel Pickl
+-- License     :  BSD3
+--
+-- Maintainer  :  Gabriel Pickl <peacemotion@gmail.com>
+-- Stability   :  unstable
+-- Portability :
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Sound.OSC
+    ( Timestamp
+    , OSC
+        ( Bundle
+        , Message
+        )
+    , Datum
+        ( String
+        , Int
+        , Float
+        , Blob
+        )
+) where
+
+import Data.Word       (Word64)
+import Data.Int        (Int32)
+import Data.ByteString (ByteString)
+
+type Timestamp = Word64
+
+data OSC = Bundle Timestamp [OSC]
+         | Message String [Datum]
+         deriving (Show)
+
+-- Minimal type definition for OSC
+data Datum = String String
+           | Int    Int32
+           | Float  Float
+           | Blob   ByteString
+           deriving (Show)
+ src/Sound/OSC/Parser.hs view
@@ -0,0 +1,111 @@+-----------------------------------------------------------------------------
+--
+-- Module      :  Sound.OSC.Parser
+-- Copyright   :  (c) Gabriel Pickl
+-- License     :  BSD3
+--
+-- Maintainer  :  Gabriel Pickl <peacemotion@gmail.com>
+-- Stability   :  unstable
+-- Portability :
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Sound.OSC.Parser (
+    osc
+) where
+
+{-# LANGUAGE DoAndIfThenElse #-}
+
+
+import Data.Attoparsec.ByteString as AP
+import Data.Binary.Get
+import Data.Binary.IEEE754
+import Data.Word (Word64, Word8)
+import Control.Applicative ((<$>), (<|>))
+import Data.ByteString.Char8 (unpack, pack)
+import Data.Int (Int32)
+import qualified Data.ByteString as BS
+import Data.ByteString.Lazy (fromStrict)
+import Data.ByteString (ByteString)
+
+import Sound.OSC
+
+nest :: AP.Parser ByteString -> AP.Parser a -> AP.Parser a
+nest bsp p = bsp >>= parse
+    where
+        parse bs = either fail return (parseOnly p bs)
+
+int32 :: AP.Parser Int32
+int32 = convert <$> AP.take 4
+    where
+        convert :: ByteString -> Int32
+        convert bs = fromIntegral $ runGet getWord32be $ fromStrict bs
+
+float32 :: AP.Parser Float
+float32 = convert <$> AP.take 4
+    where
+        convert :: ByteString -> Float
+        convert bs = runGet getFloat32be $ fromStrict bs
+
+timestamp :: AP.Parser Timestamp
+timestamp = convert <$> AP.take 8
+    where
+        convert :: ByteString -> Timestamp
+        convert bs = runGet getWord64be $ fromStrict bs
+
+oscString :: AP.Parser ByteString
+oscString = do
+    str <- AP.takeTill (==0)
+    AP.take $ blockPadding (BS.length str)
+    return str
+    where
+        blockPadding len = ((-len-1) `mod` 4)+1
+
+tokenParser :: Word8 -> AP.Parser Datum
+-- s
+tokenParser 115 = String . unpack <$> oscString
+-- i
+tokenParser 105 = Int <$> int32
+-- f
+tokenParser 102 = Float <$> float32
+-- b
+tokenParser 98 = do
+    size <- int32
+    Blob <$> (AP.take $ fromIntegral size)
+tokenParser t = fail $ "Could not parse type " ++ show t
+
+typeTag :: Parser [Word8]
+typeTag = do
+    first <- AP.peekWord8
+    case first of
+        Just 44 -> tail . BS.unpack <$> oscString
+        Just other -> fail $ "Unexpected token: " ++ show other
+        Nothing -> return []
+
+message :: AP.Parser OSC
+message = do
+    addr <- unpack <$> oscString
+    types <- typeTag
+    (Message addr) <$> (sequence $ map tokenParser types)
+
+bundle :: AP.Parser OSC
+bundle = do
+    string $ pack "#bundle"
+    word8 0
+    time <- timestamp
+    elems <- AP.manyTill bundleElement AP.endOfInput
+    return $ Bundle time elems
+
+bundleElement :: AP.Parser OSC
+bundleElement = do
+    length <- int32
+    nest (AP.take $ fromIntegral length) osc
+
+osc :: AP.Parser OSC
+osc = do
+    first <- AP.peekWord8
+    case first of
+        Just 35 -> bundle
+        otherwise -> message
+ src/Sound/OSC/Printer.hs view
@@ -0,0 +1,24 @@+-----------------------------------------------------------------------------
+--
+-- Module      :  Sound.OSC.Printer
+-- Copyright   :  (c) Gabriel Pickl
+-- License     :  BSD3
+--
+-- Maintainer  :  Gabriel Pickl <peacemotion@gmail.com>
+-- Stability   :  unstable
+-- Portability :
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Sound.OSC.Printer (
+    printOSC
+) where
+
+import Sound.OSC
+
+import Data.ByteString (ByteString)
+
+printOSC :: OSC -> ByteString
+printOSC = undefined