Haskell

Parsing WAVE files correctly in Haskell.

Wavy over WAVE

Playing with audio data is a ton of fun and something that I believe that Haskell could do very well. Processing audio data safely and efficiently seems to fit very well into Haskell’s model so, overy a year ago, I started working on and off on a WAVE file format parser. I have been working on it very infrequently (bus trips and other spare time) and I rewrote it once but today I am pleased to announce the release of the very first version of my ‘wavy’ package that lets you extract data from WAVE files in Haskell. The features of this release include:

  • Methods to Parse and Assemble Wave Files
  • Support for different orderings of RIFF chunks (via the riff library I wrote previously)
  • A split between the parsers for the container format and the data allowing efficient metadata parsing.
  • The ability to pase the data into Int64 or Float formats so that you can handle the data in whichever way that you please.
  • Example programs that make use of the library for your perusal and use.

Things which the library is currently missing include:

  • RIFX support
  • Direct support for maintaining RIFF chunks that are not mentioned in the WAVE specification.

Getting the Code

The code is on hackage as the wavy library so you can install it by:

cabal update
cabal install wavy

Please feel free to give it a try. Probably the best way to quickly see it working is by finding a WAVE file on your machine:

locate '*.wav'

And then passing that wave file as the first argument into wave-info. For example:

$ wave-info /Applications/Steam.app/Contents/MacOS/Friends/friend_join.wav
File: /Applications/Steam.app/Contents/MacOS/Friends/friend_join.wav - 2s
   Format
     Audio Format:  Microsoft PCM
     Channels:      2
     Sample Rate:   44100
     Bits Per Sample:  16
     Byte Rate:  176400
     Block Alignment:  4

   INFO Metadata
     Creation Date: 2010-03-11
     Engineers:       - Kelly Thornton
     Creation Software: Sony Sound Forge 9.0
$

As you can see it can parse an audio file very quickly. The wave-info program is very efficient because the library is lazy and does not parse the data chunk unless you specifically require it.

Using the Library

I would recommend that you start by looking at the executables in the libraries source code for examples of how this library can be used in your applications. The wave-info source code can be found on BitBucket.

Once you have finished doing that then you can have a read throug the documentation on Hackage to get a full understanding of what methods the library provides.

If you have any questions then please do not hesitate to contact me or comment on the blog.

(This blog post was produced using pandoc)

Haskell, Interesting

Read and write a RIFF (or RIFX)

What is RIFF anyway?

The RIFF file format is an old file format that is used as a container format for WAVE files among other things. Recently I decided that I wanted to write some pure Haskell code that could parse this file format so that I can start working my way towards building audio libraries in pure Haskell.

So you wrote a Haskell RIFF package did you?

Yes. You can view the results of my efforts on hackage: The riff package. You can even view the code on BitBucket if you like.

That package contains:

  • The riff library with the following features:
    • The ability to parse both RIFF and RIFX files. (Only perfectly formatted RIFF files are currently supported, we currently have no best effort support)
    • Convenience methods to make parsing / assembling RIFF files easier.
    • Written in pure Haskell so that you can run your code everywhere and be assured by all of the nice type safety that Haskell gives you.
  • A riff-structure executable that will print out the structure of all of the riff files that you provide it with.
  • A riff-convert executable that will let you convert RIFX files into RIFF files and vice versa.
  • A riff-identity executable that is pretty useless for practical purposes (it just makes a clone of the RIFF file you give it) but great for testing the library and it serves as a good code example.
  • Complete documentation coverage so that you know how to use each and every method in the library and what the limitations are.

You can give it a try today to read some RIFF files and it is all pretty self explanitory. I hope somebody gets some good use out of this. I am going to try and keep this library small and focused; please feel free to contribute and let me know what you think. And if you use it for something then especially let me know. It would make me very happy.