-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Work with WAVE and RF64 files -- -- Work with WAVE and RF64 files. @package wave @version 0.1.3 -- | This module provides a safe interface that allows to manipulate WAVE -- files in their “classic” form as well as files in the RF64 format -- https://tech.ebu.ch/docs/tech/tech3306-2009.pdf. RF64 adds the -- ability to store files larger than 4 Gb. -- -- The main feature of the API is that it does not allow the user to -- duplicate information and introduce errors in that way. For example, -- block align may be calculated from other parameters of audio stream, -- thus we do not store it in the Wave record and do not allow -- user to specify it. We provide, however, a way to calculate it given -- Wave record, see waveBlockAlign. The same is done for -- channels. Channel mask is a more general means of providing -- information about number of channels and corresponding speaker -- positions, thus we only store channel mask in user-friendly form, but -- number of channels can be derived from that information. -- -- Another feature of the library is that it does not dictate how to -- read/write audio data. What we give is the information about audio -- data and offset in file where it begins. To write data user may use a -- callback that receives a Handle as argument. Size of data block -- is deduced automatically for you. Exclusion of audio data from -- consideration makes the library pretty fast and open to different ways -- to handle audio data itself, including using foreign code (such as C). -- -- The library provides control over all parts of WAVE file that may be -- of interest. In particular, it even allows to write arbitrary chunks -- between fmt and data chunks, although it's rarely -- useful (and may actually confuse buggy applications that don't know -- how to skip unknown chunks). module Codec.Audio.Wave -- | Representation of “essential” information about a WAVE file. Every -- field in this record provides orthogonal piece of information, so no -- field can be calculated from other fields. The fields are complemented -- by the following functions that calculate some derivative parameters: -- waveByteRate, waveBitRate, waveBitsPerSample, -- waveBlockAlign, and waveChannels. data Wave Wave :: !WaveFormat -> !Word32 -> !SampleFormat -> !(Set SpeakerPosition) -> !Word32 -> !Word64 -> !Word64 -> [(ByteString, ByteString)] -> Wave -- | This specifies format of file this Wave record was extracted/to -- be written to, WaveFormat. Default value is: -- WaveVanilla. [waveFileFormat] :: Wave -> !WaveFormat -- | Sample rate in Hz, default is: 44100. [waveSampleRate] :: Wave -> !Word32 -- | Sample format. The library supports signed/unsigned integers and -- floats. Default value: SampleFormatPcmInt 16. [waveSampleFormat] :: Wave -> !SampleFormat -- | The channel mask as a Set of SpeakerPositions. Default -- value is speakerStereo. [waveChannelMask] :: Wave -> !(Set SpeakerPosition) -- | Offset in bytes from the beginning of file where actual sample data -- begins. Default value: 0. [waveDataOffset] :: Wave -> !Word32 -- | Size of audio data in bytes. Default value: 0. [waveDataSize] :: Wave -> !Word64 -- | Total number of samples in the audio stream. “Samples” here mean -- multi-channel samples, so one second of 44.1 kHz audio will have 44100 -- samples regardless of the number of channels. For PCM format it's -- deduced from size of data-block, for other formats it's read -- from/written to the “fact” chunk. Default value: 0. [waveSamplesTotal] :: Wave -> !Word64 -- | Other chunks as (tag, body) pairs. Only first four bytes of -- tag are significant (and it must be four bytes long, if it's -- too short it will be padded by null bytes). Default value: -- []. [waveOtherChunks] :: Wave -> [(ByteString, ByteString)] -- | WaveFormat as flavor of WAVE file. data WaveFormat -- | Classic WAVE file, 4 Gb size limitation WaveVanilla :: WaveFormat -- | WAVE file with RF64 extension WaveRF64 :: WaveFormat -- | Sample formats with associated bit depth (when variable). data SampleFormat -- | Unsigned/signed integers, the argument is the number of bits per -- sample (8 bit and less are encoded as unsigned integers). SampleFormatPcmInt :: Word16 -> SampleFormat -- | Samples are 32 bit floating point numbers. SampleFormatIeeeFloat32Bit :: SampleFormat -- | Samples are 64 bit floating point numbers. SampleFormatIeeeFloat64Bit :: SampleFormat -- | Speaker positions clarifying which exactly channels are packed in the -- WAVE file. data SpeakerPosition -- | Front left SpeakerFrontLeft :: SpeakerPosition -- | Front right SpeakerFrontRight :: SpeakerPosition -- | Front center SpeakerFrontCenter :: SpeakerPosition -- | Sub-woofer SpeakerLowFrequency :: SpeakerPosition -- | Back left SpeakerBackLeft :: SpeakerPosition -- | Back right SpeakerBackRight :: SpeakerPosition -- | Front left of center SpeakerFrontLeftOfCenter :: SpeakerPosition -- | Front right of center SpeakerFrontRightOfCenter :: SpeakerPosition -- | Back center SpeakerBackCenter :: SpeakerPosition -- | Side left SpeakerSideLeft :: SpeakerPosition -- | Side right SpeakerSideRight :: SpeakerPosition -- | Top center SpeakerTopCenter :: SpeakerPosition -- | Top front left SpeakerTopFrontLeft :: SpeakerPosition -- | Top front center SpeakerTopFrontCenter :: SpeakerPosition -- | Top front right SpeakerTopFrontRight :: SpeakerPosition -- | Top back left SpeakerTopBackLeft :: SpeakerPosition -- | Top back center SpeakerTopBackCenter :: SpeakerPosition -- | Top back right SpeakerTopBackRight :: SpeakerPosition -- | Exceptions the library can throw. data WaveException -- | Format of given file doesn't look like anything familiar. The first -- argument is a message explaining what's wrong and the second argument -- is the file name. BadFileFormat :: String -> FilePath -> WaveException -- | The library found a chunk which is not a data chunk but is -- way too long. The first argument is the tag of the chunk and the -- second argument is the file name. NonDataChunkIsTooLong :: ByteString -> FilePath -> WaveException -- | The specified format is non-PCM, it's vanilla WAVE, but “fact” chunk -- is missing. NonPcmFormatButMissingFact :: FilePath -> WaveException -- | Byte rate of a given Wave file. Byte rate is the number of -- bytes it takes to encode one second of audio. waveByteRate :: Wave -> Word32 -- | Bit rate in kilobits per second. waveBitRate :: Wave -> Double -- | Number of significant bits in every sample. waveBitsPerSample :: Wave -> Word16 -- | Block alignment of samples as number of bits per sample (rounded -- towards next multiplier of 8 if necessary) multiplied by number of -- channels. This is how many bytes it takes to encode a single -- multi-channel sample. waveBlockAlign :: Wave -> Word16 -- | Total number of channels present in the audio stream. waveChannels :: Wave -> Word16 -- | Duration in seconds. waveDuration :: Wave -> Double -- | Front center (C). speakerMono :: Set SpeakerPosition -- | Front left (L), front right (R). speakerStereo :: Set SpeakerPosition -- | L, R, back left (Lb), back right (Rb). speakerQuad :: Set SpeakerPosition -- | Surround: L, R, front center (C), back center (Cb). speakerSurround :: Set SpeakerPosition -- | L, R, C, Lb, Rb, low frequency (LFE). speaker5_1 :: Set SpeakerPosition -- | L, R, C, Lb, Rb, front left-of-center, front right-of-center, LFE. speaker7_1 :: Set SpeakerPosition -- | L, R, C, side left (Ls), side right (Rs), LFE. speaker5_1Surround :: Set SpeakerPosition -- | L, R, C, Lb, Rb, Ls, Rs, LFE. speaker7_1Surround :: Set SpeakerPosition -- | Read Wave record from a WAVE file found at given path. This -- action throws WaveException if the file is malformed and cannot -- be read. -- -- You can feed vanilla WAVE and RF64 files. The actual format is -- detected automatically from contents of the file, not by extension. -- -- PCM with samples in form of integers and floats only are supported, -- see SampleFormat. Addition of other formats will be performed -- on request, please feel free to contact me at -- https://github.com/mrkkrp/wave/issues. -- -- Finally, if “fmt” chunk is not extensible, we try to guess channel -- mask from number of channels alone, here is how: -- -- readWaveFile :: MonadIO m => FilePath -> m Wave -- | Write a WAVE file. The waveFileFormat value specifies in which -- of the supported formats the file should be written. The action uses -- the provided callback to write WAVE audio data. waveDataOffset -- and waveDataSize from Wave are ignored, instead the -- values are inferred dynamically after using the callback. Further, the -- function takes care of the requirement that WAVE data should end on -- “even byte boundary”. The pad byte is written for you if necessary and -- included in data size. -- -- The waveSamplesTotal field will be inferred for PCM (including -- formats with samples represented as floats, i.e. always right now), so -- the provided value is not used. -- -- If Wave specifies floating point sample format, the “fact” -- chunk is automatically generated and written (the chunk is required -- for all non-PCM formats by the spec), but only for vanilla WAVE. writeWaveFile :: MonadIO m => FilePath -> Wave -> (Handle -> IO ()) -> m () instance Data.Data.Data Codec.Audio.Wave.WaveException instance GHC.Classes.Eq Codec.Audio.Wave.WaveException instance GHC.Read.Read Codec.Audio.Wave.WaveException instance GHC.Show.Show Codec.Audio.Wave.WaveException instance Data.Data.Data Codec.Audio.Wave.Wave instance GHC.Classes.Ord Codec.Audio.Wave.Wave instance GHC.Classes.Eq Codec.Audio.Wave.Wave instance GHC.Read.Read Codec.Audio.Wave.Wave instance GHC.Show.Show Codec.Audio.Wave.Wave instance Data.Data.Data Codec.Audio.Wave.SpeakerPosition instance GHC.Enum.Enum Codec.Audio.Wave.SpeakerPosition instance GHC.Enum.Bounded Codec.Audio.Wave.SpeakerPosition instance GHC.Classes.Ord Codec.Audio.Wave.SpeakerPosition instance GHC.Classes.Eq Codec.Audio.Wave.SpeakerPosition instance GHC.Read.Read Codec.Audio.Wave.SpeakerPosition instance GHC.Show.Show Codec.Audio.Wave.SpeakerPosition instance Data.Data.Data Codec.Audio.Wave.SampleFormat instance GHC.Classes.Ord Codec.Audio.Wave.SampleFormat instance GHC.Classes.Eq Codec.Audio.Wave.SampleFormat instance GHC.Read.Read Codec.Audio.Wave.SampleFormat instance GHC.Show.Show Codec.Audio.Wave.SampleFormat instance Data.Data.Data Codec.Audio.Wave.WaveFormat instance GHC.Enum.Enum Codec.Audio.Wave.WaveFormat instance GHC.Enum.Bounded Codec.Audio.Wave.WaveFormat instance GHC.Classes.Ord Codec.Audio.Wave.WaveFormat instance GHC.Classes.Eq Codec.Audio.Wave.WaveFormat instance GHC.Read.Read Codec.Audio.Wave.WaveFormat instance GHC.Show.Show Codec.Audio.Wave.WaveFormat instance Data.Default.Class.Default Codec.Audio.Wave.Wave instance GHC.Exception.Exception Codec.Audio.Wave.WaveException instance Data.Default.Class.Default Codec.Audio.Wave.Ds64