library to read/write audio files

Hello, I've been working on a library to encode/decode audio files (wave, aiff, etc.) to and from lazy bytestrings, and it's finally in a form where I'm willing to share. It's available at http://mml.music.utexas.edu/jwlato/HSoundFile/, lightly cabalized and haddock-ified. The basic item is a Data.SoundFile datatype and a SndFileCls class. Each file format (wave, etc.) has a datatype with instances of SndFileCls and Data.Binary (thanks to Don S. for suggesting Data.Binary). At least that's the idea, I've only implemented the Wave format so far, but I wanted to make it easy to add new formats. I originally intended to use Erik de Castro Lopo's excellent libsndfile (and there are some remnants of that in darcs), but after realizing I wanted a more functional interface I decided to roll my own. It's likely possible to wrap libsndfile in a functional interface, but that is beyond my current abilities. This library is far from complete. Firstly, only the wave format is implemented (and incompletely). There are also only minimal HUnit tests; I plan to add QuickCheck tests when I have some more time. Secondly there are performance issues. For relatively short clips it's fine, but there seems to be a space leak. Attempting to copy large files while just decoding and encoding the data will quickly exhaust available memory. Other than the space leak; performance is good. Profiling indicates that reading is extremely fast, and the slowest operations during write are the multiple calls to Data.Binary.Put.putWord16le (for 16-bit files). Also, sound data is currently read into a list. I will probably change this at some point in the future, most likely copying the lazy bytestring implementation and using a list of CFloat arrays. If anyone would care to offer suggestions (or patches), they would be greatly appreciated. This is my first real project in Haskell, so please be kind. I've successfully build it on ubuntu linux with GHC 6.6.1 and 6.8.1, and I don't see any reason it won't work on other platforms. Thank you, John Lato PS I'd appreciate knowing if this project is reinventing the wheel. I didn't see anything similar in hoogle or google, but you never know.

hi john, On 11.12.2007, at 18:14, John Lato wrote:
I've been working on a library to encode/decode audio files (wave, aiff, etc.) to and from lazy bytestrings, and it's finally in a form where I'm willing to share. It's available at http://mml.music.utexas.edu/jwlato/HSoundFile/, lightly cabalized and haddock-ified. The basic item is a Data.SoundFile datatype and a SndFileCls class. Each file format (wave, etc.) has a datatype with instances of SndFileCls and Data.Binary (thanks to Don S. for suggesting Data.Binary). At least that's the idea, I've only implemented the Wave format so far, but I wanted to make it easy to add new formats.
sounds good!
I originally intended to use Erik de Castro Lopo's excellent libsndfile (and there are some remnants of that in darcs), but after realizing I wanted a more functional interface I decided to roll my own. It's likely possible to wrap libsndfile in a functional interface, but that is beyond my current abilities.
incidentally, i've been working on libsndfile bindings the last few days; here's the darcs repository: http://darcs.k-hornz.de/cgi-bin/darcsweb.cgi?r=hsndfile;a=summary it's not quite finished yet, but if you're interested you could have a look at the interface and make suggestions. maybe both projects could benefit from each other? i personally don't see much advantages in _not_ using libsndfile underneath ... <sk>

Stefan Kersten wrote:
incidentally, i've been working on libsndfile bindings the last few days; here's the darcs repository:
http://darcs.k-hornz.de/cgi-bin/darcsweb.cgi?r=hsndfile;a=summary
it's not quite finished yet, but if you're interested you could have a look at the interface and make suggestions. maybe both projects could benefit from each other? i personally don't see much advantages in _not_ using libsndfile underneath ...
Well done Stefan. Let me know how it goes. I am in the process (have been for some time, but then got distracted) of doing Ocaml bindings to libsndfile. Cheers, Erik -- ----------------------------------------------------------------- Erik de Castro Lopo ----------------------------------------------------------------- "C++ is a language strongly optimized for liars and people who go by guesswork and ignorance." -- Erik Naggum

