Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-
- Reads wave file into raw structure, containing
- meta and signal data. For detailed header structure
- see the Wave format specification.
- -}
- module Signal.Wave (
- WaveHeader (..),
- RawSignal (..),
- Wave (..),
- Endianness (..),
- readWaveFromFile
- ) where
- import Control.Applicative
- import Data.Word
- import Data.Binary.Get
- import qualified Data.ByteString.Lazy as ByteStr
- data Endianness = LittleEndian | BigEndian deriving (Eq, Show)
- data WaveHeader = WaveHeader {
- header :: !Word32,
- fileSize :: !Word32,
- waveHeader :: !Word32,
- fmtHeader :: !Word32,
- waveMetaSize :: !Word32,
- waveFormat :: !Word16,
- channelsNum :: !Word16,
- frequency :: !Word32,
- bytesPerSec :: !Word32,
- bytesPerBlock :: !Word16,
- bitsPerSample :: !Word16,
- dataHeader :: !Word32,
- dataSize :: !Word32
- } deriving (Eq, Show)
- newtype RawSignal = RawSignal {
- waveContents :: ByteStr.ByteString
- } deriving (Eq, Show)
- data Wave = Wave {
- waveMeta :: !WaveHeader,
- rawSignal :: !RawSignal,
- endianness :: Endianness
- } deriving (Eq, Show)
- waveHeaderLength = 44
- readWaveFromFile :: FilePath -> IO Wave
- readWaveFromFile path =
- Wave <$> header <*> (RawSignal <$> dataString)
- <*> (getEndianness <$> header)
- where
- input = ByteStr.readFile path
- dataString = ByteStr.drop waveHeaderLength <$> input
- header = (runGet getWaveHeader . ByteStr.take waveHeaderLength) <$> input
- getWaveHeader :: Get WaveHeader
- getWaveHeader =
- WaveHeader <$> dw <*> dw <*> dw <*> dw <*> dw <*> w
- <*> w <*> dw <*> dw <*> w <*> w <*> dw <*> dw
- where
- w = getWord16le
- dw = getWord32le
- --Endianness stub : TODO!
- getEndianness :: WaveHeader -> Endianness
- getEndianness _ = LittleEndian
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement