hsc3-sf 0.7 → 0.8
raw patch · 8 files changed
+109/−58 lines, 8 filesdep ~basedep ~hoscPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, hosc
API changes (from Hackage documentation)
+ Sound.File.Decode: decode :: Encoding -> Int -> ByteString -> [[Double]]
+ Sound.File.Decode: deinterleave :: Int -> [a] -> [[a]]
Files
- Help/rescale.help.hs +10/−7
- Help/stat.help.hs +27/−0
- README +2/−2
- Sound/File/Decode.hs +14/−9
- Sound/File/Encode.hs +4/−2
- Sound/File/Encoding.hs +5/−5
- Sound/File/NeXT.hs +34/−25
- hsc3-sf.cabal +13/−8
Help/rescale.help.hs view
@@ -1,18 +1,21 @@ -- Change the gain of an audio file. -import qualified Sound.File.NeXT as N+import qualified Sound.File.NeXT as F import System.Environment rescale :: Double -> FilePath -> IO ()-rescale n fn = do - (N.Header nf _ sr nc, d) <- N.read fn+rescale n fn = do+ (hdr, d) <- F.read fn let d' = map (map (* n)) d- N.write (fn ++ ".rescale.au") (N.Header nf N.Float sr nc) d'+ hdr' = hdr { F.encoding = F.Float }+ F.write (fn ++ ".rescale.au") hdr' d' main :: IO ()-main = do - [g, f] <- getArgs- rescale (read g) f+main = do+ a <- getArgs+ case a of+ [g, fn] -> rescale (read g) fn+ _ -> putStrLn "rescale gain-multiplier file-name" {- rescale 0.25 "/home/rohan/audio/text.snd"
+ Help/stat.help.hs view
@@ -0,0 +1,27 @@+-- Trivial sound file statistics.++import qualified Sound.File.NeXT as F+import System.Environment++stat ::FilePath -> IO ()+stat fn = do+ (hdr, d) <- F.read fn+ let nf = F.frameCount hdr+ sr = F.sampleRate hdr+ nc = F.channelCount hdr+ mapM_ print [("nframes", [fromIntegral nf])+ ,("srate", [fromIntegral sr])+ ,("nchan", [fromIntegral nc])+ ,("minimum", map minimum d)+ ,("maximum", map maximum d)]++main :: IO ()+main = do+ a <- getArgs+ case a of+ [fn] -> stat fn+ _ -> putStrLn "stat file-name"++{-+stat "/home/rohan/audio/text.snd"+-}
README view
@@ -6,7 +6,7 @@ sound file support in haskell see hsndfile. http://slavepianos.org/rd- http://darcs.k-hornz.de/repos/hsndfile/+ http://code.haskell.org/hsndfile -(c) rohan drape, 2006-2009+(c) rohan drape, 2006-2010 gpl, http://gnu.org/copyleft/
Sound/File/Decode.hs view
@@ -1,4 +1,5 @@-module Sound.File.Decode ( decode ) where+module Sound.File.Decode ( decode+ , deinterleave ) where import Data.Int import qualified Data.ByteString.Lazy as B@@ -7,8 +8,9 @@ setsOf :: Int -> [a] -> [[a]] setsOf _ [] = []-setsOf n l = x : setsOf n y - where (x, y) = splitAt n l+setsOf n l =+ let (x, y) = splitAt n l+ in x : setsOf n y channel :: [[a]] -> Int -> [a] channel l n = map (!!n) l@@ -18,8 +20,9 @@ bSetsOf :: Int64 -> B.ByteString -> [B.ByteString] bSetsOf _ b | B.null b = []-bSetsOf n b | otherwise = x : bSetsOf n y - where (x, y) = B.splitAt n b+bSetsOf n b | otherwise =+ let (x, y) = B.splitAt n b+ in x : bSetsOf n y decodef32 :: Int -> B.ByteString -> [[Double]] decodef32 n = deinterleave n . map decode_f32 . bSetsOf 4@@ -37,7 +40,9 @@ i16_f = map ((/ 32768.0) . fromIntegral) decode :: Encoding -> Int -> B.ByteString -> [[Double]]-decode enc nc b | enc == Linear8 = map i8_f (decodei8 nc b)- | enc == Linear16 = map i16_f (decodei16 nc b)- | enc == Float = decodef32 nc b- | otherwise = undefined+decode enc nc b =+ case enc of+ Linear8 -> map i8_f (decodei8 nc b)+ Linear16 -> map i16_f (decodei16 nc b)+ Float -> decodef32 nc b+ _ -> undefined
Sound/File/Encode.hs view
@@ -12,5 +12,7 @@ encodef32 = B.concat . map encode_f32 . interleave encode :: Encoding -> [[Double]] -> B.ByteString-encode enc d | enc == Float = encodef32 d- | otherwise = undefined+encode enc d =+ case enc of+ Float -> encodef32 d+ _ -> undefined
Sound/File/Encoding.hs view
@@ -1,11 +1,11 @@ module Sound.File.Encoding where data Encoding = Linear8- | Linear16- | Linear32- | Float- | Double- deriving (Eq, Show)+ | Linear16+ | Linear32+ | Float+ | Double+ deriving (Eq, Show) -- | Bytes per sample at specified encoding. sizeOf :: Encoding -> Int
Sound/File/NeXT.hs view
@@ -47,44 +47,53 @@ -- | Byte-encode a NeXT header. encodeHeader :: Header -> B.ByteString-encodeHeader (Header nf enc sr nc) = B.concat (map encode_i32 h)- where nb = nf * nc * sizeOf enc- h = [magic, 28, nb, (fromEncoding enc), sr, nc, 0]+encodeHeader (Header nf enc sr nc) =+ let nb = nf * nc * sizeOf enc+ h = [magic, 28, nb, (fromEncoding enc), sr, nc, 0]+ in B.concat (map encode_i32 h) -- | Byte-decode a NeXT header. decodeHeader :: B.ByteString -> Maybe (Offset, Header)-decodeHeader u = if m == magic then Just (off, Header nf enc sr nc) else Nothing- where f n = decode_i32 (B.drop n u)- m = f 0- off = fromIntegral (f 4)- nb = f 8- enc = toEncoding (f 12)- sr = f 16- nc = f 20- nf = nb `div` (nc * sizeOf enc)+decodeHeader u =+ let f n = decode_i32 (B.drop n u)+ m = f 0+ off = fromIntegral (f 4)+ nb = f 8+ enc = toEncoding (f 12)+ sr = f 16+ nc = f 20+ nf = nb `div` (nc * sizeOf enc)+ in if m == magic+ then Just (off, Header nf enc sr nc)+ else Nothing writeB :: FilePath -> Header -> B.ByteString -> IO ()-writeB fn (Header nf enc sr nc) d = B.writeFile fn b- where h = encodeHeader (Header nf enc sr nc)- b = B.append h d+writeB fn (Header nf enc sr nc) d =+ let h = encodeHeader (Header nf enc sr nc)+ b = B.append h d+ in B.writeFile fn b -- | Write sound file, data is non-interleaved. write :: FilePath -> Header -> [[Double]] -> IO ()-write fn (Header nf enc sr nc) d = writeB fn (Header nf enc sr nc) b- where b = encode enc d+write fn (Header nf enc sr nc) d =+ let b = encode enc d+ in writeB fn (Header nf enc sr nc) b readB :: FilePath -> IO (Header, B.ByteString)-readB fn = do b <- B.readFile fn- let (off, h) = fromMaybe undefined (decodeHeader b)- return (h, B.drop off b)+readB fn = do+ b <- B.readFile fn+ let (off, h) = fromMaybe undefined (decodeHeader b)+ return (h, B.drop off b) -- | Read sound file meta data. header :: FilePath -> IO Header-header fn = do (h, _) <- read fn- return h+header fn = do+ (h, _) <- read fn+ return h -- | Read sound file, data is interleaved. read :: FilePath -> IO (Header, [[Double]])-read fn = do (Header nf enc sr nc, b) <- readB fn- let d = decode enc nc b- return (Header nf enc sr nc, d)+read fn = do+ (Header nf enc sr nc, b) <- readB fn+ let d = decode enc nc b+ return (Header nf enc sr nc, d)
hsc3-sf.cabal view
@@ -1,29 +1,34 @@ Name: hsc3-sf-Version: 0.7+Version: 0.8 Synopsis: Haskell SuperCollider SoundFile-Description: Trivial NeXT/Sun sound file input/output.+Description: Trivial NeXT sound file input and output. For almost all use cases please see Stefan Kersten's hsndfile package. License: GPL Category: Sound-Copyright: (c) Rohan Drape, 2006-2009+Copyright: (c) Rohan Drape, 2006-2010 Author: Rohan Drape Maintainer: rd@slavepianos.org Stability: Experimental-Homepage: http://slavepianos.org/rd/f/924736/-Tested-With: GHC == 6.8.2+Homepage: http://slavepianos.org/rd/?t=hsc3-sf+Tested-With: GHC == 6.10.3 Build-Type: Simple Cabal-Version: >= 1.6 Data-files: README Help/rescale.help.hs+ Help/stat.help.hs Library- Build-Depends: base == 3.*,+ Build-Depends: base == 4.*, bytestring,- hosc == 0.7+ hosc == 0.8 GHC-Options: -Wall -fwarn-tabs Exposed-modules: Sound.File.NeXT+ Sound.File.Decode Other-modules: Sound.File.Encoding Sound.File.Encode- Sound.File.Decode++Source-Repository head+ Type: darcs+ Location: http://slavepianos.org/~rd/sw/hsc3-sf/