module Sound.File.NeXT ( FrameCount,SampleRate,ChannelCount,Header(..)
, header
, read
, write
, module Sound.File.Encoding ) where
import Prelude hiding (read)
import qualified Data.ByteString.Lazy as B
import Data.Int
import Data.Maybe
import Sound.OSC.Coding.Byte
import Sound.File.Decode
import Sound.File.Encode
import Sound.File.Encoding
type Offset = Int64
type SampleRate = Int
type FrameCount = Int
type ChannelCount = Int
data Header = Header { frameCount :: FrameCount
, encoding :: Encoding
, sampleRate :: SampleRate
, channelCount :: ChannelCount }
deriving (Eq, Show)
toEncoding :: Int -> Encoding
toEncoding n =
case n of
2 -> Linear8
3 -> Linear16
5 -> Linear32
6 -> Float
7 -> Double
_ -> undefined
fromEncoding :: Encoding -> Int
fromEncoding c =
case c of
Linear8 -> 2
Linear16 -> 3
Linear32 -> 5
Float -> 6
Double -> 7
magic :: Int
magic = 0x2e736e64
encodeHeader :: Header -> B.ByteString
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)
decodeHeader :: B.ByteString -> Maybe (Offset, Header)
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 =
let h = encodeHeader (Header nf enc sr nc)
b = B.append h d
in B.writeFile fn b
write :: (Real n,Floating n) => FilePath -> Header -> [[n]] -> IO ()
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)
header :: FilePath -> IO Header
header fn = fmap fst (readB fn)
read :: (Real n,Floating n) => FilePath -> IO (Header, [[n]])
read fn = do
(Header nf enc sr nc, b) <- readB fn
let d = decode enc nc b
return (Header nf enc sr nc, d)