Advertisement
Guest User

Wave.hs

a guest
Nov 18th, 2015
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-
  2. Reads wave file into raw structure, containing
  3. meta and signal data. For detailed header structure
  4. see the Wave format specification.
  5. -}
  6.  
  7. module Signal.Wave (
  8.     WaveHeader (..),
  9.     RawSignal (..),
  10.     Wave (..),
  11.     Endianness (..),
  12.     readWaveFromFile
  13. ) where
  14.  
  15. import Control.Applicative
  16. import Data.Word
  17. import Data.Binary.Get
  18.  
  19. import qualified Data.ByteString.Lazy as ByteStr
  20.  
  21. data Endianness = LittleEndian | BigEndian deriving (Eq, Show)
  22.  
  23. data WaveHeader = WaveHeader {
  24.     header :: !Word32,
  25.     fileSize :: !Word32,
  26.     waveHeader :: !Word32,
  27.     fmtHeader :: !Word32,
  28.     waveMetaSize :: !Word32,
  29.     waveFormat :: !Word16,
  30.     channelsNum :: !Word16,
  31.     frequency :: !Word32,
  32.     bytesPerSec :: !Word32,
  33.     bytesPerBlock :: !Word16,
  34.     bitsPerSample :: !Word16,
  35.     dataHeader :: !Word32,
  36.     dataSize :: !Word32
  37. } deriving (Eq, Show)
  38.  
  39. newtype RawSignal = RawSignal {
  40.     waveContents :: ByteStr.ByteString
  41. } deriving (Eq, Show)
  42.  
  43. data Wave = Wave {
  44.     waveMeta :: !WaveHeader,
  45.     rawSignal :: !RawSignal,
  46.     endianness :: Endianness
  47. } deriving (Eq, Show)
  48.  
  49. waveHeaderLength = 44
  50.  
  51. readWaveFromFile :: FilePath -> IO Wave
  52. readWaveFromFile path =
  53.     Wave <$> header <*> (RawSignal <$> dataString)
  54.          <*> (getEndianness <$> header)
  55.     where
  56.         input = ByteStr.readFile path
  57.         dataString = ByteStr.drop waveHeaderLength <$> input
  58.         header = (runGet getWaveHeader . ByteStr.take waveHeaderLength) <$> input
  59.  
  60. getWaveHeader :: Get WaveHeader
  61. getWaveHeader =
  62.     WaveHeader <$> dw <*> dw <*> dw <*> dw <*> dw <*> w
  63.                <*> w <*> dw <*> dw <*> w <*> w <*> dw <*> dw
  64.     where
  65.         w = getWord16le
  66.         dw = getWord32le
  67.  
  68. --Endianness stub : TODO!
  69. getEndianness :: WaveHeader -> Endianness
  70. getEndianness _ = LittleEndian
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement