-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Haskell bindings for libsndfile
--   
--   Haskell bindings for <i>libsndfile</i>, a comprehensive C library for
--   reading and writing a large number of soundfile formats by Erik de
--   Castro Lopo (<a>http://www.mega-nerd.com/libsndfile/</a>).
--   
--   For more information on <i>hsndfile</i> visit its homepage at
--   <a>http://haskell.org/haskellwiki/Hsndfile</a>.
@package hsndfile
@version 0.8.0


-- | This module provides the <a>Buffer</a> type class that abstracts the
--   array type that is being used for I/O. For concrete instances see for
--   example the <i>hsndfile-vector</i> package
--   <a>http://hackage.haskell.org/package/hsndfile-vector</a>.
module Sound.File.Sndfile.Buffer

-- | The class Sample is used for polymorphic I/O on a <a>Handle</a>, and
--   is parameterized with the element type that is to be read from a file.
--   
--   It is important to note that the data type used by the calling program
--   and the data format of the file do not need to be the same. For
--   instance, it is possible to open a 16 bit PCM encoded WAV file and
--   read the data in floating point format. The library seamlessly
--   converts between the two formats on-the-fly; the Haskell interface
--   currently supports reading and writing <a>Double</a> or <a>Float</a>
--   floating point values, as well as <a>Int16</a> and <a>Int32</a>
--   integer values.
--   
--   When converting between integer data and floating point data, the
--   following rules apply: The default behaviour when reading floating
--   point data from a file with integer data is normalisation. Regardless
--   of whether data in the file is 8, 16, 24 or 32 bit wide, the data will
--   be read as floating point data in the range [-1.0, 1.0]. Similarly,
--   data in the range [-1.0, 1.0] will be written to an integer PCM file
--   so that a data value of 1.0 will be the largest allowable integer for
--   the given bit width. This normalisation can be turned on or off using
--   the command interface (<i>implementation missing in Haskell</i>).
--   
--   <tt>hGetSamples</tt> and <tt>hGetFrames</tt> return the number of
--   items read. Unless the end of the file was reached during the read,
--   the return value should equal the number of items requested. Attempts
--   to read beyond the end of the file will not result in an error but
--   will cause the read functions to return less than the number of items
--   requested or 0 if already at the end of the file.
class Storable e => Sample e

-- | Read a buffer of frames.
hGetBuf :: Sample e => Handle -> Ptr e -> Count -> IO Count

-- | Write a buffer of frames.
hPutBuf :: Sample e => Handle -> Ptr e -> Count -> IO Count

-- | Buffer class for I/O on soundfile handles.
class Buffer a e

-- | Construct a buffer from a <a>ForeignPtr</a>, a start index and the
--   element count.
fromForeignPtr :: Buffer a e => ForeignPtr e -> Int -> Int -> IO (a e)

-- | Retrieve from a buffer a <a>ForeignPtr</a> pointing to its data, a
--   start index and an element count.
toForeignPtr :: Buffer a e => a e -> IO (ForeignPtr e, Int, Int)

-- | Return an buffer with the requested number of frames of data.
--   
--   The resulting buffer size is equal to the product of the number of
--   frames <tt>n</tt> and the number of channels in the soundfile.
hGetBuffer :: forall a e. (Sample e, Storable e, Buffer a e) => Handle -> Count -> IO (Maybe (a e))

-- | Return the contents of a handle open for reading in a single buffer.
hGetContents :: (Sample e, Buffer a e) => Handle -> IO (Info, Maybe (a e))

-- | Return the contents of a file in a single buffer.
readFile :: (Sample e, Buffer a e) => FilePath -> IO (Info, Maybe (a e))

-- | Write the contents of a buffer to a handle open for writing.
--   
--   Return the number of frames written.
hPutBuffer :: forall a e. (Sample e, Storable e, Buffer a e) => Handle -> a e -> IO Count

-- | Write the contents of a buffer to a file. Return the number of frames
--   written.
writeFile :: (Sample e, Buffer a e) => Info -> FilePath -> a e -> IO Count


-- | <a>Sound.File.Sndfile</a> provides a Haskell interface to the
--   libsndfile library by Erik de Castro Lopo
--   (<a>http://www.mega-nerd.com/libsndfile/</a>).
--   
--   The API is modeled after the original <i>C</i> API, but type and
--   function identifiers follow Haskell naming conventions.
module Sound.File.Sndfile

-- | Type for expressing sample counts.
type Count = Int

-- | Type for expressing sample indices.
type Index = Int

-- | Stream format specification, consisting of header, sample and
--   endianness formats.
--   
--   Not all combinations of header, sample and endianness formats are
--   valid; valid combinations can be checked with the <a>checkFormat</a>
--   function.
data Format
Format :: HeaderFormat -> SampleFormat -> EndianFormat -> Format
[headerFormat] :: Format -> HeaderFormat
[sampleFormat] :: Format -> SampleFormat
[endianFormat] :: Format -> EndianFormat

-- | Header format.
data HeaderFormat
HeaderFormatNone :: HeaderFormat
HeaderFormatWav :: HeaderFormat
HeaderFormatAiff :: HeaderFormat
HeaderFormatAu :: HeaderFormat
HeaderFormatRaw :: HeaderFormat
HeaderFormatPaf :: HeaderFormat
HeaderFormatSvx :: HeaderFormat
HeaderFormatNist :: HeaderFormat
HeaderFormatVoc :: HeaderFormat
HeaderFormatIrcam :: HeaderFormat
HeaderFormatW64 :: HeaderFormat
HeaderFormatMat4 :: HeaderFormat
HeaderFormatMat5 :: HeaderFormat
HeaderFormatPvf :: HeaderFormat
HeaderFormatXi :: HeaderFormat
HeaderFormatHtk :: HeaderFormat
HeaderFormatSds :: HeaderFormat
HeaderFormatAvr :: HeaderFormat
HeaderFormatWavex :: HeaderFormat
HeaderFormatSd2 :: HeaderFormat
HeaderFormatFlac :: HeaderFormat
HeaderFormatCaf :: HeaderFormat
HeaderFormatWve :: HeaderFormat
HeaderFormatOgg :: HeaderFormat
HeaderFormatMpc2k :: HeaderFormat
HeaderFormatRf64 :: HeaderFormat

-- | Sample format.
data SampleFormat
SampleFormatNone :: SampleFormat
SampleFormatPcmS8 :: SampleFormat
SampleFormatPcm16 :: SampleFormat
SampleFormatPcm24 :: SampleFormat
SampleFormatPcm32 :: SampleFormat
SampleFormatPcmU8 :: SampleFormat
SampleFormatFloat :: SampleFormat
SampleFormatDouble :: SampleFormat
SampleFormatUlaw :: SampleFormat
SampleFormatAlaw :: SampleFormat
SampleFormatImaAdpcm :: SampleFormat
SampleFormatMsAdpcm :: SampleFormat
SampleFormatGsm610 :: SampleFormat
SampleFormatVoxAdpcm :: SampleFormat
SampleFormatG72132 :: SampleFormat
SampleFormatG72324 :: SampleFormat
SampleFormatG72340 :: SampleFormat
SampleFormatDwvw12 :: SampleFormat
SampleFormatDwvw16 :: SampleFormat
SampleFormatDwvw24 :: SampleFormat
SampleFormatDwvwN :: SampleFormat
SampleFormatFormatDpcm8 :: SampleFormat
SampleFormatFormatDpcm16 :: SampleFormat
SampleFormatVorbis :: SampleFormat

-- | Endianness.
data EndianFormat
EndianFile :: EndianFormat
EndianLittle :: EndianFormat
EndianBig :: EndianFormat
EndianCpu :: EndianFormat

-- | Default 'empty' format, useful when opening files for reading with
--   <a>ReadMode</a>.
defaultFormat :: Format

-- | The <a>Info</a> structure is for passing data between the calling
--   function and the library when opening a stream for reading or writing.
data Info
Info :: Count -> Int -> Int -> Format -> Int -> Bool -> Info

-- | Number of frames in file
[frames] :: Info -> Count

-- | Audio sample rate
[samplerate] :: Info -> Int

-- | Number of channels
[channels] :: Info -> Int

-- | Header and sample format
[format] :: Info -> Format

-- | Number of sections
[sections] :: Info -> Int

-- | <a>True</a> when stream is seekable (e.g. local files)
[seekable] :: Info -> Bool

-- | Return soundfile duration in seconds computed via the <a>Info</a>
--   fields <a>frames</a> and <a>samplerate</a>.
duration :: Info -> Double

-- | Default 'empty' info, useful when opening files for reading with
--   <a>ReadMode</a>.
defaultInfo :: Info

-- | This function allows the caller to check if a set of parameters in the
--   <a>Info</a> struct is valid before calling <a>openFile</a>
--   (<a>WriteMode</a>).
--   
--   <a>checkFormat</a> returns <a>True</a> if the parameters are valid and
--   <a>False</a> otherwise.
checkFormat :: Info -> Bool

-- | Abstract file handle.
data Handle

-- | Return the stream <a>Info</a> associated with the <a>Handle</a>.
hInfo :: Handle -> Info

-- | Return the bare C pointer for the <a>Handle</a>.
hPtr :: Handle -> HandlePtr

-- | Corresponds to a <tt>SNDFILE*</tt> in C.
type HandlePtr = Ptr ()
hIsSeekable :: Handle -> IO Bool

-- | I/O mode.
data IOMode
ReadMode :: IOMode
WriteMode :: IOMode
ReadWriteMode :: IOMode
openFile :: FilePath -> IOMode -> Info -> IO Handle

-- | Get header format information associated with file.
getFileInfo :: FilePath -> IO Info

-- | If the stream is opened with <a>WriteMode</a> or <a>ReadWriteMode</a>,
--   call the operating system's function to force the writing of all file
--   cache buffers to disk. If the file is opened with <a>ReadMode</a> no
--   action is taken.
hFlush :: Handle -> IO ()

-- | The <a>hClose</a> function closes the stream, deallocates its internal
--   buffers and returns () on success or signals an <tt>Exception</tt>
--   otherwise.
hClose :: Handle -> IO ()
data SeekMode
AbsoluteSeek :: SeekMode
RelativeSeek :: SeekMode
SeekFromEnd :: SeekMode

-- | The file seek functions work much like <a>hseek</a> with the exception
--   that the non-audio data is ignored and the seek only moves within the
--   audio data section of the file. In addition, seeks are defined in
--   number of (multichannel) frames. Therefore, a seek in a stereo file
--   from the current position forward with an offset of 1 would skip
--   forward by one sample of both channels.
--   
--   like lseek(), the whence parameter can be any one of the following
--   three values:
--   
--   <ul>
--   <li><a>AbsoluteSeek</a> - The offset is set to the start of the audio
--   data plus offset (multichannel) frames.</li>
--   <li><a>RelativeSeek</a> - The offset is set to its current location
--   plus offset (multichannel) frames.</li>
--   <li><a>SeekFromEnd</a> - The offset is set to the end of the data plus
--   offset (multichannel) frames.</li>
--   </ul>
--   
--   Internally, libsndfile keeps track of the read and write locations
--   using separate read and write pointers. If a file has been opened with
--   a mode of <a>ReadWriteMode</a>, calling either <a>hSeekRead</a> or
--   <a>hSeekWrite</a> allows the read and write pointers to be modified
--   separately. <a>hSeek</a> modifies both the read and the write pointer.
--   
--   Note that the frames offset can be negative and in fact should be when
--   SeekFromEnd is used for the whence parameter.
--   
--   <a>hSeek</a> will return the offset in (multichannel) frames from the
--   start of the audio data, or signal an error when an attempt is made to
--   seek beyond the start or end of the file.
hSeek :: Handle -> SeekMode -> Count -> IO Count

-- | Like <a>hSeek</a>, but only the read pointer is modified.
hSeekRead :: Handle -> SeekMode -> Count -> IO Count

-- | Like <a>hSeek</a>, but only the write pointer is modified.
hSeekWrite :: Handle -> SeekMode -> Count -> IO Count

-- | The class Sample is used for polymorphic I/O on a <a>Handle</a>, and
--   is parameterized with the element type that is to be read from a file.
--   
--   It is important to note that the data type used by the calling program
--   and the data format of the file do not need to be the same. For
--   instance, it is possible to open a 16 bit PCM encoded WAV file and
--   read the data in floating point format. The library seamlessly
--   converts between the two formats on-the-fly; the Haskell interface
--   currently supports reading and writing <a>Double</a> or <a>Float</a>
--   floating point values, as well as <a>Int16</a> and <a>Int32</a>
--   integer values.
--   
--   When converting between integer data and floating point data, the
--   following rules apply: The default behaviour when reading floating
--   point data from a file with integer data is normalisation. Regardless
--   of whether data in the file is 8, 16, 24 or 32 bit wide, the data will
--   be read as floating point data in the range [-1.0, 1.0]. Similarly,
--   data in the range [-1.0, 1.0] will be written to an integer PCM file
--   so that a data value of 1.0 will be the largest allowable integer for
--   the given bit width. This normalisation can be turned on or off using
--   the command interface (<i>implementation missing in Haskell</i>).
--   
--   <tt>hGetSamples</tt> and <tt>hGetFrames</tt> return the number of
--   items read. Unless the end of the file was reached during the read,
--   the return value should equal the number of items requested. Attempts
--   to read beyond the end of the file will not result in an error but
--   will cause the read functions to return less than the number of items
--   requested or 0 if already at the end of the file.
class Storable e => Sample e

-- | Read a buffer of frames.
hGetBuf :: Sample e => Handle -> Ptr e -> Count -> IO Count

-- | Write a buffer of frames.
hPutBuf :: Sample e => Handle -> Ptr e -> Count -> IO Count

-- | Buffer class for I/O on soundfile handles.
class Buffer a e

-- | Construct a buffer from a <a>ForeignPtr</a>, a start index and the
--   element count.
fromForeignPtr :: Buffer a e => ForeignPtr e -> Int -> Int -> IO (a e)

-- | Retrieve from a buffer a <a>ForeignPtr</a> pointing to its data, a
--   start index and an element count.
toForeignPtr :: Buffer a e => a e -> IO (ForeignPtr e, Int, Int)

-- | Return an buffer with the requested number of frames of data.
--   
--   The resulting buffer size is equal to the product of the number of
--   frames <tt>n</tt> and the number of channels in the soundfile.
hGetBuffer :: forall a e. (Sample e, Storable e, Buffer a e) => Handle -> Count -> IO (Maybe (a e))

-- | Return the contents of a handle open for reading in a single buffer.
hGetContents :: (Sample e, Buffer a e) => Handle -> IO (Info, Maybe (a e))

-- | Return the contents of a file in a single buffer.
readFile :: (Sample e, Buffer a e) => FilePath -> IO (Info, Maybe (a e))

-- | Write the contents of a buffer to a handle open for writing.
--   
--   Return the number of frames written.
hPutBuffer :: forall a e. (Sample e, Storable e, Buffer a e) => Handle -> a e -> IO Count

-- | Write the contents of a buffer to a file. Return the number of frames
--   written.
writeFile :: (Sample e, Buffer a e) => Info -> FilePath -> a e -> IO Count

-- | Values of type <a>Exception</a> are thrown by the library when an
--   error occurs.
--   
--   Use <tt>catch</tt> to catch only exceptions of this type.
data Exception
Exception :: String -> Exception
[errorString] :: Exception -> String
UnrecognisedFormat :: String -> Exception
[errorString] :: Exception -> String
SystemError :: String -> Exception
[errorString] :: Exception -> String
MalformedFile :: String -> Exception
[errorString] :: Exception -> String
UnsupportedEncoding :: String -> Exception
[errorString] :: Exception -> String

-- | Header string field types.
data StringType
StrTitle :: StringType
StrCopyright :: StringType
StrSoftware :: StringType
StrArtist :: StringType
StrComment :: StringType
StrDate :: StringType

-- | The <a>getString</a> function returns the specified string from the
--   stream header in the <a>Maybe</a> monad if it exists and
--   <a>Nothing</a> otherwise.
getString :: Handle -> StringType -> IO (Maybe String)

-- | The <a>setString</a> function sets the string data associated with the
--   respective <a>StringType</a>.
setString :: Handle -> StringType -> String -> IO ()
