packages feed

hsndfile (empty) → 0.1.1

raw patch · 9 files changed

+1247/−0 lines, 9 filesdep +arraydep +basedep +carraysetup-changed

Dependencies added: array, base, carray, haskell98

Files

+ C2HS.hs view
@@ -0,0 +1,220 @@+--  C->Haskell Compiler: Marshalling library+--+--  Copyright (c) [1999...2005] Manuel M T Chakravarty+--+--  Redistribution and use in source and binary forms, with or without+--  modification, are permitted provided that the following conditions are met:+-- +--  1. Redistributions of source code must retain the above copyright notice,+--     this list of conditions and the following disclaimer. +--  2. Redistributions in binary form must reproduce the above copyright+--     notice, this list of conditions and the following disclaimer in the+--     documentation and/or other materials provided with the distribution. +--  3. The name of the author may not be used to endorse or promote products+--     derived from this software without specific prior written permission. +--+--  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+--  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+--  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN+--  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +--  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED+--  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+--  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+--  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+--  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+--  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+--+--- Description ---------------------------------------------------------------+--+--  Language: Haskell 98+--+--  This module provides the marshaling routines for Haskell files produced by +--  C->Haskell for binding to C library interfaces.  It exports all of the+--  low-level FFI (language-independent plus the C-specific parts) together+--  with the C->HS-specific higher-level marshalling routines.+--++module C2HS (++  -- * Re-export the language-independent component of the FFI +  module Foreign,++  -- * Re-export the C language component of the FFI+  module CForeign,++  -- * Composite marshalling functions+  withCStringLenIntConv, peekCStringLenIntConv, withIntConv, withFloatConv,+  peekIntConv, peekFloatConv, withBool, peekBool, withEnum, peekEnum,++  -- * Conditional results using 'Maybe'+  nothingIf, nothingIfNull,++  -- * Bit masks+  combineBitMasks, containsBitMask, extractBitMasks,++  -- * Conversion between C and Haskell types+  cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum+) where +++import Foreign+       hiding       (Word)+		    -- Should also hide the Foreign.Marshal.Pool exports in+		    -- compilers that export them+import CForeign++import Monad        (when, liftM)+++-- Composite marshalling functions+-- -------------------------------++-- Strings with explicit length+--+withCStringLenIntConv s f    = withCStringLen s $ \(p, n) -> f (p, cIntConv n)+peekCStringLenIntConv (s, n) = peekCStringLen (s, cIntConv n)++-- Marshalling of numerals+--++withIntConv   :: (Storable b, Integral a, Integral b) +	      => a -> (Ptr b -> IO c) -> IO c+withIntConv    = with . cIntConv++withFloatConv :: (Storable b, RealFloat a, RealFloat b) +	      => a -> (Ptr b -> IO c) -> IO c+withFloatConv  = with . cFloatConv++peekIntConv   :: (Storable a, Integral a, Integral b) +	      => Ptr a -> IO b+peekIntConv    = liftM cIntConv . peek++peekFloatConv :: (Storable a, RealFloat a, RealFloat b) +	      => Ptr a -> IO b+peekFloatConv  = liftM cFloatConv . peek++-- Passing Booleans by reference+--++withBool :: (Integral a, Storable a) => Bool -> (Ptr a -> IO b) -> IO b+withBool  = with . fromBool++peekBool :: (Integral a, Storable a) => Ptr a -> IO Bool+peekBool  = liftM toBool . peek+++-- Passing enums by reference+--++withEnum :: (Enum a, Integral b, Storable b) => a -> (Ptr b -> IO c) -> IO c+withEnum  = with . cFromEnum++peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a+peekEnum  = liftM cToEnum . peek+++-- Storing of 'Maybe' values+-- -------------------------++instance Storable a => Storable (Maybe a) where+  sizeOf    _ = sizeOf    (undefined :: Ptr ())+  alignment _ = alignment (undefined :: Ptr ())++  peek p = do+	     ptr <- peek (castPtr p)+	     if ptr == nullPtr+	       then return Nothing+	       else liftM Just $ peek ptr++  poke p v = do+	       ptr <- case v of+		        Nothing -> return nullPtr+			Just v' -> new v'+               poke (castPtr p) ptr+++-- Conditional results using 'Maybe'+-- ---------------------------------++-- Wrap the result into a 'Maybe' type.+--+-- * the predicate determines when the result is considered to be non-existing,+--   ie, it is represented by `Nothing'+--+-- * the second argument allows to map a result wrapped into `Just' to some+--   other domain+--+nothingIf       :: (a -> Bool) -> (a -> b) -> a -> Maybe b+nothingIf p f x  = if p x then Nothing else Just $ f x++-- |Instance for special casing null pointers.+--+nothingIfNull :: (Ptr a -> b) -> Ptr a -> Maybe b+nothingIfNull  = nothingIf (== nullPtr)+++-- Support for bit masks+-- ---------------------++-- Given a list of enumeration values that represent bit masks, combine these+-- masks using bitwise disjunction.+--+combineBitMasks :: (Enum a, Bits b) => [a] -> b+combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum)++-- Tests whether the given bit mask is contained in the given bit pattern+-- (i.e., all bits set in the mask are also set in the pattern).+--+containsBitMask :: (Bits a, Enum b) => a -> b -> Bool+bits `containsBitMask` bm = let bm' = fromIntegral . fromEnum $ bm+			    in+			    bm' .&. bits == bm'++-- |Given a bit pattern, yield all bit masks that it contains.+--+-- * This does *not* attempt to compute a minimal set of bit masks that when+--   combined yield the bit pattern, instead all contained bit masks are+--   produced.+--+extractBitMasks :: (Bits a, Enum b, Bounded b) => a -> [b]+extractBitMasks bits = +  [bm | bm <- [minBound..maxBound], bits `containsBitMask` bm]+++-- Conversion routines+-- -------------------++-- |Integral conversion+--+cIntConv :: (Integral a, Integral b) => a -> b+cIntConv  = fromIntegral++-- |Floating conversion+--+cFloatConv :: (RealFloat a, RealFloat b) => a -> b+cFloatConv  = realToFrac+-- As this conversion by default goes via `Rational', it can be very slow...+{-# RULES +  "cFloatConv/Float->Float"   forall (x::Float).  cFloatConv x = x;+  "cFloatConv/Double->Double" forall (x::Double). cFloatConv x = x+ #-}++-- |Obtain C value from Haskell 'Bool'.+--+cFromBool :: Num a => Bool -> a+cFromBool  = fromBool++-- |Obtain Haskell 'Bool' from C value.+--+cToBool :: Num a => a -> Bool+cToBool  = toBool++-- |Convert a C enumeration to Haskell.+--+cToEnum :: (Integral i, Enum e) => i -> e+cToEnum  = toEnum . cIntConv++-- |Convert a Haskell enumeration to C.+--+cFromEnum :: (Enum e, Integral i) => e -> i+cFromEnum  = cIntConv . fromEnum
+ COPYING view
@@ -0,0 +1,339 @@+		    GNU GENERAL PUBLIC LICENSE+		       Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++			    Preamble++  The licenses for most software are designed to take away your+freedom to share and change it.  By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users.  This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it.  (Some other Free Software Foundation software is covered by+the GNU Lesser General Public License instead.)  You can apply it to+your programs, too.++  When we speak of free software, we are referring to freedom, not+price.  Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++  To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++  For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have.  You must make sure that they, too, receive or can get the+source code.  And you must show them these terms so they know their+rights.++  We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++  Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software.  If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++  Finally, any free program is threatened constantly by software+patents.  We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary.  To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++  The precise terms and conditions for copying, distribution and+modification follow.++		    GNU GENERAL PUBLIC LICENSE+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++  0. This License applies to any program or other work which contains+a notice placed by the copyright holder saying it may be distributed+under the terms of this General Public License.  The "Program", below,+refers to any such program or work, and a "work based on the Program"+means either the Program or any derivative work under copyright law:+that is to say, a work containing the Program or a portion of it,+either verbatim or with modifications and/or translated into another+language.  (Hereinafter, translation is included without limitation in+the term "modification".)  Each licensee is addressed as "you".++Activities other than copying, distribution and modification are not+covered by this License; they are outside its scope.  The act of+running the Program is not restricted, and the output from the Program+is covered only if its contents constitute a work based on the+Program (independent of having been made by running the Program).+Whether that is true depends on what the Program does.++  1. You may copy and distribute verbatim copies of the Program's+source code as you receive it, in any medium, provided that you+conspicuously and appropriately publish on each copy an appropriate+copyright notice and disclaimer of warranty; keep intact all the+notices that refer to this License and to the absence of any warranty;+and give any other recipients of the Program a copy of this License+along with the Program.++You may charge a fee for the physical act of transferring a copy, and+you may at your option offer warranty protection in exchange for a fee.++  2. You may modify your copy or copies of the Program or any portion+of it, thus forming a work based on the Program, and copy and+distribute such modifications or work under the terms of Section 1+above, provided that you also meet all of these conditions:++    a) You must cause the modified files to carry prominent notices+    stating that you changed the files and the date of any change.++    b) You must cause any work that you distribute or publish, that in+    whole or in part contains or is derived from the Program or any+    part thereof, to be licensed as a whole at no charge to all third+    parties under the terms of this License.++    c) If the modified program normally reads commands interactively+    when run, you must cause it, when started running for such+    interactive use in the most ordinary way, to print or display an+    announcement including an appropriate copyright notice and a+    notice that there is no warranty (or else, saying that you provide+    a warranty) and that users may redistribute the program under+    these conditions, and telling the user how to view a copy of this+    License.  (Exception: if the Program itself is interactive but+    does not normally print such an announcement, your work based on+    the Program is not required to print an announcement.)++These requirements apply to the modified work as a whole.  If+identifiable sections of that work are not derived from the Program,+and can be reasonably considered independent and separate works in+themselves, then this License, and its terms, do not apply to those+sections when you distribute them as separate works.  But when you+distribute the same sections as part of a whole which is a work based+on the Program, the distribution of the whole must be on the terms of+this License, whose permissions for other licensees extend to the+entire whole, and thus to each and every part regardless of who wrote it.++Thus, it is not the intent of this section to claim rights or contest+your rights to work written entirely by you; rather, the intent is to+exercise the right to control the distribution of derivative or+collective works based on the Program.++In addition, mere aggregation of another work not based on the Program+with the Program (or with a work based on the Program) on a volume of+a storage or distribution medium does not bring the other work under+the scope of this License.++  3. You may copy and distribute the Program (or a work based on it,+under Section 2) in object code or executable form under the terms of+Sections 1 and 2 above provided that you also do one of the following:++    a) Accompany it with the complete corresponding machine-readable+    source code, which must be distributed under the terms of Sections+    1 and 2 above on a medium customarily used for software interchange; or,++    b) Accompany it with a written offer, valid for at least three+    years, to give any third party, for a charge no more than your+    cost of physically performing source distribution, a complete+    machine-readable copy of the corresponding source code, to be+    distributed under the terms of Sections 1 and 2 above on a medium+    customarily used for software interchange; or,++    c) Accompany it with the information you received as to the offer+    to distribute corresponding source code.  (This alternative is+    allowed only for noncommercial distribution and only if you+    received the program in object code or executable form with such+    an offer, in accord with Subsection b above.)++The source code for a work means the preferred form of the work for+making modifications to it.  For an executable work, complete source+code means all the source code for all modules it contains, plus any+associated interface definition files, plus the scripts used to+control compilation and installation of the executable.  However, as a+special exception, the source code distributed need not include+anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the+operating system on which the executable runs, unless that component+itself accompanies the executable.++If distribution of executable or object code is made by offering+access to copy from a designated place, then offering equivalent+access to copy the source code from the same place counts as+distribution of the source code, even though third parties are not+compelled to copy the source along with the object code.++  4. You may not copy, modify, sublicense, or distribute the Program+except as expressly provided under this License.  Any attempt+otherwise to copy, modify, sublicense or distribute the Program is+void, and will automatically terminate your rights under this License.+However, parties who have received copies, or rights, from you under+this License will not have their licenses terminated so long as such+parties remain in full compliance.++  5. You are not required to accept this License, since you have not+signed it.  However, nothing else grants you permission to modify or+distribute the Program or its derivative works.  These actions are+prohibited by law if you do not accept this License.  Therefore, by+modifying or distributing the Program (or any work based on the+Program), you indicate your acceptance of this License to do so, and+all its terms and conditions for copying, distributing or modifying+the Program or works based on it.++  6. Each time you redistribute the Program (or any work based on the+Program), the recipient automatically receives a license from the+original licensor to copy, distribute or modify the Program subject to+these terms and conditions.  You may not impose any further+restrictions on the recipients' exercise of the rights granted herein.+You are not responsible for enforcing compliance by third parties to+this License.++  7. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues),+conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License.  If you cannot+distribute so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you+may not distribute the Program at all.  For example, if a patent+license would not permit royalty-free redistribution of the Program by+all those who receive copies directly or indirectly through you, then+the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Program.++If any portion of this section is held invalid or unenforceable under+any particular circumstance, the balance of the section is intended to+apply and the section as a whole is intended to apply in other+circumstances.++It is not the purpose of this section to induce you to infringe any+patents or other property right claims or to contest validity of any+such claims; this section has the sole purpose of protecting the+integrity of the free software distribution system, which is+implemented by public license practices.  Many people have made+generous contributions to the wide range of software distributed+through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing+to distribute software through any other system and a licensee cannot+impose that choice.++This section is intended to make thoroughly clear what is believed to+be a consequence of the rest of this License.++  8. If the distribution and/or use of the Program is restricted in+certain countries either by patents or by copyrighted interfaces, the+original copyright holder who places the Program under this License+may add an explicit geographical distribution limitation excluding+those countries, so that distribution is permitted only in or among+countries not thus excluded.  In such case, this License incorporates+the limitation as if written in the body of this License.++  9. The Free Software Foundation may publish revised and/or new versions+of the General Public License from time to time.  Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++Each version is given a distinguishing version number.  If the Program+specifies a version number of this License which applies to it and "any+later version", you have the option of following the terms and conditions+either of that version or of any later version published by the Free+Software Foundation.  If the Program does not specify a version number of+this License, you may choose any version ever published by the Free Software+Foundation.++  10. If you wish to incorporate parts of the Program into other free+programs whose distribution conditions are different, write to the author+to ask for permission.  For software which is copyrighted by the Free+Software Foundation, write to the Free Software Foundation; we sometimes+make exceptions for this.  Our decision will be guided by the two goals+of preserving the free status of all derivatives of our free software and+of promoting the sharing and reuse of software generally.++			    NO WARRANTY++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+REPAIR OR CORRECTION.++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+POSSIBILITY OF SUCH DAMAGES.++		     END OF TERMS AND CONDITIONS++	    How to Apply These Terms to Your New Programs++  If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++  To do so, attach the following notices to the program.  It is safest+to attach them to the start of each source file to most effectively+convey the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++    <one line to give the program's name and a brief idea of what it does.>+    Copyright (C) <year>  <name of author>++    This program is free software; you can redistribute it and/or modify+    it under the terms of the GNU General Public License as published by+    the Free Software Foundation; either version 2 of the License, or+    (at your option) any later version.++    This program is distributed in the hope that it will be useful,+    but WITHOUT ANY WARRANTY; without even the implied warranty of+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+    GNU General Public License for more details.++    You should have received a copy of the GNU General Public License along+    with this program; if not, write to the Free Software Foundation, Inc.,+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.++Also add information on how to contact you by electronic and paper mail.++If the program is interactive, make it output a short notice like this+when it starts in an interactive mode:++    Gnomovision version 69, Copyright (C) year name of author+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+    This is free software, and you are welcome to redistribute it+    under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License.  Of course, the commands you use may+be called something other than `show w' and `show c'; they could even be+mouse-clicks or menu items--whatever suits your program.++You should also get your employer (if you work as a programmer) or your+school, if any, to sign a "copyright disclaimer" for the program, if+necessary.  Here is a sample; alter the names:++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program+  `Gnomovision' (which makes passes at compilers) written by James Hacker.++  <signature of Ty Coon>, 1 April 1989+  Ty Coon, President of Vice++This General Public License does not permit incorporating your program into+proprietary programs.  If your program is a subroutine library, you may+consider it more useful to permit linking proprietary applications with the+library.  If this is what you want to do, use the GNU Lesser General+Public License instead of this License.
+ Setup.hs view
@@ -0,0 +1,4 @@+#!/usr/bin/env runhaskell++import Distribution.Simple+main = defaultMain
+ Sound/File/Sndfile.hs view
@@ -0,0 +1,36 @@+-- | "Sound.File.Sndfile" provides a Haskell interface to the ubiquitous+-- libsndfile library by Erik de Castro Lopo (visit the author's website at+-- <http://www.mega-nerd.com/libsndfile/>).++module Sound.File.Sndfile+(+    -- *Types+    Count, Index,+    -- *Stream format+    Format(..),+    HeaderFormat(..),+    SampleFormat(..),+    EndianFormat(..),+    defaultFormat,+    -- *Stream info+    Info(..), duration, defaultInfo, checkFormat,+    -- *Stream handle operations+    Handle, hInfo, hIsSeekable,+    IOMode(..), openFile, getFileInfo, hFlush, hClose,+    SeekMode(..), hSeek, hSeekRead, hSeekWrite,+    -- *I\/O functions+    MBuffer(..), interact,+    --IBuffer(..),+    -- *Exception handling+    Exception, errorString, catch,+    -- *Header string field access+    StringType(..), getString, setString+) where++import Prelude hiding (catch, interact)+import Sound.File.Sndfile.Buffer+import Sound.File.Sndfile.Buffer.Storable ()+import Sound.File.Sndfile.Buffer.IOCArray ()+import Sound.File.Sndfile.Interface++-- EOF
+ Sound/File/Sndfile/Buffer.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE MultiParamTypeClasses #-}++module Sound.File.Sndfile.Buffer+(+    MBuffer(..),+    checkSampleBounds, checkFrameBounds,+    interact+) where++import C2HS+import Control.Monad (liftM, when)+import Data.Array.Base (unsafeRead, unsafeWrite)+import Data.Array.MArray (Ix, MArray, getBounds)+--import Data.Array.IArray (IArray)+import Data.Ix (rangeSize)+import Prelude hiding (interact)+import Sound.File.Sndfile.Interface++checkSampleBounds :: (Monad m) => Count -> Int -> Count -> m ()+checkSampleBounds size channels count+    | (count `mod` channels) /= 0 = throw (Exception ("invalid channel/count combination " ++ (show count)))+    | (count < 0) || (count > size) = throw (Exception "index out of bounds")+    | otherwise = return ()++checkFrameBounds :: (Monad m) => Count -> Int -> Count -> m ()+checkFrameBounds size channels count+    | (size `mod` channels) /= 0 = throw (Exception "invalid buffer size")+    | (count < 0) || (count > (size `quot` channels)) = throw (Exception "index out of bounds")+    | otherwise = return ()++-- |The class MBuffer is used for polymorphic I\/O on a 'Handle', and is+-- parameterized on the mutable array type, the element type and the monad+-- results are returned in.+--+-- 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 only supports reading and writing+-- 'Double' or 'Float' values.+--+-- When converting between integer data and floating point data, the following+-- rules apply: The default behaviour when reading floating point data+-- ('hGetSamples' or 'hGetFrames') 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 [TODO: implementation missing in Haskell].+--+-- 'hGetSamples' and 'hGetFrames' 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 (MArray a e m) => MBuffer a e m where+    -- |Fill the destination array with the requested number of items. The 'count'+    -- parameter must be an integer product of the number of channels or an error+    -- will occur.+    hGetSamples :: Handle -> a Index e -> Count -> m Count+    -- |Fill the destination array with the requested number of frames of data.+    -- The array must be large enough to hold the product of frames and the number+    -- of channels or an error will occur.+    hGetFrames  :: Handle -> a Index e -> Count -> m Count+    -- |Write 'count' samples from the source array to the stream. The 'count'+    -- parameter must be an integer product of the number of channels or an error+    -- will occur.+    --+    -- 'hPutSamples' returns the number of items written (which should be the same+    -- as the 'count' parameter).+    hPutSamples :: Handle -> a Index e -> Count -> m Count+    -- |Write 'count' frames from the source array to the stream.+    -- The array must be large enough to hold the product of frames and the number+    -- of channels or an error will occur.+    --+    -- 'hPutFrames' returns the number of frames written (which should be the same+    -- as the 'count' parameter).+    hPutFrames  :: Handle -> a Index e -> Count -> m Count++modifyArray :: (MArray a e m, Ix i) => (e -> e) -> a i e -> Int -> Int -> m ()+modifyArray f a i n+    | i >= n = return ()+    | otherwise = do+        e <- unsafeRead a i+        unsafeWrite a i (f e)+        modifyArray f a (i+1) n++interact :: (MBuffer a e m) => (e -> e) -> a Index e -> Handle -> Handle -> m ()+interact f buffer hIn hOut = do+    s <- liftM rangeSize $ getBounds buffer+    n <- hGetSamples hIn buffer s+    when (n > 0) $ do+        modifyArray f buffer 0 n+        hPutSamples hOut buffer n+        interact f buffer hIn hOut++-- EOF
+ Sound/File/Sndfile/Buffer/IOCArray.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# OPTIONS_GHC -fglasgow-exts #-}++module Sound.File.Sndfile.Buffer.IOCArray where++import C2HS+import Control.Monad (liftM)+import Data.Array.IOCArray+import Sound.File.Sndfile.Buffer+import Sound.File.Sndfile.Interface++type IOFunc a = HandlePtr -> Ptr a -> CLLong -> IO CLLong++{-# INLINE hIO #-}+hIO :: (Storable a) =>+           (Count -> Int -> Count -> IO ())+        -> IOFunc a+        -> Handle -> (IOCArray Index a) -> Count+        -> IO Count+hIO checkBounds ioFunc (Handle info handle) buffer count = do+    size <- liftM rangeSize $ getBounds buffer+    checkBounds size (channels info) count+    result <- withIOCArray buffer $+                \ptr -> liftM fromIntegral $ ioFunc handle ptr (cIntConv count)+    checkHandle handle+    touchIOCArray buffer+    return $ cIntConv result++foreign import ccall unsafe "sf_read_double"  sf_read_double  :: IOFunc Double+foreign import ccall unsafe "sf_write_double" sf_write_double :: IOFunc Double++instance MBuffer IOCArray Double IO where+    hGetSamples = hIO checkSampleBounds sf_read_double+    hGetFrames  = hIO checkFrameBounds  sf_read_double+    hPutSamples = hIO checkSampleBounds sf_write_double+    hPutFrames  = hIO checkFrameBounds  sf_write_double++foreign import ccall unsafe "sf_read_float"  sf_read_float  :: IOFunc Float+foreign import ccall unsafe "sf_write_float" sf_write_float :: IOFunc Float++instance MBuffer IOCArray Float IO where+    hGetSamples = hIO checkSampleBounds sf_read_float+    hGetFrames  = hIO checkFrameBounds  sf_read_float+    hPutSamples = hIO checkSampleBounds sf_write_float+    hPutFrames  = hIO checkFrameBounds  sf_write_float++-- EOF
+ Sound/File/Sndfile/Buffer/Storable.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# OPTIONS_GHC -fglasgow-exts #-}++module Sound.File.Sndfile.Buffer.Storable where++import C2HS+import Control.Monad (liftM)+import Data.Array.Storable+import Sound.File.Sndfile.Buffer+import Sound.File.Sndfile.Interface++type IOFunc a = HandlePtr -> Ptr a -> CLLong -> IO CLLong++{-# INLINE hIO #-}+hIO :: (Storable a) =>+           (Count -> Int -> Count -> IO ())+        -> IOFunc a+        -> Handle -> (StorableArray Index a) -> Count+        -> IO Count+hIO checkBounds ioFunc (Handle info handle) buffer count = do+    size <- liftM rangeSize $ getBounds buffer+    checkBounds size (channels info) count+    result <- withStorableArray buffer $+                \ptr -> liftM fromIntegral $ ioFunc handle ptr (cIntConv count)+    checkHandle handle+    touchStorableArray buffer+    return $ cIntConv result++foreign import ccall unsafe "sf_read_double"  sf_read_double  :: IOFunc Double+foreign import ccall unsafe "sf_write_double" sf_write_double :: IOFunc Double++instance MBuffer StorableArray Double IO where+    hGetSamples = hIO checkSampleBounds sf_read_double+    hGetFrames  = hIO checkFrameBounds  sf_read_double+    hPutSamples = hIO checkSampleBounds sf_write_double+    hPutFrames  = hIO checkFrameBounds  sf_write_double++foreign import ccall unsafe "sf_read_float"  sf_read_float  :: IOFunc Float+foreign import ccall unsafe "sf_write_float" sf_write_float :: IOFunc Float++instance MBuffer StorableArray Float IO where+    hGetSamples = hIO checkSampleBounds sf_read_float+    hGetFrames  = hIO checkFrameBounds  sf_read_float+    hPutSamples = hIO checkSampleBounds sf_write_float+    hPutFrames  = hIO checkFrameBounds  sf_write_float++-- EOF
+ Sound/File/Sndfile/Interface.chs view
@@ -0,0 +1,428 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# OPTIONS_GHC -fglasgow-exts #-}++module Sound.File.Sndfile.Interface where++import C2HS+import Control.Monad (liftM, when)+import Control.Exception (catchDyn, throwDyn)+import Data.Bits+import Data.Int (Int64)+import Data.Typeable (Typeable)+import Prelude hiding (catch)+import System.IO.Unsafe (unsafePerformIO)++#include <sndfile.h>++{#context lib="libsndfile" prefix="sf"#}++-- ====================================================================+-- Basic types++type Count = Int -- ^ Type for expressing sample counts.+type Index = Int -- ^ Type for expressing sample indices.++-- ====================================================================+-- Format++-- | Header format.+{#enum HeaderFormat {underscoreToCase} deriving (Eq, Show)#}+#c+enum HeaderFormat+{+    HEADER_FORMAT_NONE  = 0,++    HEADER_FORMAT_WAV   = SF_FORMAT_WAV,+    HEADER_FORMAT_AIFF  = SF_FORMAT_AIFF,+    HEADER_FORMAT_AU    = SF_FORMAT_AU,+    HEADER_FORMAT_RAW   = SF_FORMAT_RAW,+    HEADER_FORMAT_PAF   = SF_FORMAT_PAF,+    HEADER_FORMAT_SVX   = SF_FORMAT_SVX,+    HEADER_FORMAT_NIST  = SF_FORMAT_NIST,+    HEADER_FORMAT_VOC   = SF_FORMAT_VOC,+    HEADER_FORMAT_IRCAM = SF_FORMAT_IRCAM,+    HEADER_FORMAT_W64   = SF_FORMAT_W64,+    HEADER_FORMAT_MAT4  = SF_FORMAT_MAT4,+    HEADER_FORMAT_MAT5  = SF_FORMAT_MAT5,+    HEADER_FORMAT_PVF   = SF_FORMAT_PVF,+    HEADER_FORMAT_XI    = SF_FORMAT_XI,+    HEADER_FORMAT_HTK   = SF_FORMAT_HTK,+    HEADER_FORMAT_SDS   = SF_FORMAT_SDS,+    HEADER_FORMAT_AVR   = SF_FORMAT_AVR,+    HEADER_FORMAT_WAVEX = SF_FORMAT_WAVEX,+    HEADER_FORMAT_SD2   = SF_FORMAT_SD2,+    HEADER_FORMAT_FLAC  = SF_FORMAT_FLAC,+    HEADER_FORMAT_CAF   = SF_FORMAT_CAF+};+#endc++-- | Sample format.+{#enum SampleFormat {underscoreToCase} deriving (Eq, Show)#}+#c+enum SampleFormat+{+    SAMPLE_FORMAT_NONE              = 0,++    SAMPLE_FORMAT_PCM_S8            = SF_FORMAT_PCM_S8,+    SAMPLE_FORMAT_PCM_16            = SF_FORMAT_PCM_16,+    SAMPLE_FORMAT_PCM_24            = SF_FORMAT_PCM_24,+    SAMPLE_FORMAT_PCM_32            = SF_FORMAT_PCM_32,+                                    +    SAMPLE_FORMAT_PCM_U8            = SF_FORMAT_PCM_U8,+                                    +    SAMPLE_FORMAT_FLOAT             = SF_FORMAT_FLOAT,+    SAMPLE_FORMAT_DOUBLE            = SF_FORMAT_DOUBLE,+                                    +    SAMPLE_FORMAT_ULAW              = SF_FORMAT_ULAW,+    SAMPLE_FORMAT_ALAW              = SF_FORMAT_ALAW,+    SAMPLE_FORMAT_IMA_ADPCM         = SF_FORMAT_IMA_ADPCM,+    SAMPLE_FORMAT_MS_ADPCM          = SF_FORMAT_MS_ADPCM,+                                    +    SAMPLE_FORMAT_GSM610            = SF_FORMAT_GSM610,+    SAMPLE_FORMAT_VOX_ADPCM         = SF_FORMAT_VOX_ADPCM,+                                    +    SAMPLE_FORMAT_G721_32           = SF_FORMAT_G721_32,+    SAMPLE_FORMAT_G723_24           = SF_FORMAT_G723_24,+    SAMPLE_FORMAT_G723_40           = SF_FORMAT_G723_40,+                                    +    SAMPLE_FORMAT_DWVW_12           = SF_FORMAT_DWVW_12,+    SAMPLE_FORMAT_DWVW_16           = SF_FORMAT_DWVW_16,+    SAMPLE_FORMAT_DWVW_24           = SF_FORMAT_DWVW_24,+    SAMPLE_FORMAT_DWVW_N            = SF_FORMAT_DWVW_N,+                             +    SAMPLE_FORMAT_FORMAT_DPCM_8     = SF_FORMAT_DPCM_8,+    SAMPLE_FORMAT_FORMAT_DPCM_16    = SF_FORMAT_DPCM_16+};+#endc++-- | Endianness.+{#enum EndianFormat {underscoreToCase} deriving (Eq, Show)#}+#c+enum EndianFormat+{+    ENDIAN_FILE     = SF_ENDIAN_FILE,+    ENDIAN_LITTLE   = SF_ENDIAN_LITTLE,+    ENDIAN_BIG      = SF_ENDIAN_BIG,+    ENDIAN_CPU      = SF_ENDIAN_CPU+};+#endc++-- only used internally+{#enum FormatMask {underscoreToCase} deriving (Eq)#}+#c+enum FormatMask+{+    FORMAT_SUB_MASK     = SF_FORMAT_SUBMASK,+    FORMAT_TYPE_MASK    = SF_FORMAT_TYPEMASK,+    FORMAT_END_MASK     = SF_FORMAT_ENDMASK+};+#endc++-- |Stream format specification, consisting of header, sample and endianness+-- formats.+--+-- Not all combinations of header, sample and endianness formats are valid;+-- valid combinamtions can be checked with the 'checkFormat' function.+data Format = Format {+    headerFormat :: HeaderFormat,+    sampleFormat :: SampleFormat,+    endianFormat :: EndianFormat+} deriving (Eq, Show)++-- |Default \'empty\' format, useful when opening files for reading with 'ReadMode'.+defaultFormat :: Format+defaultFormat = Format HeaderFormatNone SampleFormatNone EndianFile++-- Convert CInt to Format+hsFormat :: CInt -> Format+hsFormat i =+   let hf = cToEnum (i .&. (cFromEnum FormatTypeMask) .&. complement (cFromEnum FormatEndMask))+       sf = cToEnum (i .&. (cFromEnum FormatSubMask))+       ef = cToEnum (i .&. (cFromEnum FormatEndMask))+   in+       Format {+           headerFormat = hf,+           sampleFormat = sf,+           endianFormat = ef+       }++-- Convert Format to CInt+cFormat :: Format -> CInt+cFormat (Format hf sf ef) = (cFromEnum hf) .|. (cFromEnum sf) .|. (cFromEnum ef)++-- ====================================================================+-- Info++-- |The 'Info' structure is for passing data between the calling function and+-- the library when opening a stream for reading or writing.+data Info = Info {+    frames :: Count,    -- ^Number of frames in file+    samplerate :: Int,  -- ^Audio sample rate+    channels :: Int,    -- ^Number of channels+    format :: Format,   -- ^Header and sample format+    sections :: Int,    -- ^Number of sections+    seekable :: Bool    -- ^'True' when stream is seekable (e.g. local files)+} deriving (Eq, Show)++-- |Return soundfile duration in seconds computed via the 'Info' fields+-- 'frames' and 'samplerate'.+duration :: Info -> Double+duration info = (fromIntegral $ frames info) / (fromIntegral $ samplerate info)++-- |Default \'empty\' info, useful when opening files for reading with 'ReadMode'.+defaultInfo :: Info+defaultInfo   = Info 0 0 0 defaultFormat 0 False++-- |This function allows the caller to check if a set of parameters in the+-- 'Info' struct is valid before calling 'openFile' ('WriteMode').+--+-- 'checkFormat' returns 'True' if the parameters are valid and 'False' otherwise.++{-# NOINLINE checkFormat #-}+checkFormat :: Info -> Bool+checkFormat info =+    unsafePerformIO (with info (liftM cToBool . {#call unsafe sf_format_check#} . castPtr))++-- Storable instance for Info+instance Storable (Info) where+    alignment _ = alignment (undefined :: CInt) -- hmm+    sizeOf _ = {#sizeof INFO#}+    -- Unmarshall Info from C representation+    peek ptr = do+        frames     <- liftM fromIntegral $ {#get SF_INFO.frames#} ptr+        samplerate <- liftM fromIntegral $ {#get SF_INFO.samplerate#} ptr+        channels   <- liftM fromIntegral $ {#get SF_INFO.channels#} ptr+        format     <- liftM hsFormat     $ {#get SF_INFO.format#} ptr+        sections   <- liftM fromIntegral $ {#get SF_INFO.sections#} ptr+        seekable   <- liftM toBool       $ {#get SF_INFO.seekable#} ptr+        return $ Info {+            frames = frames,+            samplerate = samplerate,+            channels = channels,+            format = format,+            sections = sections,+            seekable = seekable+        }+    -- Marshall Info to C representation+    poke ptr info =+        do+            {#set SF_INFO.frames#} ptr     $ fromIntegral $ frames info+            {#set SF_INFO.samplerate#} ptr $ fromIntegral $ samplerate info+            {#set SF_INFO.channels#} ptr   $ fromIntegral $ channels info+            {#set SF_INFO.format#} ptr     $ cFormat      $ format info+            {#set SF_INFO.sections#} ptr   $ fromIntegral $ sections info+            {#set SF_INFO.seekable#} ptr   $ fromBool     $ seekable info++-- ====================================================================+-- Exceptions++-- |Values of type 'Exception' are thrown by the library when an error occurs.+--+-- Use 'catch' to catch only exceptions of this type.+data Exception = Exception String deriving (Typeable, Show)++-- |Return the error string associated with the 'Exception'.+errorString :: Exception -> String+errorString (Exception s) = s++-- |Catch values of type 'Exception'.+catch :: IO a -> (Exception -> IO a) -> IO a+catch = catchDyn++throw :: Exception -> a+throw = throwDyn++raiseError :: Handle -> IO ()+raiseError handle = liftM (throw . Exception) $ (peekCString $ {#call pure sf_strerror#} (hPtr handle))++checkHandle :: HandlePtr -> IO HandlePtr+checkHandle handle = do+    code <- liftM fromIntegral $ {#call unsafe sf_error#} handle+    when (code /= 0) $ raiseError (Handle defaultInfo handle)+    return handle++-- ====================================================================+-- Handle operations++-- | Abstract file handle.+data Handle = Handle {+    hInfo :: Info,      -- ^Return the stream 'Info' associated with the 'Handle'.+    hPtr :: HandlePtr+}+type HandlePtr = Ptr ()++-- | I\/O mode.+{#enum IOMode {} deriving (Eq, Show)#}+#c+enum IOMode+{+    ReadMode        = SFM_READ,+    WriteMode       = SFM_WRITE,+    ReadWriteMode   = SFM_RDWR+};+#endc++-- |When opening a file for read ('ReadMode'), the format field should be set+-- to 'defaultFormat' before calling 'openFile'. The only exception to this is+-- the case of RAW files, where the caller has to set the samplerate, channels+-- and format fields to valid values. All other fields of the structure are+-- filled in by the library.+--+-- When opening a file for write ('WriteMode'), the caller must fill in the+-- structure members samplerate, channels, and format.+--+-- Every call to 'openFile' should be matched with a call to 'hClose' to free+-- up memory allocated during the call to 'openFile'.+--+-- On success, the 'openFile' function returns a 'Handle' which should be+-- passed as the first parameter to all subsequent libsndfile calls dealing+-- with that audio stream. On fail, the 'openFile' function signals an+-- 'Exception'.+openFile :: FilePath -> IOMode -> Info -> IO Handle+openFile filePath ioMode info =+    withCString filePath (\cFilePath ->+        with info (\cInfo -> do+            cHandle <- {#call unsafe sf_open#}+                            cFilePath (cFromEnum ioMode) (castPtr cInfo)+                            >>= checkHandle+            newInfo <- peek cInfo+            return $ Handle newInfo cHandle))++-- |The 'hClose' function closes the stream, deallocates its internal buffers+-- and returns () on success or signals an 'Exception' otherwise.+hClose :: Handle -> IO ()+hClose handle = do+    {#call unsafe sf_close#} $ hPtr handle+    checkHandle nullPtr+    return ()++-- |If the stream is opened with 'WriteMode' or 'ReadWriteMode', call the+-- operating system\'s function to force the writing of all file cache buffers+-- to disk. If the file is opened with 'ReadMode' no action is taken.+hFlush :: Handle -> IO ()+hFlush (Handle _ handle) = {#call unsafe sf_write_sync#} handle++-- |Get header format information associated with file.+getFileInfo :: FilePath -> IO Info+getFileInfo filePath = do+    h <- openFile filePath ReadMode defaultInfo+    let info = hInfo h+    hClose h+    return info++-- ====================================================================+-- seeking++hIsSeekable :: Handle -> IO Bool+hIsSeekable = return . seekable . hInfo++{#enum SeekMode {} deriving (Eq, Show)#}+#c+enum SeekMode+{+    AbsoluteSeek    = SEEK_SET,+    RelativeSeek    = SEEK_CUR,+    SeekFromEnd     = SEEK_END+};+#endc++-- Helper function for seeking, modifying either the read pointer, the write+-- pointer, or both.+{-# INLINE hSeek' #-}+hSeek' :: Maybe IOMode -> Handle -> SeekMode -> Count -> IO Count+hSeek' ioMode (Handle _ handle) seekMode frames = do+    n <- liftM fromIntegral $+            {#call unsafe sf_seek#}+                handle+                (cIntConv frames)+                ((cFromEnum seekMode) .|. (case ioMode of+                                                Nothing -> 0+                                                Just m -> cFromEnum m))+    checkHandle handle+    return n++-- |The file seek functions work much like 'System.IO.hseek' 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:+--+-- * 'AbsoluteSeek' - The offset is set to the start of the audio data plus+--   offset (multichannel) frames.+--+-- * 'RelativeSeek' - The offset is set to its current location plus offset+--   (multichannel) frames.+--+-- * 'SeekFromEnd' - The offset is set to the end of the data plus offset+--   (multichannel) frames.+--+-- 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+-- 'ReadWriteMode', calling either 'hSeekRead' or 'hSeekWrite' allows the read+-- and write pointers to be modified separately. 'hSeek' 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.+--         +-- 'hSeek' 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+hSeek = hSeek' Nothing++--hSeek (Handle _ handle) seekMode frames = do+--    n <- liftM fromIntegral $ {#call unsafe sf_seek#} handle (cIntConv frames) (cFromEnum seekMode)+--    checkHandle handle+--    return n++-- |Like 'hSeek', but only the read pointer is modified.+hSeekRead :: Handle -> SeekMode -> Count -> IO Count+hSeekRead = hSeek' (Just ReadMode)++-- |Like 'hSeek', but only the write pointer is modified.+hSeekWrite :: Handle -> SeekMode -> Count -> IO Count+hSeekWrite = hSeek' (Just WriteMode)++-- ====================================================================+-- string access++-- |Header string field types.+{#enum StringType {underscoreToCase} deriving (Eq, Show)#}+#c+enum StringType+{+    STR_TITLE       = SF_STR_TITLE,+    STR_COPYRIGHT   = SF_STR_COPYRIGHT,+    STR_SOFTWARE    = SF_STR_SOFTWARE,+    STR_ARTIST      = SF_STR_ARTIST,+    STR_COMMENT     = SF_STR_COMMENT,+    STR_DATE        = SF_STR_DATE+};+#endc++-- |The 'getString' function returns the specificed string from the stream+-- header in the 'Maybe' monad if it exists and 'Nothing' otherwise.+getString :: Handle -> StringType -> IO (Maybe String)+getString (Handle _ handle) t = do+    ptr <- {#call unsafe sf_get_string#} handle (cFromEnum t)+    if ptr == (nullPtr :: Ptr CChar)+        then return Nothing+        else liftM Just $ peekCString =<< (return ptr)+++-- |The 'setString' function sets the string data associated with the+-- respective 'StringType'.+setString :: Handle -> StringType -> String -> IO ()+setString (Handle _ handle) t s =+    withCString s (\cs -> do+        {#call unsafe sf_set_string#} handle (cFromEnum t) cs+        checkHandle handle+        return ())++-- EOF
+ hsndfile.cabal view
@@ -0,0 +1,27 @@+Name:                   hsndfile+Version:                0.1.1+Category:		Sound+License:                GPL+License-File:           COPYING+Copyright:              Stefan Kersten, 2007-2008+Author:                 Stefan Kersten+Maintainer:             Stefan Kersten <sk@k-hornz.de>+Stability:              Experimental+Homepage:               http://darcs.k-hornz.de/cgi-bin/darcsweb.cgi?r=hsndfile;a=summary+Synopsis:               Haskell bindings for libsndfile+Description:            Haskell bindings for libsndfile.+                        .+                        Libsndfile is a comprehensive C library for reading+                        and writing a large number of soundfile formats:+                        <http://www.mega-nerd.com/libsndfile/>.+Tested-With:            GHC+Build-Type:		Simple+Build-Depends:          array, base, carray, haskell98+Exposed-Modules:        Sound.File.Sndfile+Other-Modules:          C2HS,+		        Sound.File.Sndfile.Buffer,+		        Sound.File.Sndfile.Buffer.IOCArray,+		        Sound.File.Sndfile.Buffer.Storable,+		        Sound.File.Sndfile.Interface+Ghc-Options:            -Wall+Extra-Libraries:        sndfile