On 11 Dec 2007, jwlato@gmail.com wrote:
Also, sound data is currently read into a list. I will probably change this at some point in the future, most likely copying the lazy bytestring implementation and using a list of CFloat arrays.
Perhaps you are looking for storablevector which is a direct generalization of bytestring from Word8 to any Storable. It is not in hackage yet, but seems stable. There isn't a `lazy' version, but that could be changed. http://code.haskell.org/~sjanssen/storablevector Jed

On Tue, 11 Dec 2007, Jed Brown wrote:
Perhaps you are looking for storablevector which is a direct generalization of bytestring from Word8 to any Storable. It is not in hackage yet, but seems stable. There isn't a `lazy' version, but that could be changed.
Great, that's what I asked for on this list recently ...

On Tue, 11 Dec 2007, John Lato wrote:
I've been working on a library to encode/decode audio files (wave, aiff, etc.) to and from lazy bytestrings, and it's finally in a form where I'm willing to share. It's available at http://mml.music.utexas.edu/jwlato/HSoundFile/, lightly cabalized and haddock-ified. The basic item is a Data.SoundFile datatype and a SndFileCls class. Each file format (wave, etc.) has a datatype with instances of SndFileCls and Data.Binary (thanks to Don S. for suggesting Data.Binary). At least that's the idea, I've only implemented the Wave format so far, but I wanted to make it easy to add new formats.
These are great news. So far I used Sox to write files in several formats - reading is not nicely possible with this approach, because Sox does not output header information. Would you like to advertise your library at: http://haskell.org/haskellwiki/Applications_and_libraries/Music_and_sound I also reply to the Haskell Art Mailing list.

hello john & stefan,
Stefan Kersten
incidentally, i've been working on libsndfile bindings the last few days; here's the darcs repository:
http://darcs.k-hornz.de/cgi-bin/darcsweb.cgi?r=hsndfile;a=summary
excellent news! i have, _much_ more incidentally, a simple minded NeXT/Au library, just adequate for communicating moderate size signals to scsynth. darcs repository at: http://slavepianos.org/rd/sw/hsc3-sf/
it's not quite finished yet, but if you're interested you could have a look at the interface and make suggestions. maybe both projects could benefit from each other? i personally don't see much advantages in _not_ using libsndfile underneath ...
i agree, sound file formats are a deep
and dark well...
John Lato
It's likely possible to wrap libsndfile in a functional interface, but that is beyond my current abilities.
perhaps once a working sndfile binding is done experimenting with interface designs could be done on the haskell-art list, i'd be interested in following along with discussions. regards, rohan

Sorry, I missed this when it first came through, I was travelling in Europe. I'm also mainly a lurker on this list as my functional language of choice is actually Ocaml, but I've been wanting to learn Haskell for some time. John Lato wrote:
I originally intended to use Erik de Castro Lopo's excellent libsndfile
Thank you.
This library is far from complete. Firstly, only the wave format is implemented (and incompletely).
I really do ask you to reconsider this. Even just parsing the WAVE file format is a *HUGE* undertaking if you intend to support everything that is actually in the specs as well as handle all the horribly broken WAVE files produced by many commercial products. Cheers, Erik -- ----------------------------------------------------------------- Erik de Castro Lopo ----------------------------------------------------------------- "Men never do evil so completely and cheerfully as when they do it from religious conviction." -- Blaise Pascal, mathematician, 1670

hc-erikd:
I originally intended to use Erik de Castro Lopo's excellent libsndfile
Thank you.
This library is far from complete. Firstly, only the wave format is implemented (and incompletely).
I really do ask you to reconsider this. Even just parsing the WAVE file format is a *HUGE* undertaking if you intend to support everything that is actually in the specs as well as handle all the horribly broken WAVE files produced by many commercial products.
Cheers, Erik
I agree with Erik. It makes more sense to bind to a recognised library, so that the developer effort isn't wasted duplicating complex functionality. Unless there's a serious robustness/safety/functionality argument to be made for doing it purely in Haskell, just write a binding instead, and move on to problems we can better apply Haskell's strengths to. -- Don
participants (7)
-
Don Stewart
-
Erik de Castro Lopo
-
Henning Thielemann
-
Jed Brown
-
John Lato
-
Rohan Drape
-
Stefan Kersten