packages feed

hsdif (empty) → 0.11

raw patch · 12 files changed

+508/−0 lines, 12 filesdep +basedep +bytestringdep +hoscsetup-changedbinary-added

Dependencies added: base, bytestring, hosc

Files

+ Help/crotale.sdif view

binary file changed (absent → 856 bytes)

+ Help/hsdif.hs view
@@ -0,0 +1,54 @@+import qualified Data.ByteString.Lazy as B+import Sound.SDIF.Byte.Frame+import Sound.SDIF.Byte.Matrix+import Sound.SDIF.Byte.SDIF+import Sound.SDIF.Frame+import Sound.SDIF.Matrix+import Sound.SDIF++main :: IO ()+main = do+  b <- B.readFile "crotale.sdif"+  -- (856,True,2)+  print (show (B.length b,is_sdif_b b,sdif_b_frames b))+  s <- sdif_read_file "crotale.sdif"+  -- (2,[(0,16),(16,856)])+  print (sdif_frames s,sdif_frame_i s)+  let fb = sdif_frame_b s 1+  -- ("1RES",832,0.0,2,1,[(24,840)])+  print (frame_b_type fb+        ,frame_b_size fb+        ,frame_b_time fb+        ,frame_b_id fb+        ,frame_b_matrices fb+        ,frame_b_matrix_i fb)+  let mb = frame_b_data fb+  -- ("1RES",4,50,4,200,800,816)+  print (matrix_b_type mb+        ,matrix_b_data_type mb+        ,matrix_b_rows mb+        ,matrix_b_columns mb+        ,matrix_b_elements mb+        ,matrix_b_data_size mb+        ,matrix_b_storage_size mb)+  let f = sdif_frame s 1+  -- ("1RES",832,0.0,2,1,[(24,840)])+  print (frame_type f+        ,frame_size f+        ,frame_time f+        ,frame_id f+        ,frame_matrices f+        ,frame_matrix_i f)+  let m = frame_matrix f 0+  -- ("1RES",4,50,4,200,800,816)+  print (matrix_type m+        ,matrix_data_type m+        ,matrix_rows m+        ,matrix_columns m+        ,matrix_elements m+        ,matrix_data_size m+        ,matrix_storage_size m)+  -- ~ [F32 35.45,F32 1.28e-3,F32 5.20,F32 0.0]+  print (matrix_row m 0)+  -- ~ [F32 35.45,F32 128.59,F32 346.97]+  print (take 3 (matrix_column m 0))
+ README view
@@ -0,0 +1,8 @@+hsdif - haskell sound description interchange format++  http://slavepianos.org/rd/?t=hsdif+  http://haskell.org/+  http://sdif.sourceforge.net/++(c) rohan drape, 2010-2011+    gpl, http://gnu.org/copyleft/
+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ Sound/SDIF.hs view
@@ -0,0 +1,53 @@+-- | SDIF (Sound Description Interchange Format)+module Sound.SDIF where++import qualified Data.ByteString.Lazy as B+import Sound.SDIF.Byte.SDIF+import Sound.SDIF.Frame+import Sound.SDIF.Matrix+import Sound.SDIF.Type++-- | SDIF data store.+data SDIF = SDIF { sdif_b :: B.ByteString+                 , sdif_frames :: Int+                 , sdif_frame_i :: [(Int, Int)]+                 , sdif_frame_c :: [Frame] }+            deriving (Eq, Show)++-- | Decode 'SDIF' data stream.+decode_sdif :: B.ByteString -> SDIF+decode_sdif sdf =+    let n = sdif_b_frames sdf+        ix = sdif_b_frame_i sdf n+        frm (i,j) = decode_frame (section' sdf i j)+        s = SDIF { sdif_b = sdf+                 , sdif_frames = n+                 , sdif_frame_i = ix+                 , sdif_frame_c = map frm ix }+    in if is_sdif_b sdf+       then s+       else error "decode_sdif" "illegal data"++-- | Read and decode 'SDIF' from named file.+sdif_read_file :: FilePath -> IO SDIF+sdif_read_file file_name = do+  b <- B.readFile file_name+  return (decode_sdif b)++-- | Extract /n/th frame data from 'SDIF'.+sdif_frame_b :: SDIF -> Int -> B.ByteString+sdif_frame_b sdf n =+    let (i,j) = sdif_frame_i sdf !! n+    in (section' (sdif_b sdf) i j)++-- | Extract and decode /n/th frame from 'SDIF'.+sdif_frame :: SDIF -> Int -> Frame+sdif_frame sdf n = sdif_frame_c sdf !! n++-- | Extract and decode /j/th matrix from /i/th frame from 'SDIF'.+sdif_matrix :: SDIF -> Int -> Int -> Matrix+sdif_matrix sdf i = frame_matrix (sdif_frame sdf i)++-- | Run 'matrix_v' on result of 'sdif_matrix'.+sdif_matrix_v :: SDIF -> Int -> Int -> [Datum]+sdif_matrix_v sdf i = matrix_v . sdif_matrix sdf i
+ Sound/SDIF/Byte/Frame.hs view
@@ -0,0 +1,49 @@+-- | Byte level SDIF frame data structure.+module Sound.SDIF.Byte.Frame where++import qualified Data.ByteString.Lazy as B+import Sound.OpenSoundControl.Coding.Byte+import Sound.SDIF.Byte.Matrix+import Sound.SDIF.Type++-- | Data integrity check for SDIF frame data stream.+is_frame_b :: B.ByteString -> Bool+is_frame_b frm =+    let n = fromIntegral (B.length frm) - 8+    in frame_b_size frm == n++-- | Extract type string from SDIF frame byte stream.+frame_b_type :: B.ByteString -> String+frame_b_type frm = map (toEnum . fromIntegral) (B.unpack (section frm 0 4))++-- | Extract size from SDIF frame byte stream.+frame_b_size :: B.ByteString -> Int+frame_b_size frm = decode_i32 (section frm 4 8)++-- | Extract time stamp from SDIF frame byte stream.+frame_b_time :: B.ByteString -> Double+frame_b_time frm = decode_f32 (section frm 8 16)++-- | Extract identifier from SDIF frame byte stream.+frame_b_id :: B.ByteString -> Int+frame_b_id frm = decode_i32 (section frm 16 20)++-- | Extract matrix count from SDIF frame byte stream.+frame_b_matrices :: B.ByteString -> Int+frame_b_matrices frm = decode_i32 (section frm 20 24)++-- | Extract frame data segment from SDIF frame byte stream.+frame_b_data :: B.ByteString -> B.ByteString+frame_b_data frm = section frm 24 (B.length frm)++-- | Extract frame matrix /(start,end)/ indices from SDIF frame byte stream.+frame_b_matrix_i :: B.ByteString -> [(Int, Int)]+frame_b_matrix_i frm =+    let go i j xs =+            if j == 0+            then reverse xs+            else let h = section' frm i (i + matrix_b_header_size)+                     sz = fromIntegral (matrix_b_storage_size h)+                     xs' = (i, i + sz) : xs+                 in go (i + sz) (j - sz) xs'+    in go 24 (fromIntegral (B.length frm) - 24) []
+ Sound/SDIF/Byte/Matrix.hs view
@@ -0,0 +1,69 @@+-- | Byte level SDIF frame data structure.+module Sound.SDIF.Byte.Matrix where++import qualified Data.ByteString.Lazy as B+import Sound.OpenSoundControl.Coding.Byte+import Sound.SDIF.Type++-- | Data integrity check for SDIF matix byte stream.+is_matrix_b :: B.ByteString -> Bool+is_matrix_b mtx =+    let n = fromIntegral (B.length mtx)+    in matrix_b_storage_size mtx == n++-- | Matrix header size (constant).+matrix_b_header_size :: Int+matrix_b_header_size = 16++-- | Extract matrix header byte stream.+matrix_b_header :: B.ByteString -> B.ByteString+matrix_b_header mtx = section mtx 0 (fromIntegral matrix_b_header_size)++-- | Extract matrix type string.+matrix_b_type :: B.ByteString -> String+matrix_b_type mtx = map (toEnum . fromIntegral) (B.unpack (section mtx 0 4))++-- | Extract matrix element data 'Type'.+matrix_b_data_type :: B.ByteString -> Type+matrix_b_data_type mtx = decode_i32 (section mtx 4 8)++-- | Extract matrix row count.+matrix_b_rows :: B.ByteString -> Int+matrix_b_rows mtx = decode_i32 (section mtx 8 12)++-- | Extract matrix column count.+matrix_b_columns :: B.ByteString -> Int+matrix_b_columns mtx = decode_i32 (section mtx 12 16)++-- | Extract matrix element count (ie. rows by columns).+matrix_b_elements :: B.ByteString -> Int+matrix_b_elements mtx = matrix_b_rows mtx * matrix_b_columns mtx++-- | Calculate size of matrix data store (ie. elements by 'Type' size).+matrix_b_data_size :: B.ByteString -> Int+matrix_b_data_size mtx =+    let r = matrix_b_rows mtx+        c = matrix_b_columns mtx+    in r * c * data_type_size (matrix_b_data_type mtx)++-- | Variant of 'matrix_b_data_size' taking into account required padding.+matrix_b_storage_size :: B.ByteString -> Int+matrix_b_storage_size mtx =+    let pad_bytes sz = let m = sz `mod` 8+                       in if m > 0 then 8 - m else 0+        n = matrix_b_data_size mtx+    in n + pad_bytes n + 16++-- | Extract matrix data from byte stream.+matrix_b_to_matrix_v :: B.ByteString -> [Datum]+matrix_b_to_matrix_v mtx =+    let ty = matrix_b_data_type mtx+        sz = data_type_size ty+        dc = data_type_decoder ty+        go i j xs =+            if j == 0+            then reverse xs+            else let i' = i + sz+                     xs' = dc (section' mtx i i') : xs+                 in go i' (j - 1) xs'+    in go 16 (matrix_b_elements mtx) []
+ Sound/SDIF/Byte/SDIF.hs view
@@ -0,0 +1,33 @@+-- | Byte level SDIF data structure.+module Sound.SDIF.Byte.SDIF where++import qualified Data.ByteString.Lazy as B+import Sound.OpenSoundControl.Coding.Byte+import Sound.SDIF.Type++-- | Check signature of SDIF byte stream.+is_sdif_b :: B.ByteString -> Bool+is_sdif_b sdf =+    let sig = map (fromIntegral . fromEnum) "SDIF"+    in B.unpack (section sdf 0 4) == sig++-- | Count number of frames at SDIF byte stream.+sdif_b_frames :: B.ByteString -> Int+sdif_b_frames sdf =+    let go i j n =+            if j == 0+            then n+            else let sz = decode_i32 (section' sdf (i + 4) (i + 8)) + 8+                 in go (i + sz) (j - sz) (n + 1)+    in go 0 (fromIntegral (B.length sdf)) 0++-- | Extract start and end indices for /n/ frames at SDIF byte stream.+sdif_b_frame_i :: B.ByteString -> Int -> [(Int, Int)]+sdif_b_frame_i sdf frame_count =+    let go i j xs n =+            if n == frame_count+            then reverse xs+            else let sz = decode_i32 (section' sdf (i + 4) (i + 8)) + 8+                     xs' = (i, i + sz) : xs+                 in go (i + sz) (j - sz) xs' (n + 1)+    in go 0 (fromIntegral (B.length sdf)) [] 0
+ Sound/SDIF/Frame.hs view
@@ -0,0 +1,49 @@+-- | SDIF frame functions+module Sound.SDIF.Frame where++import qualified Data.ByteString.Lazy as B+import Sound.SDIF.Byte.Frame+import Sound.SDIF.Matrix+import Sound.SDIF.Type++-- | SDIF frame data store+data Frame = Frame { frame_b :: B.ByteString+                   , frame_type :: String+                   , frame_size :: Int+                   , frame_time :: Double+                   , frame_id :: Int+                   , frame_matrices :: Int+                   , frame_matrix_i :: [(Int, Int)]+                   , frame_matrix_c :: [Matrix] }+             deriving (Eq, Show)++-- | Decode SDIF 'Frame'.+decode_frame :: B.ByteString -> Frame+decode_frame frm =+    let ty = frame_b_type frm+        sz = frame_b_size frm+        mtx (i,j) = decode_matrix (section' frm i j)+        ix = frame_b_matrix_i frm+        f = if ty == "SDIF"+            then Frame frm ty sz 0 0 0 [] []+            else Frame { frame_b = frm+                       , frame_type = ty+                       , frame_size = sz+                       , frame_time = frame_b_time frm+                       , frame_id = frame_b_id frm+                       , frame_matrices = frame_b_matrices frm+                       , frame_matrix_i = ix+                       , frame_matrix_c = map mtx ix }+    in if is_frame_b frm+       then f+       else error "decode_frame" "illegal data"++-- | Extract /n/th matrix of 'Frame'.+frame_matrix_b :: Frame -> Int -> B.ByteString+frame_matrix_b frm n =+    let (i,j) = frame_matrix_i frm !! n+    in section' (frame_b frm) i j++-- | Extract and decode /n/th matrix of 'Frame'.+frame_matrix :: Frame -> Int -> Matrix+frame_matrix frm n = frame_matrix_c frm !! n
+ Sound/SDIF/Matrix.hs view
@@ -0,0 +1,64 @@+-- | SDIF matrix functions.+module Sound.SDIF.Matrix where++import qualified Data.ByteString.Lazy as B+import Sound.SDIF.Byte.Matrix+import Sound.SDIF.Type++-- | SDIF matrix data store.+data Matrix = Matrix { matrix_b :: B.ByteString+                     , matrix_type :: String+                     , matrix_data_type :: Int+                     , matrix_rows :: Int+                     , matrix_columns :: Int+                     , matrix_elements :: Int+                     , matrix_data_size :: Int+                     , matrix_storage_size :: Int+                     , matrix_v :: [Datum] }+              deriving (Eq, Show)++-- | Decode 'Matrix'.+decode_matrix :: B.ByteString -> Matrix+decode_matrix mtx =+    let m = Matrix { matrix_b = mtx+                   , matrix_type = matrix_b_type mtx+                   , matrix_data_type = matrix_b_data_type mtx+                   , matrix_rows = matrix_b_rows mtx+                   , matrix_columns = matrix_b_columns mtx+                   , matrix_elements = matrix_b_elements mtx+                   , matrix_data_size = matrix_b_data_size mtx+                   , matrix_storage_size = matrix_b_storage_size mtx+                   , matrix_v = matrix_b_to_matrix_v mtx }+    in if is_matrix_b mtx+       then m+       else error "decode_matrix: illegal data"++-- | Section of list from /i/th to /j/th indices.+--+-- > list_section [1..9] 4 6 == [5,6]+list_section :: [a] -> Int -> Int -> [a]+list_section xs i j = take (j - i) (drop i xs)++-- | Extract /n/th row of 'Matrix'.+matrix_row :: Matrix -> Int -> [Datum]+matrix_row m n =+    let r = matrix_rows m+        c = matrix_columns m+        i = n * c+    in if n >= r+       then error "matrix_row: domain error"+       else list_section (matrix_v m) i (i + c)++-- | Extract /n/th column of 'Matrix'.+matrix_column :: Matrix -> Int -> [Datum]+matrix_column m n =+    let nr = matrix_rows m+        nc = matrix_columns m+        v = matrix_v m+        build i xs =+            if i == nr+            then reverse xs+            else build (i + 1) ((v !! (n + (i * nc))) : xs)+    in if n >= nc+       then error "matrix_column: domain error"+       else build 0 []
+ Sound/SDIF/Type.hs view
@@ -0,0 +1,89 @@+-- | SDIF related data types+module Sound.SDIF.Type where++import Data.Bits+import qualified Data.ByteString.Lazy as B+import Data.Int+import Data.Word+import Sound.OpenSoundControl.Coding.Byte++-- | Section of 'B.ByteString' from /i/th to /j/th indices.+section :: B.ByteString -> Int64 -> Int64 -> B.ByteString+section xs i j = B.take (j - i) (B.drop i xs)++-- | 'Int' based variant of 'section'.+section' :: B.ByteString -> Int -> Int -> B.ByteString+section' xs i j = section xs (fromIntegral i) (fromIntegral j)++-- | Data element type.+type Type = Int++-- | Is data element type standard.+data_type_standard_p :: Type -> Bool+data_type_standard_p d =+    let xs = [0x004, 0x008+             ,0x101, 0x102, 0x104, 0x108+             ,0x201, 0x202, 0x204, 0x208+             ,0x301+             ,0x401]+    in d `elem` xs++-- | String describing indicated data element type.+--+-- > data_type_string 0x008 == "real number"+data_type_string :: Type -> String+data_type_string d+    | d `elem` [0x004,0x008] = "real number"+    | d `elem` [0x101,0x102,0x104,0x108] = "signed integer"+    | d `elem` [0x201,0x202,0x204,0x208] = "unsigned integer"+    | d `elem` [0x301] = "utf_8 byte"+    | d `elem` [0x401] = "byte"+    | otherwise = "unknown"++-- | Size (in bytes) of data element type.+--+-- > data_type_size 0x008 == 8+data_type_size :: Type -> Int+data_type_size d = d .&. 0xff++-- | Universal type for element data.+data Datum = I8 Int+           | I16 Int+           | I32 Int+           | I64 Int64+           | U32 Int+           | U64 Word64+           | F32 Double+           | F64 Double+             deriving (Eq, Show)++-- | Decoder for indicated data element type to 'Datum'.+data_type_decoder :: Type -> B.ByteString -> Datum+data_type_decoder d x =+    case d of+      0x004 -> F32 (decode_f32 x)+      0x008 -> F64 (decode_f64 x)+      0x101 -> I8 (decode_i8 x)+      0x102 -> I16 (decode_i16 x)+      0x104 -> I32 (decode_i32 x)+      0x108 -> I64 (decode_i64 x)+      0x201 -> undefined -- decode_u8+      0x202 -> undefined -- decode_u16+      0x204 -> U32 (decode_u32 x)+      0x208 -> U64 (decode_u64 x)+      0x301 -> undefined+      0x401 -> undefined+      _ -> undefined++-- | SDIF encoder for 'Datum'.+data_type_encoder :: Datum -> B.ByteString+data_type_encoder x =+    case x of+      I8 n -> encode_i8 n+      I16 n -> encode_i16 n+      I32 n -> encode_i32 n+      I64 n -> encode_i64 n+      U32 n -> encode_u32 n+      U64 n -> encode_u64 n+      F32 n -> encode_f32 n+      F64 n -> encode_f64 n
+ hsdif.cabal view
@@ -0,0 +1,37 @@+Name:              hsdif+Version:           0.11+Synopsis:          Haskell SDIF+Description:       hsdif provides Sound.SDIF, a haskell+                   module implementing a subset of Sound Description+                   Interchange Format.+License:           GPL+Category:          Sound+Copyright:         (c) Rohan Drape, 2011+Author:            Rohan Drape+Maintainer:        rd@slavepianos.org+Stability:         Experimental+Homepage:          http://slavepianos.org/rd/?t=hsdif+Tested-With:       GHC == 7.2.2+Build-Type:        Simple+Cabal-Version:     >= 1.8++Data-Files:        README+                   Help/hsdif.hs+                   Help/crotale.sdif++Library+  Build-Depends:   base == 4.*,+                   bytestring,+                   hosc == 0.11.*+  GHC-Options:     -Wall -fwarn-tabs+  Exposed-modules: Sound.SDIF+                   Sound.SDIF.Frame+                   Sound.SDIF.Matrix+                   Sound.SDIF.Type+                   Sound.SDIF.Byte.Frame+                   Sound.SDIF.Byte.Matrix+                   Sound.SDIF.Byte.SDIF++Source-Repository  head+  Type:            darcs+  Location:        http://slavepianos.org/rd/sw/hsdif/